关于.net:如何在-ASPNET-Core-中使用-NLog-的高级特性

38次阅读

共计 6574 个字符,预计需要花费 17 分钟才能阅读完成。

NLog 是一个开源的轻量级日志框架,提供了丰盛的日志路由和治理性能,同时 NLog 也是非常容易的去配置和扩大,其实在之前的文章中我曾经探讨过了 Nlog,在这篇我筹备持续和大家讨论一下 NLog 的更多高级性能。

接下来看看如何通过 .config代码形式 配置 NLog,如何去 轮转日志,如何将 Log 对接 database,如何应用异步的模式进步日志写入性能,同时我还会分享一些 NLog 的教训技巧。

装置 NLog

能够通过 NuGet Package Manager 可视化界面 或者 NuGet Package Manager Console 控制台 装置以下包文件。

  • NLog.Web.AspNetCore
  • NLog.Extensions.Logging
  • NLog.Config

当你装置完 NLog.Config 之后,有一个叫做 NLog.config 文件会主动援用到你的我的项目中,值得注意的是,NLog.Config 对 NLog 来说不是惟一的,话中有话就是你即能够用 config 模式配置,也能够用 基于代码 的模式配置。

应用 .config 文件配置 NLog

NLog 提供了两种配置形式。

  • file-based 配置模式
  • code-based 配置模式

回到方才的问题, 如何采纳 file-based 模式,方才被引入的 NLog.Config 内容如下:


<?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"
autoReload="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <targets>
    <target name="logfile" xsi:type="File" fileName="D:\logs\LogMessages-${shortdate}.log" />
  </targets>
  <rules>
    <logger name="*" minlevel="Trace" writeTo="logfile" />
  </rules>
</nlog>

上面的代码展现了如何在 Controller 下用 NLog 记录日志。


 public class HomeController : Controller
 {Logger _logger = (Logger)LogManager.GetCurrentClassLogger(typeof(Logger));  

     public IActionResult Index()
      {_logger.Info("Application started");       
          return View();}
    //Other action methods
  }

如果你想通过编程的形式找到以后 NLog 的 target,可应用如下代码:


var fileTarget = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");

应用 代码配置 NLog

同样你也能够应用编码的模式配置 NLog,只须要调用 NLog 提供的 API 接口即可,上面的代码展现了如何配置 Nlog。


        private static void ConfigureNLog()
        {var logConfiguration = new LoggingConfiguration();
            
            var dbTarget = new DatabaseTarget();
            dbTarget.ConnectionString = "Data Source=JOYDIP;initial catalog=NLogDemo;User Id=sa;Password=sa1@3#.;"; dbTarget.CommandText = "INSERT INTO DbLog (level, callsite, message, logdatetime)" +"Values(@level, @callsite, @message, @logdatetime)";
            dbTarget.Parameters.Add(new DatabaseParameterInfo("@level", "${level}"));
            dbTarget.Parameters.Add(new DatabaseParameterInfo("@callSite", "${callSite}"));
            dbTarget.Parameters.Add(new DatabaseParameterInfo("@message", "${message}"));
            dbTarget.Parameters.Add(new DatabaseParameterInfo("@logdatetime","${date:s}"));

            var rule = new LoggingRule("*", LogLevel.Debug, dbTarget);

            logConfiguration.LoggingRules.Add(rule);
            LogManager.Configuration = logConfiguration;
        }

配置轮转日志

你能够让 NLog 主动实现 轮转日志 ,什么叫 轮转 呢?简略来说就是:你能够让 Nlog 只保留近 N 个小时的日志 并且主动删除大于 N 小时的日志,这个个性太实用了,否则的话,你须要常常到生产下来删除日志, 上面的代码展现了如何应用 .config 实现主动轮转日志。


<?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"
autoReload="true">
   <targets>
    <target name="logfile"
            xsi:type="File"
            fileName="${basedir}/logs/App.log"
            layout="${longdate}  ${message}"
            archiveFileName="${basedir}/logs/archive.{#}.log"
            archiveEvery="Day"
            archiveNumbering="Rolling"
            maxArchiveFiles="7"
            concurrentWrites="true"
            keepFileOpen="true" />
  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="logfile" />
  </rules>
</nlog>

记录日志到数据库

创立数据库

你能够应用 NLog 将日志接入到 database 中,上面的脚本用于创立几张记录日志的表。


