ASP.NET MVC的最佳日志记录库

目录

介绍

4个日志记录库

log4net

Log4net记录文本文件中

Log4net记录到数据库中

NLOG

Nlog日志记录在文本文件中

NLog日志记录到数据库中

Serilog

Serilog记录到文本文件中

Serilog记录到数据库中

Serilog.Settings.AppSettings    

ELMAH

ELMAH记录数据库


在本文中,我们将学习如何为ASP.NET MVC应用程序实现市场上可用的最佳Logging库。

介绍

什么是日志记录?

日志记录是保存日志的行为。日志文件是写入应用程序的所有事件或错误的文件。

参考:https://en.wikipedia.org/wiki/Log_file

日志记录是应用程序的重要部分我们尝试构建多少无错误的应用程序,但有些错误是有条件地发生的,为了记录这种错误,我们需要使用一些日志库,例如,由于某些数据库服务器关闭或某些应用程序功能不正常,可能会发生一些错误,如果我们没有适当的日志记录设置,我们将无法知道在客户端功能上不起作用。开发人员有一个众所周知的短语它在我的机器上是正常的。要知道应用程序日志记录中出现的问题很重要。

https://www.codeproject.com/KB/aspnet/1278018/image001.png

4个日志记录库

我们有4个日志记录库,我们将详细了解如何使用ASP.NET MVC应用程序实现它们。

1. Log4net  (记录在文本文件中+记录在SQL数据库中)

2. Nlog  (记录在文本文件中+记录在SQL数据库中)

3. Serilog  (记录在文本文件中+记录在SQL数据库中)

4. Elmah(记录在SQL数据库中)

源代码可在Github链接上获得,在本文末尾提供。

创建ASP.NET应用程序

让我们首先使用名为“ WebErrorLogging ”4.5 ASP.NET模板创建一个简单的ASP.NET Web应用程序。

https://www.codeproject.com/KB/aspnet/1278018/image003.png

在创建应用程序之后,我们将要看到如何实现的第一个库是Log4net

log4net

什么是Apache log4net

Apache log4net库是一个帮助程序员将日志语句输出到各种输出标的工具。

参考定义:——https://logging.apache.org/log4net/

NuGet添加项目的引用

我们将从NuGet包安装log4net

https://www.codeproject.com/KB/aspnet/1278018/image004.png

在添加了log4net的引用后,我们将配置它以记录错误。

我们将在Log4net中看到两种记录方式

  1. 在文本文件中
  2. 在数据库中

Log4net记录文本文件中

让我们从日志记录在文本文件中开始。为了在Log4net中执行此操作,我们需要在web.config文件中添加配置。为了在文本文件中记录消息,我们将使用RollingLogFileAppender类。

RollingLogFileAppender根据大小或日期或两者来滚动日志文件。

RollingFileAppender构建在FileAppender之上,并且具有与该appender相同的选项。

web.config文件中添加此配置将开始将记录消息写入文件中。

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
 </configSections>

<log4net>
    <root>
      <level value="ALL"></level>
      <appender-ref ref="RollingLogFileAppender"></appender-ref>
    </root>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="E:\DemoProject\WebErrorLogging\WebErrorLogging\ErrorLog\logfile.txt" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <datePattern value="yyyyMMdd" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="1MB" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern 

        value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>
</log4net>

您可以在上面的配置设置中看到,这些设置必须添加到web.config文件的“<configuration>”标记中。

然后在log4net元素中我们可以看到该标签内的root元素,在root内我们还有2个子元素,一个是level,另一个是appender-ref

appender-ref:——允许零个或多个元素。允许记录器按名称引用appender

level:——可选元素,最多允许一个元素。定义此记录器的日志记录级别。此记录器仅接受此级别或更高级别的事件。

不同的日志记录级别

  • ALL
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL
  • OFF

RollingLogFileAppender

如果你可以看到里面有名称为RollingLogFileAppender的主元素appender,那么就有一个子元素文件,我们可以在其中配置日志记录文件的路径。

示例:——

<file value="ErrorLog/log.txt" />

注意:——我已将路径指定为“ErrorLog / log.txt”,因为我在此应用程序中创建了一个ErrorLog文件夹。

https://www.codeproject.com/KB/aspnet/1278018/image006.png

下一个元素是appendToFile

appendToFile

如果该值设置为false,则将覆盖该文件,如果将其设置为true,则将附加该文件。

RollingStyle

名称

描述

Once

每个程序执行一次滚动文件

Size

仅根据文件大小滚动文件

Date

仅根据日期滚动文件

Composite

