第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本体,结果发现依赖注入用不了,折腾了半天。

小提示: 安装完成后,检查一下项目文件(.csproj),确认引用了这两个包。版本号建议选最新的稳定版,别追预览版。

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 写入数据库 集中式日志存储
Mail 发送邮件 错误告警

layout 属性定义了日志的格式。我常用的占位符有这些:

  • ${longdate} — 完整日期时间,比如 2025-01-15 14:30:22.1234
  • ${level} — 日志级别(Info、Error等)
  • ${logger} — 记录器名称,通常是类名
  • ${message} — 日志消息正文
  • ${exception} — 异常信息
  • ${callsite} — 调用位置(文件名、行号)
重点: File类型的 fileName 支持动态路径。我用 ${basedir} 表示应用程序根目录,${shortdate} 按日期自动分文件。这样每天一个日志文件,不会撑爆磁盘。

rules节点

规则决定了日志的流向。每个rule包含:

  • name — 匹配的记录器名称,支持通配符 *
  • minlevel — 最低日志级别,低于这个级别的忽略
  • maxlevel — 最高日志级别(可选)
  • writeTo — 写入哪个target
  • final — 如果匹配,是否停止后续规则

规则是从上到下依次匹配的。我曾经踩过一个坑:把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的都被过滤掉了。

避坑指南: 我曾经在生产环境忘记把日志级别从Debug改成Warn,结果一天生成了几个G的日志文件,直接把磁盘撑爆了。生产环境建议至少设置为Warn级别。

再看文件输出。去项目目录下的 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。这样既能看到足够的信息,又不会产生太多噪音。

小技巧: 你可以在NLog.config里通过环境变量动态切换级别。比如 ${environment:ASPNETCORE_ENVIRONMENT},开发环境用Debug,生产环境自动切到Warn。这个后面章节会细讲。

好了,这一章的内容就到这里。你学会了NLog的安装、配置文件的targets和rules结构,还亲手输出了第一条日志。下一章我们聊聊如何把日志写到文件里,以及文件滚动策略——说白了就是怎么防止日志文件无限膨胀。