CREATE TABLE [dbo].[DbLog]([Id] [int] IDENTITY(1,1) NOT NULL,
      [Level] [varchar](max) NULL,
      [CallSite] [varchar](max) NULL,
      [Message] [varchar](max) NULL,
      [AdditionalInfo] [varchar](max) NULL,
      [LogDateTime] [datetime] NOT NULL,
 CONSTRAINT [PK_DbLogs] PRIMARY KEY CLUSTERED
([Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

数据库连贯串和参数属性

接下来如何在 NLog 的 target 中指定数据库连贯串,请留神 connectionStringcommandText 是如何配置的。


<target name="database" xsi:type="Database" keepConnection="true"
 useTransactions="true"
 dbProvider="System.Data.SqlClient"
 connectionString="data source=localhost;initial
 catalog=NLogDemo;integrated security=false;
 persist security info=True;User ID=sa;Password=sa1@3#."commandText="INSERT INTO DbLog (level, callsite, message, additionalInfo,
 logdatetime) Values (@level, @callsite, @message, @additionalInfo,
 @logdatetime)">

应用参数化

最初,应用 参数化查问 来避免注入攻打,具体代码如下。


<parameter name="@level" layout="${level}" />
<parameter name="@callSite" layout="${callsite}" />
<parameter name="@message" layout="${message}" />
<parameter name="@additionalInfo" layout="${var:AdditionalInfo}" />
<parameter name="@logdatetime" layout="${date:s}" />

残缺的 NLog

以下是残缺的 NLog 文件仅供参考。


<?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"
autoReload="true">
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>
  <variable name="AdditionalInfo" value=""/> 
  <targets>
    <target name="database" xsi:type="Database" keepConnection="true"
    useTransactions="true"
    dbProvider="System.Data.SqlClient"
    connectionString="data source=localhost;initial
    catalog=NLogDemo;integrated security=false;persist security  
    info=True;User ID=sa;Password=sa1@3#."commandText="INSERT INTO DbLog
    (level, callsite, message, additionalInfo, logdatetime)
    Values (@level, @callsite, @message, @additionalInfo, @logdatetime)">
      <parameter name="@level" layout="${level}" />
      <parameter name="@callSite" layout="${callsite}" />
      <parameter name="@message" layout="${message}" />
      <parameter name="@additionalInfo" layout="${var:AdditionalInfo}" />
      <parameter name="@logdatetime" layout="${date:s}" />
    </target>       
  </targets>
  <rules>
    <logger levels="Debug,Info,Error,Warn,Fatal" name="databaseLogger" writeTo="database"/>
  </rules>
</nlog>

除了 SQL Server 之外,还能够应用 NLog 将日志记录到 MySQLOracleSQLite 数据库。

应用 AsyncWrapper 进步性能

NLog 反对多种 targets,比方:AsyncWrapper, BufferingWrapper, FallbackGroup 和 RetryingWrapper,异步的 target 为了晋升性能采纳 音讯的队列化 并在多个线程中提取队列音讯,上面的代码展现了如何应用 AsyncWrapper


<targets>
  <target xsi:type="AsyncWrapper"
          name="String"
          queueLimit="Integer"
          timeToSleepBetweenBatches="Integer"
          batchSize="Integer"
          overflowAction="Enum">
    <target ... />
  </target>
</targets>

你能够实现 AsyncWrapper 来实现日志记录的异步化,具体配置如下:


  <targets>
    <target name="asyncFile" xsi:type="AsyncWrapper">
      <target xsi:type="File" name="fileLog"
         fileName="${basedir}/Logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}"/>
    </target>
  </targets>
  <rules>
    <logger levels="Debug,Info,Error,Warn,Fatal" writeTo="asyncFile"/>
  </rules>

除了这种形式,你还能够在所有的 targets 上用 async=true 间接进行标记为异步化 target,如下配置所示:


<targets async="true">
  ... Write your targets here ...
</targets>

NLog 的最佳实际

这一大节列举了一些应用 NLog 的一些最佳实际

  • logger 实例应该动态化,这样就能够防止在程序中呈现屡次 logger 初始化带来的性能开销。
  • 利用好 NLog 的 Format(当你想结构化日志)反对,防止你本人对 string 的创立和拼接。
  • 指定 throwConfigExceptions="true",能够确保当 NLog 配置谬误的时候有具体的错误信息,例子如下:

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true" throwConfigExceptions="true">
  • 当记录完日志后,能够调用 LogManager.Shutdown() 来实现数据刷新并且敞开外部所有的线程和定时器。

NLog.LogManager.Shutdown();
  • 不要将 async 属性用在 AsyncWrapper 之上,否则性能会变慢。
  • 慎用 Trace 级别,因为 Trace 会记录所有的日志,思考应用 Debug 或者 Info 代替。
  • NLog 是轻量级并且疾速的,能够应用 asynchronous wrappers 的形式来晋升性能。

对于 NLog 还是有太多的话要说,NLog 提供了日志的结构化,不便在大量日志上进行疾速过滤和剖析,在将来的文章中我会探讨 NLog 的更多高级个性。

译文链接:https://www.infoworld.com/art…

更多高质量干货:参见我的 GitHub: csharptranslate

正文完
 0