根据文件的大小和日期滚动文件

参考来自:—— https://logging.apache.org/

maxSizeRollBackups

如果我们将最大文件大小设置为1MB并将maxSizeRollBackups设置为10 MB,那么根据日期或文件大小,它将只保留最后10MB的文件。

web.config文件的快照

我在下面给出了快照,以供参考,在web.config文件中正确添加元素。

https://www.codeproject.com/KB/aspnet/1278018/image008.jpg

web.config文件中添加配置后,我们将初始化Log4net

 初始化Log4net

我们需要调用XmlConfigurator类的configure方法来初始化Log4net

log4net.Config.XmlConfigurator.Configure();

https://www.codeproject.com/KB/aspnet/1278018/image009.png

global.asax中初始化XmlConfigurator方法之后。现在可以演示了,我在此添加了一个名为DefaultController的控制器,其中包含Index操作方法,以显示我们如何记录错误,使用它来调试信息。

代码片段

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using log4net;

namespace WebErrorLogging.Controllers
{
    public class DefaultController : Controller
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultController));

        // GET: Default

        public ActionResult Index()
        {
            try
            {
                Log.Debug("Hi I am log4net Debug Level");
                Log.Info("Hi I am log4net Info Level");
                Log.Warn("Hi I am log4net Warn Level");
                throw new NullReferenceException();
                return View();
            }
            catch (Exception ex)
            {
                Log.Error("Hi I am log4net Error Level", ex);
                Log.Fatal("Hi I am log4net Fatal Level", ex);
                throw;
            }
        }
    }
}

添加控制器并获取LogManager类的实例后,我们在各个级别上记录了消息。      

现在让我们通过运行应用程序来测试它。

错误日志记录的文件

https://www.codeproject.com/KB/aspnet/1278018/image010.png

现在我们已经完成了将应用程序记录到文本文件中,然后我们将异常记录到数据库中。

Log4net记录到数据库中

要记录到数据库中,我们需要先在数据库中创建一个表。

https://www.codeproject.com/KB/aspnet/1278018/image012.png

用于创建表的脚本

CREATE TABLE [dbo].[Log](
       [Id] [int] IDENTITY(1,1) NOT NULL,
       [Date] [datetime] NOT NULL,
       [Thread] [varchar](255) NOT NULL,
       [Level] [varchar](50) NOT NULL,
       [Logger] [varchar](255) NOT NULL,
       [Message] [varchar](4000) NOT NULL,
       [Exception] [varchar](2000) NULL
) ON [PRIMARY]

在数据库中创建Log表后,我们将添加新类型的appender,即“log4net.Appender.AdoNetAppender”

web.config文件中添加此配置将开始将日志消息写入Database表。

为此,我们需要数据库的连接字符串,我们将记录错误,如果您看到下面的配置,您将看到connectionStrings元素,其中我添加了数据库连接设置,我们将在AdoNetAppender中分配connectionStrings 

如果在AdoNetAppender中看到commandText元素,您将在其中看到insert语句的脚本。

我们需要设置的主要内容是appender-ref,这里我们要将消息记录到数据库中,以便我们将参考(ref)设置为AdoNetAppender

<appender-ref ref="AdoNetAppender"></appender-ref>

配置设置

<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>
  <connectionStrings>
    <add name="ConnectionStringLogging" 

    connectionString="data source=SAI-PC\SQLEXPRESS;
    initial catalog=LoggingDatabase;
    integrated security=false;persist security info=True;User ID=sa;Password=Pass$123" 

    providerName="System.Data.SqlClient" />
  </connectionStrings>
  <log4net>
    <root>
      <level value="ALL"></level>
      <appender-ref ref="AdoNetAppender"></appender-ref>
    </root>
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="1" />
      <connectionType 

      value="System.Data.SqlClient.SqlConnection,System.Data, 
      Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <connectionStringName value="ConnectionStringLogging" />
      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) 
      VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%thread" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>
  </log4net>
</configuration>

web.config文件的快照

我在下面给出了快照,以供参考,在web.config文件中正确添加元素。

https://www.codeproject.com/KB/aspnet/1278018/image014.jpg

现在我们将运行我们用于在文本文件中记录消息的相同应用程序,但这次我们要将消息记录到数据库中。

现在让我们通过运行应用程序来测试它。

错误记录到数据库中

运行应用程序并访问默认控制器后,消息将记录在数据库中,如下所示。

https://www.codeproject.com/KB/aspnet/1278018/image015.png

在完成了解Log4net之后,接下来我们将继续讨论如何使用Nlog来记录消息。

NLOG

