You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为项目中所有Serilog日志调用注入LogContext并添加ExecutionContext属性?

实现Serilog全局注入LogContext的ExecutionContext属性

1. 启用Serilog的LogContext增强

首先要在Serilog配置中开启Enrich.FromLogContext(),确保LogContext中的属性能被自动附加到所有日志事件里。在Program.cs的配置代码如下:

var builder = WebApplication.CreateBuilder(args);

builder.Host.UseSerilog((context, config) =>
{
    config.ReadFrom.Configuration(context.Configuration)
          .Enrich.FromLogContext() // 关键配置:开启LogContext属性注入
          .WriteTo.Console(); // 根据实际需求调整输出目标
});

2. 编写全局中间件注入ExecutionContext

创建一个中间件,在每个请求启动时生成并注入ExecutionContext到LogContext,确保整个请求生命周期内的所有日志都携带该属性:

public class ExecutionContextMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IExecutionContextGenerator _executionGenerator;

    public ExecutionContextMiddleware(RequestDelegate next, IExecutionContextGenerator executionGenerator)
    {
        _next = next;
        _executionGenerator = executionGenerator;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 调用共享类库生成十六进制字符串
        var executionId = _executionGenerator.GenerateHexString();
        
        // 使用using块包裹,确保请求结束后自动释放LogContext
        using (LogContext.PushProperty("ExecutionContext", executionId))
        {
            await _next(context);
        }
    }
}

// 扩展方法简化中间件注册
public static class ExecutionContextMiddlewareExtensions
{
    public static IApplicationBuilder UseExecutionContext(this IApplicationBuilder app)
    {
        return app.UseMiddleware<ExecutionContextMiddleware>();
    }
}

然后在Program.cs中注册中间件(必须放在UseSerilogRequestLogging之前,保证请求日志本身也能带上ExecutionContext):

var app = builder.Build();

// 注册ExecutionContext中间件
app.UseExecutionContext();

// 启用Serilog请求日志
app.UseSerilogRequestLogging();

// 其他中间件配置
app.UseRouting();
app.UseAuthorization();

app.MapControllers();

app.Run();

3. 注册共享类库的生成器服务

将共享类库中生成十六进制字符串的组件注册为依赖注入服务:

// 假设共享类库中的接口与实现如下
public interface IExecutionContextGenerator
{
    string GenerateHexString();
}

public class ExecutionContextGenerator : IExecutionContextGenerator
{
    public string GenerateHexString()
    {
        // 这里替换为共享类库的实际生成逻辑,示例用GUID转十六进制
        return Guid.NewGuid().ToString("N");
    }
}

// 在Program.cs中注册服务
builder.Services.AddScoped<IExecutionContextGenerator, ExecutionContextGenerator>();

4. 验证效果

现在项目中所有日志(包括控制器、服务类、请求日志)都会自动携带ExecutionContext属性。比如控制器中的日志调用:

[ApiController]
[Route("[controller]")]
public class DemoController : ControllerBase
{
    private readonly ILogger<DemoController> _logger;

    public DemoController(ILogger<DemoController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IActionResult Get()
    {
        _logger.LogInformation("处理Get请求");
        return Ok();
    }
}

控制台输出的日志会包含类似这样的内容:

[INF] 处理Get请求 {ExecutionContext: "f47ac10b58cc4372a5670e02b2c3d799"}

额外说明

  • 对于后台任务(比如HostedService),因为不在请求生命周期内,需要在任务执行逻辑中手动用LogContext.PushProperty包裹代码,才能带上ExecutionContext属性。

内容的提问来源于stack exchange,提问作者gitzko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:22:45