ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

C# | Serilog 新手入门

C# | Serilog 新手入门

C# Serilog 新手入门

文章目录

  • C# Serilog 新手入门
    • 1. 什么是第三方日志库与 Serilog
      • 1.1 概念讲解:什么是日志?为什么不能只写 `Console.WriteLine`?
      • 1.2 C# 生态中的优秀日志库对比
      • 1.3 C# 日志技术的演进历程
    • 2. Serilog 结构化日志与传统日志的对比
      • 2.1 结构化日志(Structured Logging)的核心特点
        • 传统日志代码与产出
        • Serilog 结构化日志代码与产出
      • 2.2 Serilog 在代码与日志查询上的优势
      • 2.3 帮助小白快速理解的心智模型
    • 3. 引入 Serilog 的意义与架构定位
      • 3.1 实际应用场景与效率提升
      • 3.2 软件架构中的定位
    • 4. Serilog 动手实战
      • 4.1 第一行代码:5 分钟跑通 Hello World
        • 第一步:安装 NuGet 包
        • 第二步:编写极简控制台程序
      • 4.2 语法与配置详解
        • 4.2.1 结构化日志语法格式与核心组件
        • 4.2.2 两种配置方式:Fluent API 代码配置 vs `appsettings.json` 声明式配置
          • 方式一:Fluent API(代码链式调用,适合小型项目或控制台应用)
          • 方式二:`appsettings.json`(推荐!适合 ASP.NET Core 项目,灵活可配置)
    • 5. 总结

针对刚接触 C# 开发、从未独立使用过第三方日志库的新手,很多关于 Serilog 的官方文档过于偏向 API 说明,容易让人“知其然不知其所以然”。

本教程参考了模块化的递进架构,用通俗直白的语言带你彻底搞懂Serilog到底强在哪?以及如何在真实系统中合理定位它。


1. 什么是第三方日志库与 Serilog

1.1 概念讲解:什么是日志?为什么不能只写Console.WriteLine

在刚学 C# 时,很多人习惯用Console.WriteLine("用户登录成功")来查看程序运行状态。但在真实的企业级项目(如 Web API、后台服务)中,这种做法存在巨大隐患:

  • 数据随用随丢:程序重启或控制台窗口一关,输出的信息全部消失。
  • 没有级别区分:无法区分普通提示(Information)、警告(Warning)还是系统崩溃(Fatal)。
  • 阻塞性能:直接向控制台频繁写数据是同步且昂贵的 I/O 操作,会导致高并发下程序卡死。
  • 缺乏上下文:只写一句“报错了”,你不知道是谁在什么时间、哪条线程、哪个请求上报的错。

第三方日志库就是为此而生的专业管家。它能够异步、高性能地将程序运行过程中的重要状态记录下来,并自动附带时间戳、线程号、日志级别,最终将日志输出到文件、数据库或远程日志中心进行长期保存。

1.2 C# 生态中的优秀日志库对比

C# 生态发展至今,出现了几款经典的第三方日志库:

日志库历史与特点适用场景
Log4net移植自 Java 的 Log4j,历史最悠久,古老且稳定。老旧项目的维护。由于配置繁琐(大量 XML)、缺少现代化特性,新项目不推荐。
NLog性能优异,配置灵活,在 C# 生态中流行多年。各种中大型传统项目,功能非常强大。
Serilog现代化日志库首选,天然为“结构化日志”而生,社区最活跃。全新项目的首选,特别是结合 Seq、ELK 等现代日志分析平台的项目。

1.3 C# 日志技术的演进历程

C# 日志技术经历了四个主要阶段:

  1. 原始时代:直接使用Console.WriteLine()System.Diagnostics.Trace,功能极其原始。
  2. 文本日志时代(Log4net / NLog 早期):开始将日志格式化写入文本文件(如.log文件),但日志内容全是一串串拼接的字符串。
  3. 接口抽象时代(Microsoft.Extensions.Logging):微软推出了官方日志抽象接口ILogger,框架只定义标准,具体实现交由第三方库(如 Serilog)完成。
  4. 结构化日志时代(Serilog 领衔):不再把日志当作“一句话”,而是当作“带属性的 JSON 数据对象”,掀起了现代化运维与排查的变革。

