Elmah.Mvc, где хранятся журналы ошибок? Как я могу хранить их в базе данных Azure SQL?

Я использую простой проект aspnet MVC, который использует elmah MVC для регистрации ошибок. Локально (например, работая на локальном хосте) elmah отлично работает, однако я не уверен, что понимаю, где хранятся данные? Я заметил созданную базу данных «AzureStorageEmulatorDb45». Это для elmah?

Как elmah узнает, к какой базе данных подключаться?

Как я могу указать elmah использовать мою базу данных Azure SQL, которая подключена к моему проекту MVC через платформу Entity?

В настоящее время, когда я пытаюсь получить доступ к elmah на сервере развертывания, он просто терпит неудачу, без сомнения, поскольку не может найти базу данных.

Я вижу много старых сообщений о старом elmah.axd и т. д., некоторые об использовании лазурного хранилища таблиц, однако я хочу использовать базу данных лазурного SQL.

Итак, два вопроса. Когда я запускаю свой проект MVC на локальном хосте, где хранятся журналы и как elmah узнает, где их найти?

Второй вопрос: как заставить мой опубликованный на Azure веб-сайт использовать базу данных Azure SQL в качестве хранилища данных для elmah mvc?

редактировать: я следовал приведенным ниже инструкциям и создал таблицы базы данных со следующим скриптом

SET ansi_nulls ON 
SET quoted_identifier ON 

IF NOT EXISTS (SELECT * 
               FROM   sys.objects 
               WHERE  object_id = Object_id(N'[dbo].    [ELMAH_Error]') 
                      AND type IN ( N'U' )) 
  BEGIN 
      CREATE TABLE [dbo].[elmah_error] 
        ( 
           [errorid]     [UNIQUEIDENTIFIER] NOT NULL, 
           [application] [NVARCHAR](60) NOT NULL, 
           [host]        [NVARCHAR](50) NOT NULL, 
           [type]        [NVARCHAR](100) NOT NULL, 
           [source]      [NVARCHAR](60) NOT NULL, 
           [message]     [NVARCHAR](500) NOT NULL, 
           [user]        [NVARCHAR](50) NOT NULL, 
           [statuscode]  [INT] NOT NULL, 
           [timeutc]     [DATETIME] NOT NULL, 
           [sequence]    [INT] IDENTITY(1, 1) NOT NULL, 
           [allxml]      [NVARCHAR](max) NOT NULL, 
           CONSTRAINT [PK_ELMAH_Error] PRIMARY KEY CLUSTERED ( [errorid] ASC ) 
           WITH 
           ( 
           statistics_norecompute = OFF, ignore_dup_key = OFF) 
        ) 
  END 

IF NOT EXISTS (SELECT * 
               FROM   sys.indexes 
               WHERE  object_id = Object_id(N'[dbo].[ELMAH_Error]') 
                      AND NAME = N'IX_ELMAH_Error_App_Time_Seq') 
  CREATE NONCLUSTERED INDEX [IX_ELMAH_Error_App_Time_Seq] 
    ON [dbo].[ELMAH_Error] ( [application] ASC, [timeutc] DESC, [sequence] DESC 
  ) 
    WITH (statistics_norecompute = OFF, ignore_dup_key = OFF, drop_existing = 
  OFF, 
  online = OFF) 

go 

IF NOT EXISTS (SELECT * 
               FROM   dbo.sysobjects 
               WHERE  id = Object_id(N'[DF_ELMAH_Error_ErrorId]') 
                      AND type = 'D') 
  BEGIN 
      ALTER TABLE [dbo].[elmah_error] 
        ADD CONSTRAINT [DF_ELMAH_Error_ErrorId] DEFAULT (Newid()) FOR [ErrorId] 
  END 

go 

SET ansi_nulls ON 
SET quoted_identifier ON 

