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 中指定数据库连贯串,请留神 connectionString
和 commandText
是如何配置的。
<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 将日志记录到 MySQL
,Oracle
和 SQLite
数据库。
应用 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