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

.NET Core 3.1 WebAPI中Serilog日志ClientIp字段为空排查

问题原因

你配置的ClientIp、ClientAgent字段为空并非语法错误,是两处核心配置遗漏导致:

  • Serilog.Enrichers.ClientInfo 组件依赖IHttpContextAccessor获取请求上下文信息,.NET Core 3.1默认不注册该服务,组件拿不到HttpContext实例自然返回空值。
  • 你原有配置用了嵌套子Logger结构,根节点配置的Enrich规则不会自动被子Logger继承,控制台、MSSqlServer两个输出目标实际根本没有执行IP和UA的取值逻辑。
  • 补充说明:应用启动阶段的日志(比如监听端口、服务启动提示)本身没有关联HTTP请求上下文,这部分日志的ClientIp为空是正常现象,只有进入请求处理管道后产生的日志才会携带对应值。
修复步骤

1. 注入HttpContextAccessor服务

打开项目的Startup.cs,在ConfigureServices方法中添加服务注册:

public void ConfigureServices(IServiceCollection services)
{
    // 新增这行,注册IHttpContextAccessor
    services.AddHttpContextAccessor();
    // 保留原有其他服务注册逻辑,比如AddControllers、AddDbContext等
}

2. 简化修正Serilog配置

原配置中嵌套两层Logger的写法完全多余,不仅容易丢失Enrich规则,还增加配置复杂度,直接去掉嵌套,将输出目标平铺在WriteTo节点即可,修正后的Serilog配置参考:

"Serilog": {
    "MinimumLevel": {
        "Default": "Debug",
        "Override": {
            "Microsoft": "Warning",
            "System": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "Enrich": [ "FromLogContext", "WithMachineName", "WithClientIp", "WithClientAgent" ],
    "WriteTo": [
        {
            "Name": "Console",
            "Args": {
                "outputTemplate": "[{Level:u3} {Timestamp:o}] {ClientIp} {ClientAgent} ({SourceContext}) {Message} {NewLine}"
            }
        },
        {
            "Name": "MSSqlServer",
            "Args": {
                "connectionString": "TestDbContext",
                "tableName": "ErrorLogs",
                "batchPostingLimit": 50,
                "autoCreateSqlTable": true,
                "restrictedToMinimumLevel": "Error",
                "columnOptionsSection": {
                    "removeStandardColumns": [ "MessageTemplate" ],
                    "customColumns": [
                        {
                            "ColumnName": "ClientIp",
                            "DataType": "VARCHAR",
                            "AllowNull": true,
                            "DataLength": 50
                        },
                        {
                            "ColumnName": "ClientAgent",
                            "DataType": "VARCHAR",
                            "AllowNull": true,
                            "DataLength": 500
                        }
                    ]
                }
            }
        }
    ]
}

配置说明:用restrictedToMinimumLevel: "Error"即可实现只写入Error、Fatal级别日志到数据库,比原来的Filter配置更简洁,也不会丢失Enrich生成的属性。原配置的自定义列只加了ClientIp,如果需要把UA也存到数据库,记得补上ClientAgent的列定义。

3. 反向代理场景额外配置

如果服务部署在Nginx、IIS等反向代理之后,默认拿到的会是代理服务器的IP,需要在Startup.cs的Configure方法最顶部添加转发头中间件,才能获取真实客户端IP:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 放在所有中间件的最前面
    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });
    // 保留原有其他中间件配置,比如UseRouting、UseAuthorization、UseEndpoints等
}
验证方法

修改完成后重启应用,发起任意接口请求,请求生命周期内产生的日志会正常打印ClientIp和ClientAgent值,Error级别的日志也会自动将ClientIp写入ErrorLogs表对应字段。启动阶段无请求上下文的日志ClientIp为空属于正常情况,无需额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:30:53