2. Serilog 结构化日志与传统日志的对比

2.1 结构化日志(Structured Logging)的核心特点

传统日志输出的是非结构化纯文本,而 Serilog 输出的是结构化键值数据

传统日志代码与产出
// 传统拼接字符串logger.Info("用户 "+userId+" 在 "+DateTime.Now+" 购买了商品 "+productId);// 产出文本: 用户 10086 在 2026-08-09 10:00:00 购买了商品 9988

当你在数 GB 的日志文件中想要检索“用户 10086 买了哪些商品”时,只能用复杂的正则表达式或全文逐字匹配,非常缓慢且容易误判。

Serilog 结构化日志代码与产出
// Serilog 消息模板(注意变量名前的名称)logger.Information("用户 {UserId} 购买了商品 {ProductId}",userId,productId);

Serilog 在后台不仅会生成人眼可读的文本,还会同时保留数据的原始结构:

{"Timestamp":"2026-08-09T10:00:00Z","Level":"Information","MessageTemplate":"用户 {UserId} 购买了商品 {ProductId}","Properties":{"UserId":10086,"ProductId":9988}}

2.2 Serilog 在代码与日志查询上的优势

  • 像查 SQL 数据库一样查日志:因为属性被单独提取保存了,在 Seq 或 Elasticsearch 等日志系统中,你可以直接输入Properties.UserId == 10086Properties.ProductId > 1000实施精确过滤。
  • 复杂对象的原生拆解:如果你传入一个 C# 对象,在变量名前加上@符号(如{@User}),Serilog 会自动将其序列化为 JSON 展开存储,无需手动JsonConvert.SerializeObject

2.3 帮助小白快速理解的心智模型

  • 传统日志的心智模型:把日志当成记事本,疯狂向里面追加一行行打印出来的文本。
  • Serilog 的心智模型:把打日志当成向一个无模式(NoSQL)数据库插入事件记录。你每一次记录日志,都是在发起一次数据结构收集。

3. 引入 Serilog 的意义与架构定位

3.1 实际应用场景与效率提升

  1. 生产环境快速排错:系统报错时,无需猜测参数,结构化日志直接呈现当时请求入参的完整 JSON 数据。
  2. 性能瓶颈追踪:通过在日志中附带ElapsedMilliseconds,可以秒级筛选出“执行时间大于 2000ms”的所有数据库查询日志。
  3. 安全审计与业务分析:记录关键业务事件(如支付、修改密码),方便日后查账或统计用户行为轨迹。

3.2 软件架构中的定位

在遵循领域驱动设计(DDD)或分层架构的系统里,日志属于典型的横切关注点(Cross-Cutting Concerns)

  • 配置与初始化:位于系统的最外层(基础设施层/启动入口)。
  • 业务层使用:业务层(应用层、领域层)不直接依赖 Serilog,而是通过依赖注入使用微软官方抽象的ILogger<T>接口记录日志。这样可以实现业务逻辑与具体日志实现框架的解耦。

下面的架构图展示了 Serilog 在 DDD 系统中的位置与数据流向:

外部日志接收终端

Cross-Cutting Concerns

Infrastructure Layer

Domain Layer

Application Layer

Presentation Layer

调用

调用

数据持久化

提供实现并注册

依赖注入

依赖注入

依赖注入

异步刷盘/推送

网络发送 JSON

OrdersController

OrderAppService

OrderDomainService

Database Context

Serilog 配置与全局初始化

Microsoft.Extensions.Logging.ILogger

本地磁盘文件

Seq 日志服务器 / ELK

InfraLayer


4. Serilog 动手实战

4.1 第一行代码:5 分钟跑通 Hello World

第一步:安装 NuGet 包

