部署运行你感兴趣的模型镜像一键部署
〇、前言
相较于 log4net,Serilog 则是新项目的首选,现代化、高性能、易用,是 .NET 日志的未来方向。如需了解 log4net 详见往期博文:https://www.cnblogs.com/hnzhengfy/p/19121607/log4net。
log4net 虽然是一个广泛使用的、功能强大的日志记录库,而且专为 .NET 平台设计,但由于她是较老的日志框架,其生态在 .NET Core/.NET 5+ 环境中支持有限,因此还是要慎重考虑。
方面 log4net Serilog
日志模型 文本日志:日志是纯字符串,信息混在一起。
例如:“用户 alice 从 192.168.1.1 登录” 结构化日志:日志是带属性的数据事件。
例如:“用户 {UserName} 从 {IP} 登录”,UserName=“alice”, IP=“192.168.1.1”
配置方式 主要靠 XML 文件,复杂且不易读。 支持代码和 appsettings.json,更现代、简洁。
API 使用 需为每个类创建 logger 实例,较繁琐。 提供静态 Log 类,一行代码即可记录,更简单。
生态系统 老牌库,Appenders 丰富但更新慢。 Sinks 生态活跃,原生支持 Elasticsearch、Seq、云平台等。
.NET 集成 在 ASP.NET Core 中集成较麻烦。 与 ASP.NET Core 深度集成,自动记录请求上下文。
维护状态 活跃维护,持续更新,最新版 3.2.0(20250823)。 活跃维护,持续更新,支持最新 .NET 版本。
经过对比,当然还是 Serilog 更有优势,那么本文将就概念方面来详细介绍下,后续会继续更新相关用法实践,有兴趣可持续关注。
回到顶部
一、Serilog 简介
Serilog 是一个为 .NET 应用程序设计的强大的诊断日志库,以易于设置、简洁的 API 和跨所有最新 .NET 平台的兼容性而著称。
它是 .NET 平台中非常流行且强大的结构化日志库,其最大特点是结构化日志记录(Structured Logging)。
1.1 核心特点:结构化日志记录(Structured Logging)
日志不是简单的字符串,而是包含命名属性的结构化事件。
// 例如记录用户登录事件
string username = “bob”;
string clientIp = “10.0.0.5”;
int userId = 789;
Log.Information(“用户 {UserName} (ID: {UserId}) 从 {ClientIP} 登录”,
username, userId, clientIp);
// 生成的结构化数据(以 JSON 形式表示):
{
“Timestamp”: “2025-03-28T14:30:00Z”,
“Level”: “Information”,
“MessageTemplate”: “用户 {UserName} (ID: {UserId}) 从 {ClientIP} 登录”,
“RenderedMessage”: “用户 bob (ID: 789) 从 10.0.0.5 登录”,
“Properties”: {
“UserName”: “bob”,
“UserId”: 789,
“ClientIP”: “10.0.0.5”
}
}
// 可以直接在 Seq 或 Elasticsearch 中搜索,例如:UserName = ‘bob’
这样便于和另外的日志接收系统对接,针对日志量较大的场景比较友好。
1.2 核心特点:强大的 Sink 生态系统
Serilog 通过 Sinks(接收器)将日志事件发送到各种目的地。这种“即插即用”的架构是 Serilog 强大和流行的关键。
官方 Sinks:Serilog.Sinks.Console(控制台)、Serilog.Sinks.File(文件)、Serilog.Sinks.Seq(Seq 服务器)、Serilog.Sinks.Elasticsearch(Elasticsearch)等。
第三方 Sinks:支持 Splunk、DataDog、Graylog、Kafka、RabbitMQ、AWS CloudWatch 等
优势:可以同时配置多个 Sinks,将同一日志事件发送到不同地方。
工作原理:
日志事件生成:业务端代码调用 Log.Information(“…”),Serilog 创建一个 LogEvent 对象。
事件处理:该事件可能经过过滤、丰富(Enrichment)等处理。
分发到 Sinks:Serilog 核心引擎将处理后的 LogEvent 分发给所有配置的 Sinks。
Sink 执行写入:每个 Sink 根据自己的逻辑,将 LogEvent 转换为适合目标系统的格式(如 JSON、文本行),并通过相应协议(如 HTTP、文件 I/O)发送出去。
1.3 核心特点:简洁易用的 API
使用静态 Log 类,无需依赖注入即可在任何地方记录日志。
它极大地简化了日志记录的开发体验,让开发者能够以最少的代码、最直观的方式完成强大的日志功能。
// Serilog:全局静态 Log 类,任何地方直接调用
Log.[Level](string messageTemplate, params object[] propertyValues); // 格式
Log.Verbose(“调试信息: {Detail}”, detail); // 示例
Log.Debug(“进入方法: {MethodName}”, “ProcessOrder”);
Log.Information(“订单 {OrderId} 已创建”, orderId);
Log.Warning(“库存不足,商品 {ProductId}”, productId);
Log.Error(exception, “处理支付失败,用户 {UserId}”, userId);
Log.Fatal(“应用程序即将退出”);
// 对比传统日志库 log4net 的方式:
// 每个类都需要声明一个 logger 实例,代码重复,不够优雅
private static readonly ILog log = LogManager.GetLogger(typeof(MyClass));
public void DoSomething()
{
log.Info(“用户登录”);
}
支持所有标准日志级别:Verbose,Debug,Information,Warning,Error,Fatal。
使用 {PropertyName} 占位符,清晰表达意图。
自动提取属性值,生成结构化数据。
支持格式化说明符,如 {LoginTime:HH:mm}。
即使没有提供参数,也不会抛出异常(会原样输出占位符)。
// 异常处理的优雅支持
// 记录异常是常见需求,Serilog 提供了专门的重载,让异常日志既简洁又完整
try
{
// …
}
catch (Exception ex)
{
Log.Error(ex, “处理订单 {OrderId} 失败”, orderId);
}
// 第一个参数是 Exception 对象,Serilog 会自动捕获堆栈跟踪。
// 后续参数用于填充消息模板中的属性。
// 生成的日志事件同时包含异常详情和业务上下文。
特性 如何体现“简洁易用”
静态 Log 类 全局可用,无需实例化,减少样板代码
统一方法签名 所有日志级别使用相同模式,降低记忆负担
消息模板 结构化日志 + 直观语法,代码可读性强
异常支持 一行代码
1810



被折叠的 条评论
为什么被折叠?



