本文转载自微信公众号「 码农读书」,作者 码农读书 。转载本文请联系 码农读书公众号。
NLog 是一个开源的轻量级日志框架,提供了丰富的日志路由和管理功能,同时 NLog 也是非常容易的去配置和扩展,其实在之前的文章中我已经讨论过了 Nlog,在这篇我准备继续和大家讨论一下 NLog 的更多高级功能。
接下来看看如何通过 .config 和 代码方式 配置 NLog,如何去 轮转日志,如何将 Log 对接 database,如何使用异步的模式提高日志写入性能,同时我还会分享一些 NLog 的经验技巧。
安装 NLog
可以通过 NuGet Package Manager 可视化界面 或者 NuGet Package Manager Console 控制台 安装以下包文件。
当你安装完 NLog.Config 之后,有一个叫做 NLog.config 文件会自动引用到你的项目中,值得注意的是,NLog.Config 对 NLog 来说不是唯一的,言外之意就是你即可以用 config 模式配置,也可以用 基于代码 的模式配置。
使用 .config 文件配置 NLog
NLog 提供了两种配置方式。
回到刚才的问题,如何采用 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 的一些最佳实践
- <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- autoReload="true" throwConfigExceptions="true">
- NLog.LogManager.Shutdown();
关于 NLog 还是有太多的话要说,NLog 提供了日志的结构化,方便在大量日志上进行快速过滤和分析,在未来的文章中我会讨论 NLog 的更多高级特性。
译文链接:https://www.infoworld.com/article/3438540/using-advanced-nlog-features-in-aspnet-core.html
网站 虚拟主机 选多大好?很多新手站长,对于网站虚拟主机还不是很了解,不知道...
工信部发布,近日,有不法分子偷盗个人手机后,在某政务App窃取用户个人信息,进...
服务器租用 购买前注意事项 做过SEO的朋友都知道,一个稳定、合适的服务器是建立...
内置示例数据集 seaborn内置了十几个示例数据集,通过load_dataset函数可以调用...
景安 域名 怎么实名认证?其实,域名的实名方法其实都差不多,跟在哪儿注册关系...
TOP云 (west.cn)7月14日消息,易到用车今日发布消息称,其官网 域名 yongche.c...
前阵子开发了公司领劵中心的项目,这个项目是以 redis 作为关键技术落地的。 先...
最近很火的TailwindCSS有一个功能: 可以将项目未使用的css选择器从编译后css文...
在上一篇文章:Scrapy源码剖析:Scrapy是如何运行起来的?我们主要剖析了 Scrapy...
作者 缪可延 IBM 副总裁,大中华区云计算与认知软件事业部总经理 企业正处在一个...