什么是Nlog

NLog是一个灵活的免费日志记录平台,适用于各种.NET平台,包括.NET standardNLog可以轻松写入多个目标(数据库,文件,控制台)并即时更改日志记录配置。

参考来自:—— https://nlog-project.org/

NuGet添加项目的引用

我们将从NuGet包安装2个包NLogNLog.Config

https://www.codeproject.com/KB/aspnet/1278018/image017.png

添加NLog的引用后,接下来我们将配置它以记录错误。

我们将看到在NLog中有2种日志记录的方法

  1. 在文本文件中
  2. 在数据库中 

Nlog日志记录在文本文件中

级别

典型用途

Fatal

发生了一件坏事应用程序即将关闭

Error

有些事情失败了应用程序可能会也可能不会继续工作

Warn

出乎意料的事应用程序将继续工作

Info

正常行为如邮件发送给用户,更新配置文件等

Debug

用于调试执行查询,用户通过身份验证,会话已过期

Trace

用于跟踪调试开始方法X,结束方法X.

参考自:https://github.com/NLog/NLog/wiki/Configuration-file#log-levels

让我们从在文本文件中的日志记录开始。为了在NLog中执行此操作,我们需要在web.config文件中添加配置以便在文本文件中写入。

代码片段

<configSections>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
  </configSections>

  <nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <targets>
      <target name="logfile" xsi:type="File"

              maxArchiveFiles="10"

              archiveAboveSize="5242880"

              archiveEvery="Minute"

              archiveNumbering="Sequence"

              fileName="${basedir}/ErrorLog/logfile.txt"

              layout="------${level}(${longdate})${machinename}------${newline}
                      Exception Type:${exception:format=Type} |
                      Exception Message:${exception:format=Message} |
                      Stack Trace:${exception:format=Stack Trace} |
                      Additional Info:${message}${newline}" />
    </targets>
    <rules>
      <logger name="*" minlevel="Trace" writeTo="logfile" />
    </rules>
  </nlog>

您可以根据需要设置许多选项,您可以根据文件的时间大小存档日志。对于这个例子,我是根据时间和大小来完成的, 因为我已经通过了archiveEvery =“Minute”,对于大小,我提供了archiveAboveSize =“5242880”,大小是以字节5MB =“5,242,880”为单位。

链接:——https://github.com/nlog/NLog/wiki/File-target

web.config文件的快照

我在下面给出了快照,以供参考,在web.config文件中正确添加元素。

​​​​​​https://www.codeproject.com/KB/aspnet/1278018/image019.png

在配置NLog后,接下来我们将在其中添加带有Index操作方法的DefaultController,其接下来用于日志记录,我们将使用LogManager类创建Logger实例。

代码片段

public class DefaultController : Controller
    {
        public readonly Logger Logger = NLog.LogManager.GetCurrentClassLogger();
        // GET: Default
        public ActionResult Index()
        {
            try
            {
                Logger.Debug("Hi I am NLog Debug Level");
                Logger.Info("Hi I am NLog Info Level");
                Logger.Warn("Hi I am NLog Warn Level");
                throw new NullReferenceException();
                return View();
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "Hi I am NLog Error Level");
                Logger.Fatal(ex, "Hi I am NLog Fatal Level");
                throw;
            }
        }
    }

在创建Logger实例后,我们将调用各种日志记录级别方法来记录消息。

现在让我们通过运行应用程序来测试它。

错误记录的文件

https://www.codeproject.com/KB/aspnet/1278018/image021.png

现在我们已经完成了在文本文件中记录消息,接下来在配置文件中进行了一些更改,我们将以简单的步骤将日志记录消息发送到数据库中

NLog日志记录到数据库中

要把日志记录到数据库中,我们需要先在数据库中创建一个表。

https://www.codeproject.com/KB/aspnet/1278018/image023.png

用于创建表的脚本

CREATE TABLE [dbo].[NLog](
    [id] [int] IDENTITY(1,1) NOT NULL Primary key,
    [timestamp] [datetime] NOT NULL,
    [level] [varchar](100) NOT NULL,
    [logger] [varchar](1000) NOT NULL,
    [message] [varchar](3600) NOT NULL,
    [Callsite] [varchar](3600) NULL,
    [exception] [varchar](3600) NULL
)

完成创建NLog表后,接下来我们将添加配置设置到现有web.config文件以记录到数据库中。

我们只需要在现有的NLog配置中添加一个具有新名称的新目标。这个目标包含数据库的连接字符串以及SQL插入查询以插入数据库,下一步,我们需要传递包含要与之一起记录的数据的参数,我们需要在rules元素中使用日志级别(“trace”)注册目标(“database”)。     

