.NET 日志库怎么选:ILogger、Serilog、NLog、log4net 横向对比
.NET 日志方案选型中文指南:内置 ILogger(Microsoft.Extensions.Logging)、Serilog、NLog、log4net 四大方案的结构化能力、配置方式、性能与维护状态对比,附选型决策建议与观测云平台接入方案。
.NET 日志生态的四个主流选择——内置 ILogger 抽象、Serilog、NLog、log4net——各有清晰的适用边界。本文做一次系统的横向对比,帮你在新项目选型与老系统演进时做出不纠结的决策。
业务代码调用什么接口,与日志最终怎样输出,是两个决定。ILogger 提供抽象和基础 Provider;简单服务可以直接使用 JSON Console。Serilog 的消息模板、解构和 Sink,或 NLog 的 Target 与路由规则,解决的是更具体的输出需求。log4net 仍在维护,已有系统可以按所需布局和扩展继续演进。
四大方案对比表
| 维度 | ILogger(内置) | Serilog | NLog | log4net |
|---|---|---|---|---|
| 定位 | 日志抽象 + 基础 Provider | 结构化日志框架 | 全能日志框架 | 老牌日志框架 |
| 结构化字段 | 消息模板支持 | 一流(消息模板 + 解构) | 支持(属性 + JsonLayout) | 事件与上下文属性,按布局输出 |
| JSON 输出 | 内置 Console 的 JSON Formatter | 原生 Formatter | JsonLayout | 需第三方扩展 |
| 输出目的地 | 少量官方 Provider | 官方与社区 Sink | 丰富 Target | 丰富 Appender |
| 文件轮转 | 内置通用 Provider 不提供滚动文件输出 | File Sink 提供滚动文件输出 | 内建(archive 配置) | 内建(RollingFileAppender) |
| 配置方式 | 代码/配置 | 代码/appsettings | XML/代码,热重载 | XML/代码 |
| 维护状态 | 按 .NET 支持周期核对 | 核对核心与 Sink 版本 | 核对核心与 Target 版本 | 仍有维护发布,核对 Apache 版本 |
| 选用侧重点 | 简单 JSON Console 输出 | 模板、解构与 Sink | Target、路由及配置 | 现有集成与扩展维护 |
逐款点评
1. ILogger(Microsoft.Extensions.Logging)
.NET 官方日志抽象:六个级别、消息模板、Provider 可插拔,ASP.NET Core 深度集成。简单 Web 服务用内置 Console(JSON 模式)Provider 就能满足生产需求。它的真正价值是"面向抽象编程":业务代码只依赖 ILogger,底层换成 Serilog/NLog 通常可保留调用点,但还需核对依赖、过滤、上下文与输出字段,不能只改启动注册就保证行为一致。
2. Serilog:消息模板与结构化属性
消息模板 {UserId} 保存命名属性,@ 可以解构对象。Sink 决定输出目的地,Formatter 决定序列化格式;ASP.NET Core 可通过相应集成包接入,例如 UseSerilog。LogContext 需配置 .Enrich.FromLogContext() 后才能把作用域属性加入事件,包和 Sink 也要匹配应用运行时。
3. NLog:Target 与路由规则
targets/rules 两段式 XML 配置可以按 logger 名和级别分流、过滤事件,并为不同目标选择格式。autoReload 支持配置重载,JsonLayout 用于 JSON 输出。与 Serilog 的取舍可以从路由、事件 API、目标集成和团队已有配置出发。
4. log4net:延续现有 Logger/Appender/Layout
log4j 移植,概念(Logger/Appender/Layout)影响了一代 .NET 工程师。仍有维护发布,常用 API 的消息模板语义与 Serilog 不同;支持事件属性和结构化 XML,JSON 可用外部布局扩展。存量系统可继续维护,新项目按具体需求评估。
选型决策建议
- 新项目默认:ILogger 抽象 + Serilog Provider(
UseSerilog),兼得标准抽象与结构化输出; - 偏好 XML 声明式配置/复杂路由:NLog;
- 极简微服务:内置 ILogger + Console Provider 的 JSON Formatter;
- log4net 存量:维护为主,新代码面向 ILogger 编程,逐步收敛。
确认输出格式与采集规则
选定框架后,先检查实际输出的一条日志:时间戳、级别、异常和请求标识分别位于哪个字段。不同 Formatter 或 Layout 的 JSON 结构可能不同,迁移日志库时应同时检查解析规则。
接入观测云时,按 DataKit 日志采集指南选择文件或容器日志来源,再通过 Pipeline 将源字段映射为 time、status 等字段。要从链路查日志,还需在应用日志中注入请求的 trace_id,并按关联日志说明核对服务标识。
常见问题(FAQ)
ILogger 会不会取代 Serilog/NLog?
ILogger 是可组合的日志抽象,可通过 Provider 接入 Serilog 或 NLog。如果内置 Provider 已满足输出与过滤需求,也不必额外引入框架;是否组合应按目标、字段格式和运维要求判断。
Serilog 和 NLog 性能差多少?
不能脱离工作负载给出固定差异。两者都有异步方案(Async Sink / AsyncWrapper),需测试格式化、目标 I/O、队列满和退出行为;API 偏好与团队经验也应纳入选型。
可以同时用两个框架吗?
技术上可以(比如过渡期),但要统一输出格式与目的地,否则平台侧解析规则翻倍。过渡期建议尽早收敛到一个框架。
.NET Framework 老项目呢?
需逐一核对 log4net、NLog、Serilog 及各 Provider/Sink 的具体版本和目标框架;历史版本支持 4.6.1 不代表当前所有包均支持。集中采集前先检查旧项目的日志编码、多行堆栈和轮转后的路径。
系列阅读
- 上一篇:log4net 实战指南
- 下一篇:Java 日志最佳实践十条
- 相关阅读:Serilog 实战 | NLog 实战 | 如何选择日志框架