C# Serilog配置方法 C#如何集成Serilog进行结构化日志记录

来源:这里教程网 时间:2026-02-21 17:39:25 作者:

如何在.NET项目中正确安装并初始化Serilog

直接用

NuGet
安装两个核心包就够了:
Serilog
和对应输出目标的扩展,比如控制台用
Serilog.Sinks.Console
,文件用
Serilog.Sinks.File
。别装
Serilog.AspNetCore
除非你用的是 ASP.NET Core —— 普通 .NET Framework 或 .NET 6+ 控制台项目不需要它。

初始化必须在

Main
方法最开头做,早于任何日志调用:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

漏掉这句或放错位置,后续所有

Log.Information(...)
都会静默失败(不是报错,是根本没输出)。

Serilog.WriteTo.Console() 输出中文乱码怎么办

默认控制台编码是 ANSI,Windows 上常见 GBK 环境下中文变问号。这不是 Serilog 的问题,是

Console
自身限制。

解决方式只有两种:

启动程序前执行
chcp 65001
切换到 UTF-8(临时有效)
在代码里加一句
Console.OutputEncoding = Encoding.UTF8;
,且必须放在
Log.Logger = ...
之前

注意:.NET Core 3.0+ 默认支持 UTF-8 控制台,但若项目降级兼容旧框架,仍需手动设置。

结构化日志怎么写才真正“结构化”

关键不是用

Log.Information
,而是用占位符传参,而不是字符串拼接:

// ✅ 正确:生成带 property 的结构化事件
Log.Information("User {UserId} logged in from {IpAddress}", userId, ip);
// ❌ 错误:只是普通字符串,无字段可查
Log.Information($"User {userId} logged in from {ip}");

这样写之后,日志目标(如 Seq、Elasticsearch)才能把

UserId
IpAddress
当成独立字段过滤或聚合。如果值是对象,Serilog 会自动序列化其公共属性——但别传
this
或大集合,容易拖慢性能或泄露敏感数据。

ASP.NET Core 中如何替换默认 ILogger 并注入上下文信息

Program.cs
(.NET 6+)或
Startup.ConfigureServices
(.NET 5 及以前)里,用
UseSerilog()
替换掉 Microsoft 的日志系统:

var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSerilog((ctx, lc) => lc
    .WriteTo.Console()
    .ReadFrom.Configuration(ctx.Configuration));

然后用

ILogger<t></t>
注入即可,和原来完全兼容。想自动带上请求 ID、路径等?加
.Enrich.FromLogContext()
,并在中间件里用
LogContext.PushProperty

app.Use(async (ctx, next) =>
{
    LogContext.PushProperty("Path", ctx.Request.Path);
    await next();
});

不加

Enrich.FromLogContext()
PushProperty
就无效;不配中间件,Web 请求日志就缺上下文——这两步缺一不可。

结构化日志真正的门槛不在配置,而在写日志时是否习惯用命名参数、是否理解

LogContext
的作用域边界、以及是否意识到日志输出目标对字段解析能力的依赖。

相关推荐