百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

C#.NET serilog 详解(c# repository)

ztj100 2025-07-24 23:24 5 浏览 0 评论

简介

Serilog.NET 平台中非常流行且强大的结构化日志库,其最大特点是“结构化日志记录(Structured Logging)”,支持通过键值对记录丰富的上下文信息,并且拥有强大的 Sink 插件系统,支持写入控制台、文件、数据库、Elasticsearch、Seq 等。

Serilog 核心概念

概念

说明

Logger

日志记录器实例

Sink

日志的输出目标,如 Console、File、Elasticsearch 等

Enrichment

日志信息的丰富,比如自动记录线程ID、机器名等上下文信息

Filter

日志的筛选器

Structured Logging

日志以键值对形式记录,便于搜索和分析

安装 Serilog(NuGet 包)

dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.File
dotnet add package Serilog.Sinks.Async

基础配置示例

using Serilog;

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File("Logs/log.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

try
{
    Log.Information("Starting up");
    // 启动主程序或 ASP.NET Core 应用
}
catch (Exception ex)
{
    Log.Fatal(ex, "Application start-up failed");
}
finally
{
    Log.CloseAndFlush();
}

ASP.NET Core 集成方式

using Serilog;

var builder = WebApplication.CreateBuilder(args);

// 配置 Serilog 替换默认日志
Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File("Logs/log-.txt", rollingInterval: RollingInterval.Day)
    .CreateLogger();

builder.Host.UseSerilog(); // 使用 Serilog

builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();

appsettings.json 配置方式

"Serilog": {
  "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
  "MinimumLevel": {
    "Default": "Information",
    "Override": {
      "Microsoft": "Warning",
      "System": "Warning"
    }
  },
  "Enrich": [ "FromLogContext", "WithThreadId" ],
  "WriteTo": [
    {
      "Name": "Console"
    },
    {
      "Name": "File",
      "Args": {
        "path": "Logs/log-.txt",
        "rollingInterval": "Day",
        "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
      }
    }
  ]
}

配合 NuGet 包:

dotnet add package Serilog.Settings.Configuration

Serilog Sink 示例

Sink 名称

说明

Serilog.Sinks.Console

输出到控制台

Serilog.Sinks.File

输出到文件

Serilog.Sinks.Seq

输出到 Seq 可视化平台

Serilog.Sinks.Elasticsearch

输出到 Elasticsearch

Serilog.Sinks.Async

异步包装器

Serilog.Sinks.MSSqlServer

写入 SQL Server

基本用法

基本结构化日志

var orderId = 123;
var customerId = 456;

// 结构化日志记录
Log.Information("处理订单 {OrderId} 来自客户 {CustomerId}", orderId, customerId);

// 输出示例(JSON 格式):
// {
//   "OrderId": 123,
//   "CustomerId": 456,
//   "Message": "处理订单 123 来自客户 456",
//   "Level": "Information"
// }

复杂对象序列化

var order = new Order { Id = 123, Products = new List<string> { "Book", "Pen" } };
Log.Information("创建订单 {@Order}", order);
// 输出: 创建订单 {"Id": 123, "Products": ["Book", "Pen"]}

上下文丰富(Enrichers)

// 为当前作用域添加属性
using (LogContext.PushProperty("RequestId", Guid.NewGuid()))
{
    Log.Information("处理请求");
    // 所有日志自动附加 RequestId 属性
}
// 添加全局属性
Log.Logger = new LoggerConfiguration()
    .Enrich.WithMachineName()
    .Enrich.WithEnvironmentUserName()
    .CreateLogger();

// 添加临时上下文
using (LogContext.PushProperty("RequestId", Guid.NewGuid())) {
    Log.Information("处理请求");
}

常用 Enrichers

.Enrich.WithProperty("AppVersion", "1.0.0")
.Enrich.FromLogContext()
.Enrich.WithThreadId()

文件滚动

按日期或大小滚动日志文件:

.WriteTo.File("logs/app-.log",
    rollingInterval: RollingInterval.Day,
    fileSizeLimitBytes: 10_000_000,
    retainedFileCountLimit: 30)
  • rollingInterval:按天滚动。
  • fileSizeLimitBytes:限制文件大小(10MB)。
  • retainedFileCountLimit:保留 30 个文件。

数据库 Sink

dotnet add package Serilog.Sinks.MSSqlServer
.WriteTo.MSSqlServer(
    connectionString: "Server=.;Database=Logs;Trusted_Connection=True;",
    sinkOptions: new MSSqlServerSinkOptions { TableName = "Logs" })

过滤日志

通过过滤器控制日志:

.Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("SensitiveData"))

JSON 配置

"Filter": [
  {
    "Name": "ByExcluding",
    "Args": {
      "expression": "SourceContext = 'Microsoft.*'"
    }
  }
]

配置 HTTP 上下文:

高级用法

动态日志级别

var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Information);

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.ControlledBy(levelSwitch)
    .WriteTo.Console()
    .CreateLogger();

// 运行时调整级别
levelSwitch.MinimumLevel = LogEventLevel.Debug;

自定义输出模板

.WriteTo.Console(outputTemplate:
    "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {Properties}{NewLine}{Exception}")

错误日志特殊处理

.WriteTo.Logger(lc => lc
    .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Error)
    .WriteTo.File("logs/errors.txt"))

请求日志中间件

