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

如何在C# Web API中使用Serilog自定义指定格式的JSON日志并添加运行时字段

如何在C# Web API中使用Serilog自定义指定格式的JSON日志并添加运行时字段

看起来你已经搭好了Serilog的基础配置,现在要改成指定的JSON格式,还要加上那些动态的运行时字段对吧?我来一步步帮你实现:

第一步:修改appsettings.json,让Serilog输出指定格式的JSON

首先,我们需要把控制台输出换成JSON格式,并且匹配你要的字段结构。修改你的appsettings.json里的Serilog配置:

"Serilog": {
  "Using": ["Serilog.Sinks.Console"],
  "MinimumLevel": {
    "Default": "Information"
  },
  "Enrich": ["FromLogContext"],
  "WriteTo": [
    {
      "Name": "Console",
      "Args": {
        "outputTemplate": "{{\"LEVEL\": \"{Level:u}\", \"TIMESTAMP\": \"{Timestamp:yyyy-MM-dd HH:mm:ss,fff}\", \"CALLER\": \"{Properties:Caller}\", \"EVENT_NAME\": \"{Properties:EventName}\", \"ERRORID\": \"{Properties:ErrorId}\", \"MESSAGE\": \"{Message}\"}} {NewLine}{Exception}",
        "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
      }
    }
  ]
}

这个模板会直接输出你要的JSON结构,注意双引号的转义处理即可。

第二步:添加运行时动态字段(CALLER、EVENT_NAME、ERRORID)

这些动态字段需要我们把值注入到Serilog的日志上下文里,这样日志输出时就能自动包含它们,有两种常用方式:

方式1:单个日志调用时手动添加

在需要记录日志的方法里,用LogContext.PushProperty临时注入字段:

using Serilog.Context;

// 示例:从请求头获取客户端名称,当前方法名作为事件名,自定义错误ID
var callerName = HttpContext.Request.Headers["Client-Name"].FirstOrDefault() ?? "UNKNOWN_CLIENT";
var eventName = nameof(GetUserInfo); // 获取当前方法名
var errorId = "10001";

// 用using包裹,确保上下文在日志完成后自动释放
using (LogContext.PushProperty("Caller", callerName))
using (LogContext.PushProperty("EventName", eventName))
using (LogContext.PushProperty("ErrorId", errorId))
{
    Log.Error("INVALID REQUEST");
}

方式2:中间件统一处理全局字段

如果像CALLER这种字段是每个请求都需要的,可以写个中间件自动注入,不用每次手动加:

public class LogContextMiddleware
{
    private readonly RequestDelegate _next;

    public LogContextMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var callerName = context.Request.Headers["Client-Name"].FirstOrDefault() ?? "UNKNOWN_CLIENT";
        // 注入客户端名称到日志上下文
        using (LogContext.PushProperty("Caller", callerName))
        {
            await _next(context);
        }
    }
}

// 在Program.cs里注册中间件(要放在其他业务中间件之前)
app.UseMiddleware<LogContextMiddleware>();

第三步:确保Serilog配置正确生效

你的logConfig.cs可以简化一下,直接在Program.cs里注册Serilog更直观:

var builder = WebApplication.CreateBuilder(args);

// 先配置Serilog
builder.Host.UseSerilog((context, config) =>
{
    config.ReadFrom.Configuration(context.Configuration);
});

// 再添加其他服务
builder.Services.AddControllers();
// ...其他业务服务注册

var app = builder.Build();

// 注册中间件(包括上面的LogContextMiddleware)
app.UseHttpsRedirection();
app.UseMiddleware<LogContextMiddleware>();
app.UseAuthorization();

app.MapControllers();
app.Run();

测试效果

当你触发日志后,控制台会输出完全符合你要求的JSON格式:

{"LEVEL":"ERROR","TIMESTAMP":"2023-06-07 14:07:59,983","CALLER":"MY_CLIENT","EVENT_NAME":"GetUserInfo","ERRORID":"10001","MESSAGE":"INVALID REQUEST"}

备注:内容来源于stack exchange,提问作者learningdotnet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 10:18:00