用于记录数据库的配置设置

<target name="database" type="Database" 

connectionString="data source=SAI-PC\SQLEXPRESS;
initial catalog=LoggingDatabase;
integrated security=false;
persist security info=True;
User ID=sa;Password=Pass$123">
        <commandText> insert into NLog ([TimeStamp],[Level],Logger, [Message], Callsite, Exception) 
        values (@TimeStamp, @Level, @Logger, @Message, @Callsite, @Exception); </commandText>
        <parameter name="@TimeStamp" layout="${date}" />
        <parameter name="@Level" layout="${level}" />
        <parameter name="@Logger" layout="${logger}" />
        <parameter name="@Message" layout="${message}" />
        <parameter name="@Callsite" layout="${callsite}" />
        <parameter name="@Exception" layout="${exception:tostring}" />
        <dbProvider>System.Data.SqlClient</dbProvider>
      </target>
    <rules>
      <logger name="*" minlevel="Trace" writeTo="database" />
    </rules>

注意: - * - 匹配0个或更多字符。

添加新目标以记录数据库中的消息后,web.config文件的快照

https://www.codeproject.com/KB/aspnet/1278018/image024.png

现在让我们通过运行应用程序来测试它。

错误记录到数据库中

运行应用程序并访问默认控制器后,消息将记录在数据库中,如下所示。

https://www.codeproject.com/KB/aspnet/1278018/image026.png

在完全理解Nlog后,接下来我们将继续前进,将看看如何使用Serilog Log记录消息。

Serilog

什么是Serilog

Serilog.NET应用程序的诊断日志记录库。它易于设置,具有干净的API,并可在所有最新的.NET平台上运行。虽然它在最简单的应用程序中也很有用,但Serilog对结构化日志记录的支持在检测复杂、分布式和异步应用程序和系统时尤为突出。

我们将在Serilog中看到两种记录的方法

  1. 在文本文件中
  2. 在数据库中 

NuGet添加项目的引用

我们将从NuGet包安装2个软件包“Serilog”“Serilog.Sinks.File”

Serilog:——Serilog.NET应用程序的日志记录库。

https://www.codeproject.com/KB/aspnet/1278018/image028.png

Serilog.Sinks.File:——此包用于将日志记录消息写入文本文件。

https://www.codeproject.com/KB/aspnet/1278018/image030.png

添加两个包之后,接下来我们将查看日志事件级别。

记录事件级别

Serilog使用级别作为分配日志事件重要性的主要手段。重要性递增的级别为:

接下来,我编写了一个帮助类,其中我编写了代码来集中事件日志记录。

名称

描述

Verbose

跟踪信息和调试细节通常,仅在异常情况下开启

Debug

内部控制流程和诊断状态转储,以便于查明已识别的问题

Information

感兴趣的事件或与外部观察员有关的事件默认启用的最低日志记录级别

Warning

可能的问题或服务/功能退化的指标

Error

表示应用程序或连接系统中的故障

Fatal

导致应用程序完全失败的严重错误

参考链接:——https://github.com/serilog/serilog/wiki/Writing-Log-Events

Serilog记录到文本文件中

让我们开始理解代码。我创建了一个名为helper的静态类,这样就可以在不创建对象的情况下使用它。下一个案例是仅初始化此类一次,这就是为什么我必须使用静态构造函数来初始化它。对于在文本文件中的日志记录,我们已经创建了LoggerConfiguration类的实例,并且对于日志记录错误,我已经将最低级别设置为错误,我们要写文本文件,但在我们要存储它的地方,它将在文件夹右侧,为了保持整洁以维护错误,我已经在该文件夹中创建了一个主文件夹“ ErrorLog ”,我必须根据调试,错误,警告...” 级别创建子文件夹。现在我们需要将消息写入此文件夹,这样我们就需要为它设置路径,我们将使用“ WriteTo.File方法,并以字符串形式将路径传递给它。接下来,我们不能将错误消息记录为单个大文本文件,因为我不会帮助我们轻松跟踪消息记录。另一个原因是,如果文件大小变大,则无法轻松打开该文件以克服这种情况,我们可以使用rollingIntervalrollOnFileSizeLimit属性,在rollingInterval中,我们可以使用RollingInterval参数(无限,年,月,日,小时,分钟)滚动文件,在rollOnFileSizeLimit中,我们可以设置文件大小限制。为此,我们需要以字节为单位设置属性fileSizeLimitBytes并将rollOnFileSizeLimit设置为true。现在,在创建实例后,我根据不同的级别创建了不同的方法,以便我们可以根据需要使用不同的方法。 

https://www.codeproject.com/KB/aspnet/1278018/image032.png    

Helper类的代码片段

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Serilog;
using Serilog.Events;

namespace WebErrorLogging.Utilities
{
    public static class Helper
    {
        private static readonly ILogger Errorlog;
        private static readonly ILogger Warninglog;
        private static readonly ILogger Debuglog;
        private static readonly ILogger Verboselog;
        private static readonly ILogger Fatallog;

        static Helper()
        {

            // 5 MB = 5242880 bytes

            Errorlog = new LoggerConfiguration()
                .MinimumLevel.Error()
               .WriteTo.File(System.Web.Hosting.HostingEnvironment.MapPath("~/ErrorLog/Error/log.txt"),
                rollingInterval: RollingInterval.Day,
                fileSizeLimitBytes: 5242880,
                rollOnFileSizeLimit: true)
                .CreateLogger();

            Warninglog = new LoggerConfiguration()
                .MinimumLevel.Warning()
              .WriteTo.File(System.Web.Hosting.HostingEnvironment.MapPath("~/ErrorLog/Warning/log.txt"),
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 5242880,
                    rollOnFileSizeLimit: true)
                .CreateLogger();

            Debuglog = new LoggerConfiguration()
                .MinimumLevel.Debug()
              .WriteTo.File(System.Web.Hosting.HostingEnvironment.MapPath("~/ErrorLog/Debug/log.txt"),
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 5242880,
                    rollOnFileSizeLimit: true)
                .CreateLogger();

            Verboselog = new LoggerConfiguration()
                .MinimumLevel.Verbose()
              .WriteTo.File(System.Web.Hosting.HostingEnvironment.MapPath("~/ErrorLog/Verbose/log.txt"),
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 5242880,
                    rollOnFileSizeLimit: true)
                .CreateLogger();

            Fatallog = new LoggerConfiguration()
                .MinimumLevel.Fatal()
              .WriteTo.File(System.Web.Hosting.HostingEnvironment.MapPath("~/ErrorLog/Fatal/log.txt"),
                    rollingInterval: RollingInterval.Day,
                    fileSizeLimitBytes: 5242880,
                    rollOnFileSizeLimit: true)
                .CreateLogger();

        }

        public static void WriteError(Exception ex, string message)
        {
            //Error - indicating a failure within the application or connected system
            Errorlog.Write(LogEventLevel.Error, ex, message);
        }

        public static void WriteWarning(Exception ex, string message)
        {
            //Warning - indicators of possible issues or service / functionality degradation
            Warninglog.Write(LogEventLevel.Warning, ex, message);
        }

        public static void WriteDebug(Exception ex, string message)
        {
            //Debug - internal control flow and diagnostic state dumps to facilitate 
            //          pinpointing of recognised problems
            Debuglog.Write(LogEventLevel.Debug, ex, message);
        }

        public static void WriteVerbose(Exception ex, string message)
        {
            // Verbose - tracing information and debugging minutiae; 
            //             generally only switched on in unusual situations
            Verboselog.Write(LogEventLevel.Verbose, ex, message);
        }

        public static void WriteFatal(Exception ex, string message)
        {
            //Fatal - critical errors causing complete failure of the application
            Fatallog.Write(LogEventLevel.Fatal, ex, message);
        }

        public static void WriteInformation(Exception ex, string message)
        {
            //Fatal - critical errors causing complete failure of the application
            Fatallog.Write(LogEventLevel.Fatal, ex, message);
        }

    }
}

在创建一个helper之后,接下来我们将在DefaultControllerIndex操作方法中调用这个helper类来测试和记录所有类型的消息。

DefaultController的代码片段 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebErrorLogging.Utilities;

namespace WebErrorLogging.Controllers
{
    public class DefaultController : Controller
    {

        // GET: Default
        public ActionResult Index()
        {
            try
            {
                Helper.WriteDebug(null, "Debug ");
                Helper.WriteWarning(null, "Warning ");
                throw new NotImplementedException();
            }
            catch (Exception e)
            {
                Helper.WriteError(e, "Error");
                Helper.WriteFatal(e, "Fatal");
                Helper.WriteVerbose(e, "Verbose");
                throw;
            }

            return View();
        }
    }
}

在默认控制器中将Helper类添加到日志记录消息之后,我们将保存应用程序并对其进行测试。

最后输出

使用Serilog在文本文件中记录消息后的最终输出

https://www.codeproject.com/KB/aspnet/1278018/image033.png

使用Serilog在文本文件中完成日志消息之后,接下来我们将学习如何使用相同的Serilog将消息记录到SQL数据库中,但是使用另一个额外的NuGet包。

Serilog记录到数据库中

在这一部分中,我们将消息记录到SQL数据库中,以便我们将新的NuGet“ Serilog.Sinks.MSSqlServer ”添加到现有解决方案中。

NuGet添加项目的引用

https://www.codeproject.com/KB/aspnet/1278018/image034.png

安装NuGet包之后,现在我们将编写一个类似的帮助类,就像我们在文本文件中记录消息一样,但这次我们将在数据库中记录消息。

为此,我们首先要创建一个表。

https://www.codeproject.com/KB/aspnet/1278018/image036.png

用于创建表的脚本 

CREATE TABLE [dbo].[Serilogs](
    [Id] [int] IDENTITY(1,1) NOT NULL Primary Key,
    [Message] [nvarchar](max) NULL,
    [MessageTemplate] [nvarchar](max) NULL,
    [Level] [nvarchar](128) NULL,
    [TimeStamp] [datetime] NULL,
    [Exception] [nvarchar](max) NULL,
    [Properties] [xml] NULL)

在创建表之后,我们将编写一个帮助程序类HelperStoreSqlLog,它将集中记录并在Serilogs表中存储消息。

在数据库中设置日志记录时,需要关注3个要点。

  1. web.config文件中检查数据库的正确连接字符串
  2. 在数据库中创建Serilogs表。
  3. 要使用WriteTo.MSSqlServer方法在数据库中写入消息和错误,此方法需要2个参数作为输入,一个是连接字符串,另一个是您的表。

代码片段

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using Serilog;
using Serilog.Events;

namespace WebErrorLogging.Utilities
{
    public static class HelperStoreSqlLog
    {
        private static readonly ILogger Errorlog;
        private static readonly ILogger Warninglog;
        private static readonly ILogger Debuglog;
        private static readonly ILogger Verboselog;
        private static readonly ILogger Fatallog;
        private static readonly string ConnectionString = 
         ConfigurationManager.ConnectionStrings["ConnectionStringLogging"].ToString();

        static HelperStoreSqlLog()
        {

            Errorlog = new LoggerConfiguration()
                .MinimumLevel.Error()
                .WriteTo.MSSqlServer(ConnectionString, "Serilogs")
                .CreateLogger();

            Warninglog = new LoggerConfiguration()
                .MinimumLevel.Warning()
                .WriteTo.MSSqlServer(ConnectionString, "Serilogs")
                .CreateLogger();

            Debuglog = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.MSSqlServer(ConnectionString, "Serilogs")
                .CreateLogger();

            Verboselog = new LoggerConfiguration()
                .MinimumLevel.Verbose()
                .WriteTo.MSSqlServer(ConnectionString, "Serilogs")
                .CreateLogger();

            Fatallog = new LoggerConfiguration()
                .MinimumLevel.Fatal()
                .WriteTo.MSSqlServer(ConnectionString, "Serilogs")
                .CreateLogger();

        }

        public static void WriteError(Exception ex, string message)
        {
            //Error - indicating a failure within the application or connected system
            Errorlog.Write(LogEventLevel.Error, ex, message);
        }

        public static void WriteWarning(Exception ex, string message)
        {
            //Warning - indicators of possible issues or service / functionality degradation
            Warninglog.Write(LogEventLevel.Warning, ex, message);
        }

        public static void WriteDebug(Exception ex, string message)
        {
            //Debug - internal control flow and diagnostic 
            // state dumps to facilitate pinpointing of recognised problems
            Debuglog.Write(LogEventLevel.Debug, ex, message);
        }

        public static void WriteVerbose(Exception ex, string message)
        {
            // Verbose - tracing information and debugging minutiae; 
            //   generally only switched on in unusual situations
            Verboselog.Write(LogEventLevel.Verbose, ex, message);
        }

        public static void WriteFatal(Exception ex, string message)
        {
            //Fatal - critical errors causing complete failure of the application
            Fatallog.Write(LogEventLevel.Fatal, ex, message);
        }

        public static void WriteInformation(Exception ex, string message)
        {
            //Fatal - critical errors causing complete failure of the application
            Fatallog.Write(LogEventLevel.Fatal, ex, message);
        }
    }
}

在创建HelperStoreSqlLog之后,接下来我们将在DefaultControllerIndex操作方法中调用此HelperStoreSqlLog类来测试和记录所有类型的消息。

代码片段

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebErrorLogging.Utilities;

namespace WebErrorLogging.Controllers
{
    public class DefaultController : Controller
    {
        // GET: Default   
        public ActionResult Index()
        {
            try
            {
                HelperStoreSqlLog.WriteDebug(null, "Debug ");
                HelperStoreSqlLog.WriteWarning(null, "Warning ");
                throw new NotImplementedException();
            }
            catch (Exception e)
            {
                HelperStoreSqlLog.WriteError(e, "Error");
                HelperStoreSqlLog.WriteFatal(e, "Fatal");
                HelperStoreSqlLog.WriteVerbose(e, "Verbose");
                throw;
            }
            return View();
        }
    }
}

在默认控制器中将HelperStoreSqlLog类添加到日志消息后,我们将保存应用程序并对其进行测试。

 最后输出

使用Serilog在数据库中记录消息后的最终输出

https://www.codeproject.com/KB/aspnet/1278018/image037.png

我们已经使用Serilog完成了日志消息,接下来我们将看到一些配置,我们可以使用Serilog中的appsettings来完成。

Serilog.Settings.AppSettings    

到目前为止,我们已经完全使用代码配置了Serilog,现在我们将使用appsettings在文本文件中执行相同的日志消息配置。

https://www.codeproject.com/KB/aspnet/1278018/image038.png

安装软件包之后,接下来我们将在appsettings中进行配置设置。

使用Serilog.Settings.AppSettings在文本文件中记录消息的Appsettings 

<appSettings>

    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />

    <!-- appSettings for Serilog Storing in Text file  -->
    <add key="serilog:minimum-level" value="Verbose" />
    <add key="serilog:using:File" value="Serilog.Sinks.File" />
    <add key="serilog:write-to:File.path" 

         value="E:\DemoProject\WebErrorLogging\WebErrorLogging\ErrorLog\Error\log.txt" />
    <add key="serilog:write-to:File.fileSizeLimitBytes" value="1234567" />
    <add key="serilog:write-to:RollingFile.retainedFileCountLimit" value="10" />
    <add key="serilog:write-to:File.rollingInterval" value="Day"/>
    <!-- appSettings for Serilog Storing in Text file  -->

  </appSettings>

appsettings中进行配置后,接下来我们将对代码进行一些更改,使其适用于此配置。

代码片段

代码中配置的主要部分是使用“.ReadFrom.AppSettings()”方法从我们配置的appsetting中读取配置。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Serilog;
using WebErrorLogging.Utilities;

namespace WebErrorLogging.Controllers
{
    public class DefaultController : Controller
    {
        private ILogger _errorlog;
        public ActionResult Index()
        {
            try
            {
                throw new NotImplementedException();
            }
            catch (Exception e)
            {
                _errorlog = new LoggerConfiguration()
                    .ReadFrom.AppSettings()
                    .CreateLogger();

                _errorlog.Error(e, "DefaultController");
                throw;
            }
            return View();
        }
    }
}

添加Serilog.Settings.AppSettings后,接下来我们将保存应用程序并对其进行测试。

 最后输出

https://www.codeproject.com/KB/aspnet/1278018/image040.png

https://www.codeproject.com/KB/aspnet/1278018/image042.png

最后,我们使用serilog完成了日志消息,接下来我们将要看看最后一个最好的日志记录选项是ELMAH

ELMAH

什么是ELMAH

错误日志记录模块和处理程序(ELMAH)。

  • 记录几乎所有未处理的异常。
  • 用于远程查看记录的异常的整个日志的网页。
  • 用于远程查看任何一个已记录异常的完整详细信息的网页,包括彩色堆栈跟踪。
  • 在许多情况下,您可以查看ASP.NET为给定异常生成的原始黄色死亡屏幕,即使关闭了自定义错误模式也是如此。
  • 每个错误发生时的电子邮件通知。
  • 来自日志的最后15个错误的RSS提要。

参考来自:——https://code.google.com/archive/p/elmah/

我们将看到在Elmah中日志记录的一种方式

  1. 在数据库中

在这部分中,我们将使用ELMAH将错误记录到数据库中。首先,我们需要从NuGet包中安装2ELMAH包。

ELMAH记录数据库

NuGet添加项目的引用

1. Elmah.MVC

https://www.codeproject.com/KB/aspnet/1278018/image044.png

2. elmah.sqlserver

https://www.codeproject.com/KB/aspnet/1278018/image046.png

安装elmah.sqlserver包时,它创建App_Readme文件夹,在该文件夹中,它添加了SQL查询脚本,用于创建Elmah的表和存储过程。

https://www.codeproject.com/KB/aspnet/1278018/image048.png

以类似的方式,在安装elmahelmah.sqlserver包时,它将XML配置添加到该配置文件中的web.config文件中,您将在此处看到elmah-sqlserver标记添加到连接字符串部分中,您需要提供数据库连接设置。

安装elmah.sqlserver包后添加的elmah-sqlserver标记片段。

<connectionStrings>
  <!-- TODO: Replace the ****'s with the correct entries -->
  <add name="elmah-sqlserver"
       connectionString="Data Source=****;User ID=****;Password=****;Initial Catalog=****;"
       providerName="System.Data.SqlClient" />
</connectionStrings>

用正确的数据库凭据替换“****”以连接到数据库。

<connectionStrings>
    <!-- TODO: Replace the ****'s with the correct entries -->
    <add name="elmah-sqlserver" 

         connectionString="Data Source=SAI-PC\SQLEXPRESS;User ID=sa;Password=Pass$123;
         Initial Catalog=LoggingDatabase;" 

         providerName="System.Data.SqlClient" />
  </connectionStrings>

设置连接字符串后,接下来你需要在数据库中执行Elmah.Sqlserver脚本,以生成Elmah的表和存储过程。

下面是执行Elmah SqlServer 脚本后的快照

https://www.codeproject.com/KB/aspnet/1278018/image049.png

现在我们已经配置了ELMAH,让我们创建一个带有Index操作方法的默认控制器,这会抛出一个错误。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebErrorLogging.Controllers
{
    public class DefaultController : Controller
    {
        public ActionResult Index()
        {
            try
            {
                throw new NotImplementedException();
            }
            catch (Exception)
            {
                throw;
            }
            return View();
        }
    }
}

添加ControllerIndex操作之后,接下来我们将保存应用程序并对其进行测试。

输出

使用ELMAH在数据库中记录错误后的最终输出

https://www.codeproject.com/KB/aspnet/1278018/image050.png

现在我们在浏览器上存储错误查看错误,我们需要在web.config文件中进行配置,如下所示。

1.web.config中的<system.web>元素下添加的片段

https://www.codeproject.com/KB/aspnet/1278018/image052.png

片段

<!--Newly Added-->  
    <httpHandlers>  
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />  
    </httpHandlers>  
<!--Newly Added-->

2.要在web.config中的<system.webServer>元素下添加的代码段

https://www.codeproject.com/KB/aspnet/1278018/image054.png

片段

<!--Newly Added-->
<handlers>
  <add name="Elmah" verb="POST,GET,HEAD" path="elmah.axd"
       type="Elmah.ErrorLogPageFactory, Elmah" />
</handlers>
<!--Newly Added-->

3.要添加到web.config中的 <elmah>元素中的代码段 

https://www.codeproject.com/KB/aspnet/1278018/image056.png

片段

<elmah>
  <security allowRemoteAccess="0" />
  <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah-sqlserver" />
</elmah>

什么是allowRemoteAccess

https://www.codeproject.com/KB/aspnet/1278018/image058.png

默认情况下,不允许远程访问/elmah.axd,这意味着请求除了localhost之外的其他所有URL,返回HTTP状态代码403。不建议打开远程访问ELMAH UI,但是在某些情况下,它可能是有道理的。将allowRemoteAccess设置为1true,可以在面向公众的网站上访问/elmah.axd

参考自:——https://blog.elmah.io/elmah-security-and-allowremoteaccess-explained/

现在要查看网页上的错误,您需要在URL http://localhost:55946/elmah.axd末尾输入“elmah.axd”  如下所示。

如果您已在IIS中托管您的站点,则需要输入URL,例如  http://xyz.com/elmah.axd

最后输出

https://www.codeproject.com/KB/aspnet/1278018/image059.png

最后,我们学习了如何使用最适合以简单方式记录ASP.NET MVC应用程序的所有4个记录器。这些记录器已被许多公司用于真是生成应用中。

源代码Log4Net的链接:——https://github.com/saineshwar/WebErrorLogging_Log4Net

源代码NLog的链接:——https://github.com/saineshwar/WebErrorLogging_NLog

源代码Serilog的链接:——https://github.com/saineshwar/WebErrorLogging_Serilog

源代码链接ELMAH:——https://github.com/saineshwar/WebErrorLogging_ELMAH

 

原文地址:https://www.codeproject.com/Articles/1278018/Best-Logging-libraries-for-ASP-NET-MVC

猜你喜欢

转载自blog.csdn.net/mzl87/article/details/88074594