.NET 日志入门:从内置 ILogger 到第三方框架选型

.NET 日志中文入门指南:Console.WriteLine 为什么不够用、ILogger<T> 与 LoggerFactory 用法、六个日志级别、内置日志提供程序、Serilog/NLog/log4net 三大第三方框架简介与选型,以及观测云 DataKit 采集落地方案。

最佳实践
.NET 日志入门:从内置 ILogger 到第三方框架选型技术指南封面

日志是 .NET 应用全生命周期的重要组成——一套好的日志系统能同时服务开发、运维与客服团队。.NET 自带可扩展的日志抽象(Microsoft.Extensions.Logging),生态中还有 Serilog、NLog、log4net 三大成熟框架。本文梳理内置方案与第三方方案的全貌,帮你搭起 .NET 日志的第一块基石。

核心要点速览

  • Console.WriteLine 不是日志:没有级别、没有时间戳、无法配置输出——只适合写demo。
  • ILogger 是 .NET 的标准日志抽象ASP.NET Core 深度集成,六个级别,提供程序可插拔。
  • 第三方框架补能力短板:结构化字段、丰富输出端(Sink/Target)、细粒度过滤,Serilog/NLog/log4net 三选一。
  • 生产落地:JSON 结构化输出 stdout/文件,观测云 DataKit 采集,监控器告警。

为什么不能只用 Console.WriteLine?

Console.WriteLine("用户登录");  // 问题在哪?

这条"日志":没有级别(无法区分 INFO 和 ERROR)、没有时间戳、没有上下文字段、输出目的地写死、无法集中配置。生产环境需要的是可分级、可过滤、可路由、可解析的日志系统。

内置方案:ILogger 与 LoggerFactory

.NET 的标准日志抽象是 Microsoft.Extensions.Logging 中的 ILogger

using Microsoft.Extensions.Logging;

using var loggerFactory = LoggerFactory.Create(builder =>
{
    builder.AddConsole().SetMinimumLevel(LogLevel.Debug);
});

ILogger logger = loggerFactory.CreateLogger<Program>();

logger.LogTrace("Trace message");
logger.LogDebug("Debug message");
logger.LogInformation("应用启动");
logger.LogWarning("配置缺失,使用默认值");
logger.LogError("数据库连接失败");
logger.LogCritical("系统级故障");

六个级别:Trace(最啰嗦)→ Debug → Information(默认最低级别)→ Warning → Error → Critical(最严重)

ASP.NET Core 中更简单——构造函数注入即可:

public class OrderController : ControllerBase
{
    private readonly ILogger<OrderController> _logger;
    public OrderController(ILogger<OrderController> logger) => _logger = logger;

    public IActionResult Create()
    {
        _logger.LogInformation("创建订单 user={UserId}", userId);  // 结构化参数
        ...
    }
}

注意 {UserId} 消息模板写法:这不是字符串插值——参数会被结构化保存,日志平台可按字段过滤。别用 $"创建订单 user={userId}",那会丢失结构化信息。

内置提供程序(Provider)有 Console、Debug、EventSource、EventLog(Windows)等;builder.AddConsole().AddDebug() 即可多路输出。

三大第三方框架速览

内置日志够简单应用使用,但结构化输出、文件轮转、丰富输出端这些生产能力,第三方框架明显更强:

框架 一句话定位
Serilog 结构化日志的开创者:消息模板、Sink 生态(数百种输出)、JSON 一流支持
NLog 配置灵活的老牌强者:XML/代码配置、自动重载、路由规则强大
log4net Apache log4j 的 .NET 移植:历史悠久,维护存量系统为主

三者都能与 ILogger 抽象集成(作为 Provider),ASP.NET Core 项目迁移成本很低。后续三篇分别深入。

观测云落地:.NET 日志采集与分析

无论内置 ILogger 还是第三方框架,平台接入路径一致:

  1. 应用侧:输出 JSON 结构化日志到 stdout(容器)或文件(主机)。Serilog 用 JSON formatter,NLog 用 JsonLayout。
  2. DataKit 采集:容器 stdout 自动采集;主机在 conf.d/log/logging.conf 配置文件采集,source 设为 dotnet-appservice 标识服务。JSON 自动解析为字段。
  3. Pipeline 标准化:级别字段映射标准 status(Error/Critical/Fatal → error),时间戳解析为 time
  4. 检索告警:日志查看器按 status/service 过滤与聚类;监控器对 error 日志设阈值,告警策略绑定钉钉/企业微信/飞书通知对象。
  5. 链路关联:接入观测云 APM(.NET 探针)后 trace_id 注入日志,错误日志一键跳转调用链。
  6. 成本控制:多索引按级别拆保留策略,历史数据转发归档对象存储。

常见问题(FAQ)

控制台应用和 ASP.NET Core 的日志配置差别大吗?

抽象一致(都是 ILogger),差别在装配:ASP.NET Core 由宿主自动配置并提供注入;控制台应用需自己 LoggerFactory.Create 或装 Microsoft.Extensions.Hosting 获得同样的宿主体验。

LogLevel 设多少合适?

生产 Information 起步,排障临时调 Debug。Trace 只用于深度调试,常态开启会淹没日志并拖累性能。

ILogger 的消息模板为什么不要用字符串插值?

LogInformation("user={id}", id) 会把 id 存为结构化字段,平台可按 user 过滤聚合;$"user={id}" 只是拼字符串,字段信息丢失,还可能在级别不够时白做拼接。

新项目内置日志和 Serilog 怎么选?

简单服务用内置 ILogger + Console/JSON 提供程序就够;需要文件轮转、丰富输出端、复杂过滤时上 Serilog——它也能作为 ILogger 的 Provider,切换平滑。

系列阅读


获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台