打开 Visual Studio 的 NuGet 包管理器,安装以下三个包:

  • Serilog(核心库)
  • Serilog.Sinks.Console(输出到控制台插件)
  • Serilog.Sinks.File(输出到文件插件)
第二步:编写极简控制台程序
usingSerilog;classProgram{staticvoidMain(){// 1. 初始化 Serilog 配置Log.Logger=newLoggerConfiguration().MinimumLevel.Debug()// 设置最低日志记录级别.WriteTo.Console()// 输出到控制台.WriteTo.File("logs/myapp.txt",rollingInterval:RollingInterval.Day)// 按天生成日志文件.CreateLogger();// 2. 打出第一行日志Log.Information("Hello, Serilog! 欢迎来到结构化日志的世界。");// 3. 带有变量的结构化日志stringuserName="张三";intage=18;Log.Information("创建用户:姓名={UserName}, 年龄={Age}",userName,age);// 4. 确保程序退出前把内存中的日志刷入磁盘Log.CloseAndFlush();}}

4.2 语法与配置详解

4.2.1 结构化日志语法格式与核心组件

Serilog 由三个核心概念组成:

  1. Sinks(输出接收端):日志去哪里?(控制台、文件、数据库、Seq、Elasticsearch)。
  2. Enrichers(上下文增强器):自动补全环境信息(如:当前线程 ID、机器名、环境名)。
  3. Message Template(消息模板):定义变量提取规则。

关键语法技巧:@$占位符

varuser=new{Id=1001,Name="李四",Role="Admin"};// 1. 默认处理:Serilog 会调用 user.ToString(),通常输出类名Log.Information("用户信息:{User}",user);// 2. 加上 @ 符号(Destructuring 解构):把对象展开为 JSON 存储Log.Information("用户信息:{@User}",user);// 3. 加上 $ 符号:强制转换为字符串(即使是复杂对象)Log.Information("用户信息:{$User}",user);
4.2.2 两种配置方式:Fluent API 代码配置 vsappsettings.json声明式配置
方式一:Fluent API(代码链式调用,适合小型项目或控制台应用)
Log.Logger=newLoggerConfiguration().MinimumLevel.Information().Enrich.WithThreadId()// 需要安装 Serilog.Enrichers.Thread 包.WriteTo.Console(outputTemplate:"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} (Thread:{ThreadId}){NewLine}{Exception}").CreateLogger();
方式二:appsettings.json(推荐!适合 ASP.NET Core 项目,灵活可配置)

需要安装包:Serilog.Settings.ConfigurationSerilog.AspNetCore

1. 修改appsettings.json文件:

{"Serilog":{"MinimumLevel":{"Default":"Information","Override":{"Microsoft":"Warning","System":"Warning"}},"WriteTo":[{"Name":"Console"},{"Name":"File","Args":{"path":"logs/log-.txt","rollingInterval":"Day","retainedFileCountLimit":30}}],"Enrich":["FromLogContext","WithMachineName","WithThreadId"]}}

2. 在 ASP.NET CoreProgram.cs中挂载:

varbuilder=WebApplication.CreateBuilder(args);// 声明让 ASP.NET Core 读取配置文件并使用 Serilog 接管官方日志系统builder.Host.UseSerilog((context,services,configuration)=>configuration.ReadFrom.Configuration(context.Configuration).ReadFrom.Services(services));varapp=builder.Build();// 在 Controller 中即可通过标准 ILogger<T> 注入直接使用 Serilog 的强大功能

5. 总结

学习 Serilog 不仅仅是学会安装一个 NuGet 包,更是从传统文本运维现代化数据驱动运维转变的关键一步。

  • 抛弃旧观念:不要再使用Console.WriteLine或简单的字符串拼接写日志。
  • 掌握核心价值:Serilog 的灵魂在于结构化,把日志当作带属性的事件数据保存。
  • 架构规范:业务代码中依赖微软抽象的ILogger,通过依赖注入在基础设施层配置 Serilog,实现优雅的架构解耦。
返回列表