IF NOT EXISTS (SELECT * 
               FROM   sys.objects 
               WHERE  object_id = Object_id(N'[dbo].[ELMAH_GetErrorsXml]') 
                      AND type IN ( N'P', N'PC' )) 
  BEGIN 
      EXEC dbo.Sp_executesql 
        @statement = N' CREATE PROCEDURE [dbo].[ELMAH_GetErrorsXml] ( @Application NVARCHAR(60), @PageIndex INT = 0, @PageSize INT = 15, @TotalCount INT OUTPUT ) AS  SET NOCOUNT ON DECLARE @FirstTimeUTC DATETIME DECLARE @FirstSequence INT DECLARE @StartRow INT DECLARE @StartRowIndex INT SELECT      @TotalCount = COUNT(1)  FROM      [ELMAH_Error] WHERE      [Application] = @Application -- Get the ID of the first error for the requested page SET @StartRowIndex = @PageIndex * @PageSize + 1 IF @StartRowIndex <= @TotalCount BEGIN     SET ROWCOUNT @StartRowIndex     SELECT           @FirstTimeUTC = [TimeUtc],         @FirstSequence = [Sequence]     FROM          [ELMAH_Error]     WHERE            [Application] = @Application     ORDER BY          [TimeUtc] DESC,          [Sequence] DESC END ELSE BEGIN     SET @PageSize = 0 END -- Now set the row count to the requested page size and get -- all records below it for the pertaining application. SET ROWCOUNT @PageSize SELECT      errorId     = [ErrorId],      application = [Application],     host        = [Host],      type        = [Type],     source      = [Source],     message     = [Message],     [user]      = [User],     statusCode  = [StatusCode],      time        = CONVERT(VARCHAR(50), [TimeUtc], 126) + ''Z'' FROM      [ELMAH_Error] error WHERE     [Application] = @Application AND     [TimeUtc] <= @FirstTimeUTC AND      [Sequence] <= @FirstSequence ORDER BY     [TimeUtc] DESC,      [Sequence] DESC FOR     XML AUTO ' 
  END 

go 

SET ansi_nulls ON 
SET quoted_identifier ON 

IF NOT EXISTS (SELECT * 
               FROM   sys.objects 
               WHERE  object_id = Object_id(N'[dbo].[ELMAH_GetErrorXml]') 
                      AND type IN ( N'P', N'PC' )) 
  BEGIN 
      EXEC dbo.Sp_executesql 
        @statement = N' CREATE PROCEDURE [dbo].[ELMAH_GetErrorXml] ( @Application NVARCHAR(60), @ErrorId UNIQUEIDENTIFIER ) AS SET NOCOUNT ON SELECT      [AllXml] FROM      [ELMAH_Error] WHERE     [ErrorId] = @ErrorId AND     [Application] = @Application ' 
  END 

go 

SET ansi_nulls ON 
SET quoted_identifier ON 

IF NOT EXISTS (SELECT * 
               FROM   sys.objects 
               WHERE  object_id = Object_id(N'[dbo].    [ELMAH_LogError]') 
                      AND type IN ( N'P', N'PC' )) 
  BEGIN 
      EXEC dbo.Sp_executesql 
        @statement = N' CREATE PROCEDURE [dbo].[ELMAH_LogError] ( @ErrorId UNIQUEIDENTIFIER, @Application NVARCHAR(60), @Host NVARCHAR(30), @Type NVARCHAR(100), @Source NVARCHAR(60), @Message NVARCHAR(500), @User NVARCHAR(50), @AllXml NVARCHAR(MAX), @StatusCode INT, @TimeUtc DATETIME ) AS SET NOCOUNT ON INSERT INTO     [ELMAH_Error]     (         [ErrorId],         [Application],         [Host],         [Type],         [Source],         [Message],         [User],         [AllXml],         [StatusCode],         [TimeUtc]     ) VALUES     (         @ErrorId,         @Application,         @Host,         @Type,         @Source,         @Message,         @User,         @AllXml,         @StatusCode,         @TimeUtc     ) ' 
  END 

go 

Затем я добавил в web.config следующее:

<configuration>
  <configSections>
    </sectionGroup>
      <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
  </configSections>

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=tcp:MYWEBSITELOL.database.windows.net,1433;Initial Catalog=LOL;Persist Security Info=True;User ID=trololol;Password=trolololol;Connect Timeout=30;Encrypt=True;TrustServerCertificate=False" providerName="System.Data.SqlClient"/>
  </connectionStrings>

  <elmah>
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="DefaultConnection" applicationName="Lol" />
  </elmah>

  <appSettings>
    <add key="elmah.mvc.disableHandler" value="false" />
    <add key="elmah.mvc.disableHandleErrorFilter" value="false" />
    <add key="elmah.mvc.requiresAuthentication" value="true" />
    <add key="elmah.mvc.IgnoreDefaultRoute" value="false" />
    <add key="elmah.mvc.allowedRoles" value="admin" />
    <add key="elmah.mvc.allowedUsers" value="[email protected] />
    <add key="elmah.mvc.route" value="ServerLog" />
    <add key="elmah.mvc.UserAuthCaseSensitive" value="true" />
  </appSettings>

  <system.web>
  <httpModules>
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
    </httpModules><httpHandlers>
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
  </system.web>

Теперь, когда я запускаю веб-сервер на локальном хосте (используя базу данных Azure), я могу войти в систему и просмотреть elmah со следующим текстом, указывающим на успех.

Этот журнал предоставляется журналом ошибок Microsoft SQL Server.