app.UseSerilogRequestLogging(options => 
{
    options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
    {
        diagnosticContext.Set("User", httpContext.User.Identity.Name);
        diagnosticContext.Set("ClientIP", httpContext.Connection.RemoteIpAddress);
    };
});

异步日志

.WriteTo.Async(a => a.File("logs/async.log"))

批量写入

// 使用 PeriodicBatchingSink 实现批处理
Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.PeriodicBatchingSink(
        new HttpSink("https://logserver/api/logs"),
        batchSizeLimit: 100,
        period: TimeSpan.FromSeconds(2))
    .CreateLogger();

使用配置文件初始化

using Serilog;
using Serilog.Settings.Configuration;

var configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .Build();

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration)
    .CreateLogger();

条件性日志记录

Log.Logger = new LoggerConfiguration()
    .WriteTo.Logger(lc => lc
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Error)
        .WriteTo.File("logs/errors.log"))
    .WriteTo.Logger(lc => lc
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Information)
        .WriteTo.Console())
    .CreateLogger();

级别动态控制

.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)  // 抑制第三方库日志

轻量级序列化

.WriteTo.File(new CompactJsonFormatter(), "logs/compact.json")  // 节省存储

异步批处理配置

.WriteTo.Async(a => a.Elasticsearch(), batchSize: 1000)

参数调优:

  • batchSize:根据网络延迟调整(建议 500-5000)
  • blockWhenFull:队列满时阻塞而非丢弃

零分配渲染(ZeroAllocation)

var log = new LoggerConfiguration()
    .Destructure.ByTransforming<User>(u => new { u.Id, u.Name })
    .CreateLogger();

// 避免 ToString() 分配
Log.Information("用户 {@User} 登录", user); 

自定义 Sink 开发

public class CustomSink : ILogEventSink {
    public void Emit(LogEvent logEvent) {
        var json = JsonConvert.SerializeObject(logEvent.Properties);
        SendToQueue(queue, json); // 写入消息队列
    }
}
// 注册
.WriteTo.Sink(new CustomSink())

故障转移机制

.WriteTo.Conditional(
    e => IsElasticAlive(), 
    wt => wt.Elasticsearch(), 
    wt => wt.File("fallback.log")
)

过滤日志

通过过滤器控制日志

.Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("SensitiveData"))

JSON 配置

"Filter": [
  {
    "Name": "ByExcluding",
    "Args": {
      "expression": "SourceContext = 'Microsoft.*'"
    }
  }
]

相关推荐

10条军规:电商API从数据泄露到高可用的全链路防护

电商API接口避坑指南:数据安全、版本兼容与成本控制的10个教训在电商行业数字化转型中,API接口已成为连接平台、商家、用户与第三方服务的核心枢纽。然而,从数据泄露到版本冲突,从成本超支到系统崩溃,A...

Python 文件处理在实际项目中的困难与应对策略

在Python项目开发,文件处理是一项基础且关键的任务。然而,在实际项目中,Python文件处理往往会面临各种各样的困难和挑战,从文件格式兼容性、编码问题,到性能瓶颈、并发访问冲突等。本文将深入...

The Future of Manufacturing with Custom CNC Parts

ThefutureofmanufacturingisincreasinglybeingshapedbytheintegrationofcustomCNC(ComputerNumericalContro...

Innovative Solutions in Custom CNC Machining

Inrecentyears,thelandscapeofcustomCNCmachininghasevolvedrapidly,drivenbyincreasingdemandsforprecisio...

C#.NET serilog 详解(c# repository)

简介Serilog是...

Custom CNC Machining for Small Batch Production

Inmodernmanufacturing,producingsmallbatchesofcustomizedpartshasbecomeanincreasinglycommondemandacros...

Custom CNC Machining for Customized Solutions

Thedemandforcustomizedsolutionsinmanufacturinghasgrownsignificantly,drivenbydiverseindustryneedsandt...

Revolutionizing Manufacturing with Custom CNC Parts

Understandinghowmanufacturingisevolving,especiallythroughtheuseofcustomCNCparts,canseemcomplex.Thisa...

Breaking Boundaries with Custom CNC Parts

BreakingboundarieswithcustomCNCpartsinvolvesexploringhowadvancedmanufacturingtechniquesaretransformi...

Custom CNC Parts for Aerospace Industry

Intherealmofaerospacemanufacturing,precisionandreliabilityareparamount.Thecomponentsthatmakeupaircra...

Cnc machining for custom parts and components

UnderstandingCNCmachiningforcustompartsandcomponentsinvolvesexploringitsprocesses,advantages,andcomm...

洞察宇宙(十八):深入理解C语言内存管理

分享乐趣,传播快乐,增长见识,留下美好。亲爱的您,这里是LearingYard学苑!今天小编为大家带来“深入理解C语言内存管理”...

The Art of Crafting Custom CNC Parts

UnderstandingtheprocessofcreatingcustomCNCpartscanoftenbeconfusingforbeginnersandevensomeexperienced...

Tailored Custom CNC Solutions for Automotive

Intheautomotiveindustry,precisionandefficiencyarecrucialforproducinghigh-qualityvehiclecomponents.Ta...

关于WEB服务器(.NET)一些经验累积(一)

以前做过技术支持,把一些遇到的问题累积保存起来,现在发出了。1.问题:未能加载文件或程序集“System.EnterpriseServices.Wrapper.dll”或它的某一个依赖项。拒绝访问。解...

取消回复欢迎 发表评论: