使用 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)。
#相关阅读
Tutorial
Configuration file
Configure from code
Layouts
Nlog笔记