Затем я публикую веб-сайт, и когда я пытаюсь получить доступ к журналу elmah, я получаю следующую ошибку:

При установлении соединения с SQL Server произошла ошибка, связанная с сетью или конкретным экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен на разрешение удаленных подключений. (поставщик: Сетевые интерфейсы SQL, ошибка: 26 — Ошибка при обнаружении указанного сервера/экземпляра)

Описание: во время выполнения текущего веб-запроса возникло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.

Ошибка автоматического создания файла базы данных SQLExpress:

Строка подключения указывает локальный экземпляр Sql Server Express, используя расположение базы данных в каталоге App_Data приложения. Поставщик попытался автоматически создать базу данных служб приложений, так как поставщик определил, что база данных не существует. Следующие требования к конфигурации необходимы для успешной проверки существования базы данных служб приложений и автоматического создания базы данных служб приложений:

Поскольку версия localhost использует ту же базу данных, я могу использовать elmah-localhost для просмотра ошибки, связанной с elmah-azure, что удобно. Elmah сообщает о следующей ошибке, временная метка которой совпадает, когда я пытался просмотреть Elmah с лазурного веб-сайта:

При установлении соединения с SQL Server произошла ошибка, связанная с сетью или конкретным экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен на разрешение удаленных подключений. (поставщик: Сетевые интерфейсы SQL, ошибка: 26 — Ошибка при обнаружении указанного сервера/экземпляра)

ERRORSHELPABOUT System.Data.SqlClient.SqlException При установлении соединения с SQL Server произошла ошибка, связанная с сетью или экземпляром. Сервер не найден или не был доступен. Убедитесь, что имя экземпляра указано правильно и что SQL Server настроен на разрешение удаленных подключений. (поставщик: Сетевые интерфейсы SQL, ошибка: 26 — Ошибка при обнаружении указанного сервера/экземпляра)

Есть ли что-то, что мне нужно добавить в файл web.RELEASE.config и т. д., чтобы elmah работал правильно при работе в среде выпуска/лазури?

Ошибки кажутся противоречивыми, одна пишет таймаут, другая пишет ошибка автосоздания (что пытается автосоздать и почему?)


person rolls    schedule 10.01.2017    source источник
comment
Кстати, AzureStorageEmulatorDb45 — это база данных, которую эмулятор хранилища Azure создает для себя. Он поставляется с Azure SDK и позволяет тестировать такие вещи, как хранилище BLOB-объектов и таблиц, локально без учетной записи хранения. Это не связано с ELMAH (если вы не настроите его для хранения журналов в хранилище таблиц в эмуляторе).   -  person juunas    schedule 10.01.2017
comment
Спасибо, полезно знать   -  person rolls    schedule 10.01.2017
comment
Первая ошибка означает, что вы не обновили строку подключения, чтобы она указывала на Azure SQL, она по-прежнему указывает на экспресс-базу данных. Второй, вероятно, означает, что вы не добавили исключение брандмауэра для своего IP-адреса в Azure SQL.   -  person juunas    schedule 16.01.2017
comment
Я сделал обе эти вещи, хотя. Я знаю, что брандмауэр работает как. Я могу подключиться к базе данных, чтобы выполнить вход пользователя и т. д. Express dB? Почему тогда моя локальная копия подключается?   -  person rolls    schedule 16.01.2017


Ответы (1)


Журналы хранятся там, где вы их настраиваете. Если вы посмотрите в web.config, вы должны найти что-то вроде этого:

<elmah>
  <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data" />
</elmah>

В этом случае журналы хранятся в файловой системе в виде XML-файлов. В папке App_Data.

Если вы хотите использовать базу данных SQL для хранения, следуйте инструкциям здесь: http://www.andyfrench.info/2014/07/configuring-elmah-to-use-sql-server.html

В основном вам нужно будет добавить строку подключения, создать таблицы ELMAH вручную с помощью предварительно созданного скрипта, а затем изменить конфигурацию следующим образом:

<connectionStrings>
  <add name="elmah" connectionString="server=localhost;database=;uid=Elmah;password=password;" />
</connectionStrings>
<!-- other configuration removed for clarity -->
<elmah>
  <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah" applicationName="YourApplicationName"/>
</elmah>

Страница ELMAH также сообщает вам, какой из них вы используете в настоящее время в нижней части страницы, например:

Этот журнал предоставляется журналом ошибок хранилища Microsoft Azure.

person juunas    schedule 10.01.2017
comment
Спасибо, я попробую и отчитаюсь. - person rolls; 10.01.2017
comment
Обновлен основной пост с тем, как далеко я продвинулся. - person rolls; 11.01.2017