使用 NLog 需要先进行配置。可以通过文件配置或代码配置。大多数时候都是通过文件来配置。
配置文件搜索顺序
程序启动时会依次搜索以下文件,直到搜索到为止:
- 标准应用程序配置文件 app.config(例如
myapp.exe.config
)。 - 应用程序目录中的
myapp.exe.nlog
。 - 应用程序目录中的
NLog.config
。 NLog.dll.nlog
位于 NLog.dll 所在目录中(仅当 NLog 未安装在 GAC 中时)。
从这个顺序可以看出,当有多个项目时可以为每个 exe 独立配置规则,也可以共用一个规则。
配置文件
在工程目录下创建一个 NLog.config
文件,在 Visual Studio 中选中该文件将属性复制到输出目录
改为始终复制
或如果较新则复制
。
一个简单的配置文件:
1 |
|
测试代码:
1 | using NLog; |
控制台输出:
1 | 2024-04-25 23:22:03.6134|INFO|WinFormsApp1.Program|hello info |
日志文件输出:
1 | 2024-04-25 23:22:03.6134|INFO|WinFormsApp1.Program|hello info |
Targets
targets 部分定义日志目标。每个目标都由一个 target 元素表示。每个目标需要两个属性:
- name:目标名称,在 logger 中需要用到。
- type:目标类型,表示日志将写到哪里。
Type
目标 | 说明 | 文档 |
---|---|---|
Chainsaw | 将日志消息发送到 Log4J XML Viewer 应用程序的远程实例。 | Wiki |
ColoredConsole | 使用可自定义的颜色将日志消息写入控制台。 | Wiki |
Console | 将日志消息写入控制台。 | Wiki |
Database | 使用ADO.NET提供程序将日志消息写入数据库。数据库操作总是在事务之外执行。 | Wiki |
DebugSystem | 通过 Debug.WriteLine 发送日志消息。 | Wiki |
Debug | Wiki | |
Debugger | 将日志消息写入附加的托管调试器。 | Wiki |
EventLog | 将日志消息写入Windows事件日志。 | Wiki |
File | 将日志消息写入一个或多个文件。 | Wiki |
LogReceiverService | Wiki | |
Wiki | ||
Memory | Wiki | |
MethodCall | Wiki | |
Network | Wiki | |
NLogViewer | Wiki | |
Null | Wiki | |
OutputDebugString | Wiki | |
PerfCounter | Wiki | |
Trace | Wiki | |
WebService | Wiki |
每个 target 都有自己的配置属性,查看官方 Wiki 即可。其中用的最多的当然还是 File target 了。
注意,某些 target 还需要按照依赖包才会生效。
Layout
laytou
属性默认值是:
1 | ${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true} |
输出的日志:
1 | 2024-04-27 13:40:17.5794|TRACE|WindowsFormsApp.Program|start |
简单说,layout
就是由一系列的内置变量组合而成的。
变量 | 示例 | 说明 | 文档 |
---|---|---|---|
${shortdate} | 2024-04-27 | 当前日期 | Wiki |
${time} | 14:08:04.4274 | 当前时间 | Wiki |
${date} | 2024/04/27 14:04:02.735 | 当前日期时间(短) | Wiki |
${longdate} | 2024-04-27 13:49:06.1412 | 当前日期时间(长) | Wiki |
${ticks} | 638498236261006047 | 当前日期和时间的刻度值 | Wiki |
${level} | TRACE | 日志级别 | Wiki |
${logger} | WindowsFormsApp.Program | 记录器名称 | Wiki |
${message} | 日志内容 | Wiki | |
${callsite} | WindowsFormsApp.Program.Main | 调用站点。可包含函数名、源文件等信息 | Wiki |
${appdomain} | 0001:WindowsFormsApp.exe | 应用程序域 | Wiki |
${appsetting} | 应用程序设置配置 | Wiki | |
${assembly-version} | 1.0.0.0 | 程序集版本 | Wiki |
${gc} | 1291536 | 垃圾收集器的信息 | Wiki |
${hostname} | DESKTOP-XXXX | 计算机名 | Wiki |
${machinename | DESKTOP-XXXX | 运行进程的计算机名 | Wiki |
${local-ip} | 169.254.227.96 | 本地IP地址 | Wiki |
${processid} | 14476 | 进程ID | Wiki |
${processname} | WindowsFormsApp | 进程名称 | Wiki |
${processdir} | D:\MyApp | 进程目录 | Wiki |
${processinfo} | 进程信息。默认显示进程ID | Wiki | |
${processtime} | 00:00:04.836 | 进程启动以来的时间 | Wiki |
${threadname} | 线程名称 | Wiki | |
${threadid} | 线程ID | Wiki | |
${basedir} | D:\MyApp | 应用程序的位置 | Wiki |
${currentdir} | D:\MyApp | 工作路径 | Wiki |
${specialfolder} | 系统特殊文件夹路径 | Wiki | |
${tempdir} | 系统临时目录 | Wiki | |
${environment} | 环境变量 | Wiki | |
${registry} | 注册表值 | Wiki | |
${pad} | 将填充应用于另一个布局输出 | Wiki |
常用的一般就是进程、线程信息了。还有其他一些高级用法可以参考官方文档。
另外注意,某些变量需要依赖扩展包,否则不会生效。
我个人喜欢的一个布局:
1 | ${longdate} [${level:uppercase=true:padding=5}] [${threadid}] [${logger}] ${message} |
在默认的布局上对齐日志级别以及加入线程ID
1 | 2024-04-27 15:03:14.0145 [TRACE] [1] [WindowsFormsApp.Program] Hello |
Rules
rules 部分控制什么级别的日志输出到什么 target。一些例子:
1 |
|
NLog 会自上而下去尝试匹配每个 logger,匹配到了就打印日志到 target,除非遇到了 final 属性,比如:
1 | <rules> |
final
属性会阻止 NLog 继续向下匹配,所以这个例子只会将日志输出到 logfile target。
name
匹配记录器对象的记录器名称,可以包含通配符(*
和?
)。
创建 NLog 记录器对象时,必须提供类似 NLog.LogManager.GetLogger("logger name")
的记录器名称。还可以使用 NLog.LogManager.GetCurrentClassLogger()
从类上下文中提取记录器名称。
1 | internal static class Program |
记录器级别过滤器
如果规则包含多个级别声明属性( level 、 levels 、 minlevel 和 maxlevel ),则仅包含第一个级别声明使用属性或集合,其余的将被忽略。
级别声明属性按以下顺序处理:
- levels
- level
- minlevel 和 maxlevel (它们具有相同的优先级)
注意这里是我测试过的排序,与官方文档中的优先级不同(NLog v5.2.8)。