第2章:NLog入门:NuGet安装与配置文件详解
好,咱们正式开始动手了。这一章我带你从零搭建一个NLog日志系统。说白了,就是让程序学会「说话」——把运行过程中的关键信息记录下来。
我个人习惯,不管项目大小,日志系统都是第一个要集成的组件。为什么?因为程序跑起来之后,你根本不知道它内部发生了什么。日志就是你的眼睛。
2.1 安装NLog NuGet包
先打开你的.NET项目(控制台、Web API都行)。在包管理器控制台里敲一行命令:
Install-Package NLog
或者你用图形界面也行。右键项目 → 管理NuGet程序包 → 搜索NLog → 安装。
嗯,这里要注意:如果你用的是.NET Core或.NET 5+,建议同时安装这个扩展包:
Install-Package NLog.Extensions.Logging
这个包能让NLog和微软原生的ILogger接口无缝对接。我在项目中遇到过有人只装了NLog本体,结果发现依赖注入用不了,折腾了半天。
2.2 配置文件详解:targets和rules
NLog的核心配置就两个东西:targets(目标)和rules(规则)。
你想想看,targets就是「日志要写到哪里去」,rules就是「什么样的日志写到哪个target」。就这么简单。
默认情况下,NLog会在项目根目录找 NLog.config 文件。我个人习惯手动创建这个文件,而不是用appsettings.json。因为配置文件独立出来,修改时不用重新编译。
来看一个最基础的配置模板:
<?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">
<!-- 定义目标 -->
<targets>
<target name="console"
xsi:type="Console"
layout="${longdate} | ${level:uppercase=true} | ${message}" />
<target name="file"
xsi:type="File"
fileName="${basedir}/logs/app-${shortdate}.log"
layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message}" />
</targets>
<!-- 定义规则 -->
<rules>
<logger name="*"
minlevel="Info"
writeTo="console" />
<logger name="*"
minlevel="Debug"
writeTo="file" />
</rules>
</nlog>
我来拆解一下这里面的门道。
targets节点
每个target都有一个name属性,这是它的唯一标识。rules里通过这个名字来引用。
xsi:type 指定目标类型。最常用的有:
| 类型 | 说明 | 适用场景 |
|---|---|---|
| Console | 输出到控制台 | 开发调试阶段 |
| File | 写入文件 | 生产环境持久化 |
| Database | 写入数据库 | 集中式日志存储 |
| 发送邮件 | 错误告警 |
layout 属性定义了日志的格式。我常用的占位符有这些:
${longdate}— 完整日期时间,比如 2025-01-15 14:30:22.1234${level}— 日志级别(Info、Error等)${logger}— 记录器名称,通常是类名${message}— 日志消息正文${exception}— 异常信息${callsite}— 调用位置(文件名、行号)
fileName 支持动态路径。我用 ${basedir} 表示应用程序根目录,${shortdate} 按日期自动分文件。这样每天一个日志文件,不会撑爆磁盘。
rules节点
规则决定了日志的流向。每个rule包含:
name— 匹配的记录器名称,支持通配符*minlevel— 最低日志级别,低于这个级别的忽略maxlevel— 最高日志级别(可选)writeTo— 写入哪个targetfinal— 如果匹配,是否停止后续规则
规则是从上到下依次匹配的。我曾经踩过一个坑:把Error级别的规则写在Info规则下面,结果Error日志被Info规则先匹配走了,导致没有触发邮件告警。嗯,顺序很重要。
2.3 第一个控制台日志输出
配置写好了,咱们来写代码验证一下。
创建一个控制台应用,在 Program.cs 里写:
using NLog;
class Program
{
// 获取当前类的日志记录器
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
// 输出不同级别的日志
logger.Trace("这是Trace级别的日志,最详细");
logger.Debug("这是Debug级别的日志,调试用");
logger.Info("系统启动成功,用户登录了");
logger.Warn("磁盘空间不足,剩余10%");
logger.Error("数据库连接超时,请检查网络");
logger.Fatal("系统崩溃,无法恢复");
Console.WriteLine("日志已输出,按任意键退出...");
Console.ReadKey();
}
}
运行一下,你会看到控制台输出了Info级别及以上的日志。为什么Trace和Debug没出来?因为我们的规则里 minlevel="Info",低于Info的都被过滤掉了。
再看文件输出。去项目目录下的 logs 文件夹,你会看到一个 app-2025-01-15.log 这样的文件。打开看看,里面记录了Debug级别及以上的所有日志。
为什么文件里能看到Debug,而控制台看不到?因为两条规则的 minlevel 不一样。文件规则是Debug,控制台规则是Info。这就是rules的灵活之处——你可以为不同目标设置不同的过滤条件。
2.4 日志级别的选择建议
很多新手会问:到底该用哪个级别?我分享一个实战经验:
| 级别 | 什么时候用 | 举个栗子 |
|---|---|---|
| Trace | 方法入口/出口,参数值 | 「调用GetUser方法,参数userId=123」 |
| Debug | 开发调试时的中间状态 | 「SQL查询返回了5条记录」 |
| Info | 业务关键节点 | 「用户登录成功,订单已创建」 |
| Warn | 潜在问题,但不影响运行 | 「缓存未命中,回查数据库」 |
| Error | 异常,功能受影响 | 「数据库连接失败,重试3次后放弃」 |
| Fatal | 系统级崩溃,无法自愈 | 「内存溢出,进程即将终止」 |
我个人习惯:开发环境用Debug级别,测试环境用Info,生产环境用Warn。这样既能看到足够的信息,又不会产生太多噪音。
${environment:ASPNETCORE_ENVIRONMENT},开发环境用Debug,生产环境自动切到Warn。这个后面章节会细讲。
好了,这一章的内容就到这里。你学会了NLog的安装、配置文件的targets和rules结构,还亲手输出了第一条日志。下一章我们聊聊如何把日志写到文件里,以及文件滚动策略——说白了就是怎么防止日志文件无限膨胀。