NLog 实战指南:配置灵活的 .NET 老牌日志框架
NLog 中文实战指南:nlog.config XML 配置(targets/rules/layout)、六个日志级别、文件轮转与自动重载、结构化日志 ${properties}、代码配置方式、ASP.NET Core 集成,以及观测云 DataKit 采集落地方案。
NLog 是 .NET 生态中最灵活的老牌日志框架之一:强大的路由规则、丰富的 layout 渲染器、配置文件热重载。它既能服务简单的控制台程序,也能驾驭复杂的多目标路由场景。本文覆盖 NLog 的核心配置与生产实践,并给出观测云平台接入方案。
核心要点速览
- targets + rules 两段式配置:target 定义"写到哪、什么格式",rule 定义"哪个 logger、哪个级别、路由到哪个 target"。
- autoReload="true" 热重载:监测已加载的配置文件变化并尝试重载;需确认文件路径、配置有效及文件监测可用。
- 结构化日志:
logger.Info("用户 {UserId} 登录", id)参数存为属性,${properties}或 JsonLayout 输出。 - 生产落地:JsonLayout 输出文件/控制台,观测云 DataKit 采集,监控器告警。
快速上手: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"
internalLogLevel="Warn"
internalLogFile="logs/nlog-internal.txt">
<targets>
<target name="console" xsi:type="Console"
layout="${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />
<target name="file" xsi:type="File"
fileName="logs/app-${shortdate}.log"
layout="${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="console" />
<logger name="*" minlevel="Error" writeTo="file" />
</rules>
</nlog>
代码中使用:
var logger = NLog.LogManager.GetCurrentClassLogger();
logger.Trace("Trace message");
logger.Debug("调试细节");
logger.Info("应用启动");
logger.Warn("配置缺失");
// 在 catch (Exception ex) 块内使用:
// logger.Error(ex, "数据库连接失败"); // 输出捕获的异常信息
logger.Fatal("系统级故障");
六个级别:Trace → Debug → Info → Warn → Error → Fatal。上面的规则实现了"控制台看全部 Info+,文件只留 Error+"的分级路由。
internalLogLevel/internalLogFile 是 NLog 自身排障的内部日志,生产建议开 Warn。
layout 渲染器与结构化属性
layout 中的 ${...} 是渲染器,常用的有:
| 渲染器 | 含义 |
|---|---|
${longdate} / ${shortdate} |
完整/短日期时间 |
${level:uppercase=true} |
级别(大写) |
${logger} |
logger 名称(通常是类名) |
${message} |
日志消息 |
${exception:format=tostring} |
异常完整信息 |
${machinename} ${processid} ${threadid} |
机器/进程/线程 |
结构化参数:
logger.Info("用户 {UserId} 购买了 {Item},金额 {Price}", 42, "Orange Soda", 100.00);
参数被存为属性(properties),layout 中用 ${properties:item=UserId} 引用,或直接用 JsonLayout 全部输出。
JSON 输出:JsonLayout
<target name="jsonfile" xsi:type="File" fileName="logs/app.json">
<layout xsi:type="JsonLayout" includeEventProperties="true">
<attribute name="time" layout="${longdate}" />
<attribute name="level" layout="${level:uppercase=true}" />
<attribute name="logger" layout="${logger}" />
<attribute name="message" layout="${message}" />
<attribute name="exception" layout="${exception:format=tostring}" />
</layout>
</target>
输出一行一个 JSON 对象,结构化属性自动展开为字段——这是接入日志平台的推荐格式。
JSON 文件写出后,取一条正常日志和一条异常日志验证采集结果。观测云 DataKit的文件采集需要配置路径、读取权限与解析规则;重点检查 JsonLayout 输出的时间、级别及异常属性,将其映射到 time、status 后,再按服务与 logger 检索。容器输出则先核对运行时的日志采集配置,不能只凭控制台有输出就认定已上报。
文件轮转与高级路由
<target name="file" xsi:type="File"
fileName="logs/app.log"
archiveSuffixFormat="_{1:yyyyMMdd}_{0:00}"
archiveAboveSize="104857600"
maxArchiveFiles="10" />
以上使用 NLog 6 的 archiveSuffixFormat;旧版本需按对应文档配置 archiveFileName 等属性。单文件超 100MiB 自动归档,保留 10 个历史文件。规则还可以按 logger 名分流:
<!-- 放在其他输出规则之前 -->
<logger name="Microsoft.*" maxlevel="Warn" final="true" />
<!-- paymentsFile 需在 targets 中定义 -->
<logger name="MyApp.Payments.*" minlevel="Info" writeTo="paymentsFile" />
第一条不指定目标,并用 final 阻止 Warn 及以下的 Microsoft 日志继续匹配;它必须位于其他输出规则之前,不能撤销先前规则已经写出的日志。
代码配置与 ASP.NET Core 集成
不用 XML 也可以纯代码配置(NLog.LogManager.Setup() 流式 API);ASP.NET Core 安装 NLog.Web.AspNetCore 后:
builder.Logging.ClearProviders();
builder.Host.UseNLog();
NLog 接管 ILogger 体系,框架日志与业务日志统一出口。
常见问题(FAQ)
NLog 和 Serilog 怎么选?
两者都活跃且成熟。NLog 胜在 XML 配置的路由规则表达力与热重载;Serilog 胜在消息模板与 Sink 生态。团队熟悉度优先,新项目两者皆可,本系列倾向 Serilog 的结构化体验。
改了 nlog.config 没生效?
检查 autoReload="true" 是否开启,以及文件的"复制到输出目录"属性(CopyToOutputDirectory)是否设为 Always——常见的坑是改的是源文件、运行目录里还是旧副本。
internalLog 有什么用?
NLog 自身故障(如文件无权限、配置错误)通常通过内部日志报告;是否抛出还取决于 ThrowExceptions、ThrowConfigExceptions 等配置和错误类型。排查"日志没输出"时先看 internalLogFile,建议生产设为 Warn。
异步写入怎么配?
用 AsyncWrapper 包装 target,并让规则写入该包装目标。默认队列满时可能丢弃日志;可显式设置 overflowAction="Block" 施加背压,但业务线程会等待。正常退出时调用 LogManager.Shutdown(),异常退出仍可能丢失队列数据。
系列阅读
- 上一篇:Serilog 实战指南
- 下一篇:log4net 实战指南
- 相关阅读:.NET 日志入门 | .NET 日志库对比