Elmah.Mvc存储错误日志在哪里?如何将它们存储在azure SQL数据库中?

时间:2017-01-10 06:42:13

标签: c# asp.net-mvc azure azure-sql-database elmah.mvc

我正在使用一个简单的aspnet MVC项目,该项目利用elmah MVC进行错误记录。在本地(例如在localhost上运行)elmah工作得很好但是我不确定我知道数据的存储位置?我注意到了一个" AzureStorageEmulatorDb45"已经创建的数据库,这是为了elmah吗?

elmah如何知道要连接的数据库?

如何告诉elmah使用通过Entity框架连接到我的MVC项目的azure SQL数据库?

目前,当我尝试在部署服务器上访问elmah时,它只是失败了,毫无疑问,因为它无法找到数据库。

我看到很多关于旧elmah.axd等的旧帖子,有些关于使用azure表存储但是我想使用azure sql数据库。

所以有两个问题。当我在localhost上运行我的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="waewaewa@lolol.com />
    <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>

现在,当我在localhost上运行Web服务器时(使用azure DB),我可以登录并查看elmah,其中包含以下指示成功的文本。

  

此日志由Microsoft SQL Server错误日志提供。

然后我发布网站,当我尝试访问elmah日志时,我收到以下错误:

  

发生与网络相关或特定于实例的错误   建立与SQL Server的连接。找不到服务器或   无法访问。验证实例名称是否正确   SQL Server配置为允许远程连接。 (提供者:SQL   网络接口,错误:26 - 查找服务器/实例时出错   指定)

     

描述:执行期间发生了未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

SQLExpress数据库文件自动创建错误:

     

连接字符串指定本地Sql Server Express实例   使用应用程序的App_Data目录中的数据库位置。   提供程序尝试自动创建应用程序   服务数据库因为提供者确定了数据库   不存在。以下配置要求是必需的   成功检查是否存在应用程序服务   数据库并自动创建应用服务数据库:

由于localhost版本使用相同的DB,我实际上可以使用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在发布/天蓝色环境中运行时正常工作?

错误似乎有冲突,一个说超时,另一个说自动生成错误(它试图自动创建什么?为什么?)

1 个答案:

答案 0 :(得分: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存储错误日志提供。