.NET NLog与Log4net与Serilog比较

在本文中,将介绍.NET中三种最受欢迎​​的日志记录框架:log4net,NLog和Serilog。

一、log4net概述

回溯到开始或至少很接近它的时候,.NET只有一个日志记录框架:log4net。它于2001年作为Java框架log4j的端口开始。它托管在Sourceforge上,以供您那些足以记住该平台的人使用。多年来,Apache Logging Services项目继续进行开发。

在过去的17年中,log4net已在成千上万的应用程序中使用。当然,它是所有现代.NET日志记录框架的祖父母。日志级别,日志记录器和附加器等概念在日志记录框架中几乎是通用的。这可能是喜忧参半的事情:没有其他框架能像log4net那样经过艰苦的考验。

过去,我们提供有关使用log4net的一些技巧,以及在.NET Core中使用它快速教程 冒着重复自己的风险,让我们至少看看如何设置记录器和记录消息。我们将对每个.NET日志记录框架执行相同的操作:生成一条消息,并将其记录到控制台和一个日志文件中。本文的所有代码都在Github上提供

只需安装log4net软件包即可从NuGet安装log4net。

log4net代码示例

我们将针对.NET Core编写所有代码,因为这是未来。前面我提到过log4net很旧。该遗产的一部分是,它不能与.NET Core配合使用。您在网上的大多数地方都找不到配置示例,但是幸运的是,配置的答案就在此博客上(谢谢,Matt!)。

 
using log4net;

using log4net.Config; 
using System; 
using System.IO; 
using System.Reflection; 
namespace LoggingDemo.Log4Net

{
    class Program 
        private static readonly ILog log = LogManager.GetLogger(typeof(Program)); 
        static void Main(string[] args) 
            var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly()); 
            XmlConfigurator.Configure(logRepository, new FileInfo("log4net.config")); 
            log.Debug("Starting up"); 
            log.Debug("Shutting down"); 
            Console.ReadLine(); 
}

 

我们将从一个名为log4net.config的文件中加载配置。这是一个XML配置文件,其中包含用于记录的设置。不要忘记将文件设置为复制到输出目录。  
<log4net>
   <appender name="Console" type="log4net.Appender.ConsoleAppender">
       <layout type="log4net.Layout.PatternLayout">
           <!-- Pattern to output the caller's file name and line number -->
           <conversionPattern value="%utcdate %5level [%thread] - %message%newline" />
       </layout>
   </appender>
   <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
       <file value="logfile.log" />
       <appendToFile value="true" />
       <maximumFileSize value="100KB" />
       <maxSizeRollBackups value="2" />
       <layout type="log4net.Layout.PatternLayout">
           <conversionPattern value="%utcdate %level %thread %logger - %message%newline" />
       </layout>
   <appender>
   <root>
       <level value="DEBUG" />
       <appender-ref ref="Console" />
       <appender-ref ref="RollingFile" />
   </root>
</log4net>

此配置文件非常长且复杂。定义了两个附加程序:一个用于写入控制台,另一个用于写入滚动文件,该文件的大小为100KB。我们必须在conversionPattern中定义自定义日志格式,因为默认的log4net配置为垃圾桶。设置conversionPattern后,我们将获得如下日志:

2018-08-18 18:57:37,278 DEBUG 1 LoggingDemo.Log4Net.Program - Starting up
2018-08-18 18:57:37,298 DEBUG 1 LoggingDemo.Log4Net.Program - Shutting down

  

在log4net上的结论

此处的配置是log4net失败。它很复杂,而且XML总是很难实现。可以使用code对其进行配置,但是没有充分的文档说明。实际上,“记录不充分”几乎是所有log4net的口号。这些示例很复杂,并且侧重于日志记录到SQL数据库(2009年这样)之类的事情。log4net有很多不同的附加程序,因此对于特定的日志记录情况,您可能不会挂在嘴上。

二、NLog概述

NLog也是一个相当老的项目。1.0版于2006年发布,但仍在积极开发中,最新版本已于2017年12月发布。log4net尚未在18个月内发布,这不一定很糟糕,因为该项目很稳定。NLog的最新版本增加了结构化日志记录并支持.NET Standard。

可以通过安装nlog软件包从NuGet进行安装。

NLog代码示例

 
using NLog;
using System;
namespace LoggingDemo.Nlog
{
    class Program
    {
        static void Main(string[] args)
        {
            LogManager.LoadConfiguration("nlog.config");
            var log = LogManager.GetCurrentClassLogger();
            log.Debug("Starting up");
            log.Debug("Shutting down");
            Console.ReadLine();
        }
    }
}

   

此处的代码与log4net非常相似:加载配置文件,然后登录。

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <targets>
   <target name="logfile" xsi:type="File" fileName="logfile.txt" />
   <target name="logconsole" xsi:type="Console" />
 </targets>
 <rules>
   <logger name="*" minlevel="Debug" writeTo="logconsole" />
   <logger name="*" minlevel="Debug" writeTo="logfile" />
 </rules>
</nlog>

   

嗯,现在这是NLog和log4net之间的区别。配置文件仍然是XML,但是看起来更干净。我们不需要编写自己的格式。

日志格式如下:

2018-08-18 13:27:10.5022|DEBUG|LoggingDemo.Nlog.Program|Starting up
2018-08-18 13:27:10.5623|DEBUG|LoggingDemo.Nlog.Program|Shutting down

还有一种使用代码配置日志记录的方法。 

var config = new NLog.Config.LoggingConfiguration();
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "logfile.txt" };
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logconsole);
config.AddRule(LogLevel.Debug, LogLevel.Fatal, logfile);
NLog.LogManager.Configuration = config;

 对我来说,基于代码的配置看起来还不错,但是肯定不那么流畅。

关于NLog的结论

NLog和log4net之间有一些细微的差异。与Log4net相比,NLog易于配置,并且支持基于代码的配置更加简洁。我认为NLog中的默认设置比log4net中的设置更合理。

我对这两个框架都遇到的一个问题是,如果记录器出现问题(在我的情况下,是忘记复制配置文件),那么就没有任何提示。这个想法是,日志记录问题不应使应用程序崩溃。我可以体会到这种愿望,但是如果启动过程中记录失败,那将是致命的。记录不是,也不应该是事后的想法。许多自动问题检测都依赖于日志输出,而没有那么严重。

三、Serilog概述

该系列的最新日志记录框架Serilog于2013年发布。Serilog与其他框架之间的最大区别在于,该框架旨在进行结构化的现成日志记录。NLog还支持  结构化日志记录,但它只是在最近才添加   ,  基准测试表明  使用它会严重影响性能。 编辑:似乎有一些问题与基准而  这一次  是一个更好的基础。 

等待!什么是结构化日志记录?天哪,我以为你永远不会问。

结构化日志记录示例

通常,您会发现编写的日志包含两件事:消息和值。

例:

log.Debug($"User id is: ${userId}");

在大多数日志记录框架中,这只是转换为日志文件中的文本。文本很不错,但是知道记录的值称为userId并能够搜索该值实际上非常有用。Serilog保持属性一直可用到目的地。 

log.Debug("User id is {@userId}", userId);

Serilog由一家商业公司https://getseq.net/提供支持,后者提供了一个非常不错的日志聚合工具。当然,您也可以将日志发送到我们最喜欢的日志聚合器:Retrace。Retrace还支持在日志中保留属性。

安装Serilog比NLog或log4net稍微复杂些,因为它努力做到高度模块化。对于我们的示例代码,您将需要软件包serilog,serilog.sinks.file和serilog.sinks.console。

Serilog代码示例

这次无需任何XML配置!Serilog的配置使用流畅的界面,使其非常美观和干净。比较与log4net相比,设置滚动文件记录器有多么容易。 

using Serilog;
using System;
namespace LoggingDemo.Serilog
{
    class Program
    {
        static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.File("logfile.log", rollingInterval: RollingInterval.Day)
                .CreateLogger();
            Log.Debug("Starting up");
            Log.Debug("Shutting down");
            Console.ReadLine();
        }
    }
}
The logging output from Serilog looks like:

  

 日志 输出  Serilog  看起来 
2018-08-18 14:37:21.463 -06:00 [DBG] Starting up
2018-08-18 14:37:21.560 -06:00 [DBG] Shutting down

Serilog结论

Serilog中的结构化日志支持非常好,而且配置简便。我能够比其他任何人更轻松地启动和运行Seirlog。Serilog中的日志可以发送到很多目的地。Serilog称这些东西为“接收器”,您可以在https://github.com/serilog/serilog/wiki/Provided-Sinks中查看非常全面的列表

我在Serilog中真正喜欢的另一个概念是浓缩器。这是一段针对每个日志请求运行的代码,向其中添加了新信息。例如,如果您需要在ASP.NET中包含有关请求的信息,则可以使用扩充器将属性附加到日志消息中。您甚至可以使用扩充程序来更改日志条目。例如,有一个丰富器可以提高堆栈跟踪的可理解性。

结论:最佳日志记录框架是……

我保证我们将在本文结尾处给出一个建议,即:Serilog。该API更现代,更易于设置,维护更好,并且默认情况下进行结构化日志记录。添加浓缩器的功能使您能够拦截和修改消息,这非常有用。我选择Serilog作为最佳的.NET日志记录框架。

日志记录是任何应用程序的重要方面,不应被视为事后考虑。用右手启动您的应用程序并使用结构化日志记录。您还应该使用日志聚合器(如Retrace)在一个位置查看所有应用程序日志。

你可能感兴趣的