.NET 日志入门:从内置 ILogger 到第三方框架选型
.NET 日志中文入门指南:Console.WriteLine 为什么不够用、ILogger<T> 与 LoggerFactory 用法、六个日志级别、内置日志提供程序、Serilog/NLog/log4net 三大第三方框架简介与选型,以及观测云 DataKit 采集落地方案。
日志是 .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 还是第三方框架,平台接入路径一致:
- 应用侧:输出 JSON 结构化日志到 stdout(容器)或文件(主机)。Serilog 用 JSON formatter,NLog 用 JsonLayout。
- DataKit 采集:容器 stdout 自动采集;主机在
conf.d/log/logging.conf配置文件采集,source设为dotnet-app、service标识服务。JSON 自动解析为字段。 - Pipeline 标准化:级别字段映射标准
status(Error/Critical/Fatal →error),时间戳解析为time。 - 检索告警:日志查看器按 status/service 过滤与聚类;监控器对 error 日志设阈值,告警策略绑定钉钉/企业微信/飞书通知对象。
- 链路关联:接入观测云 APM(.NET 探针)后 trace_id 注入日志,错误日志一键跳转调用链。
- 成本控制:多索引按级别拆保留策略,历史数据转发归档对象存储。
常见问题(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,切换平滑。
系列阅读
- 上一篇:Semantic Logger 实战指南
- 下一篇:Serilog 实战指南
- 相关阅读:NLog 实战 | 日志级别详解