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

.NET Core API中Serilog结合Azure Table Storage自定义日志字段

解决方案

完全不用编写自定义sink,Serilog的Azure Table Storage Sink本身就支持将对象属性扁平化存储为单独列,具体实现步骤如下:

1. 安装依赖包

确保项目中安装以下NuGet包:

Install-Package Serilog.AspNetCore
Install-Package Serilog.Sinks.AzureTableStorage

2. 保留你的LogDetail类

维持自定义类的定义不变,示例如下:

public class LogDetail
{
    public string CallingMethod { get; set; }
    public string AuthenticatedUser { get; set; }
    public string StackTrace { get; set; }
    public string CallingApp { get; set; }
}

3. 配置Serilog启用属性扁平化

在Program.cs(或Startup.cs)中配置Serilog时,开启FlattenObjects选项,Sink会自动将对象的每个属性展开为单独列:

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog
builder.Host.UseSerilog((context, config) =>
{
    config.WriteTo.AzureTableStorage(
        connectionString: context.Configuration["AzureTableStorage:ConnectionString"],
        storageTableName: "ApiLogs",
        flattenObjects: true // 关键配置:启用对象扁平化
    )
    .Enrich.FromLogContext()
    .ReadFrom.Configuration(context.Configuration);
});

// 其他API配置逻辑
var app = builder.Build();

4. 记录日志时注入LogDetail属性

在需要记录日志的位置,通过LogContext.PushProperty将LogDetail的属性(或整个对象)添加到日志上下文:

方式一:逐个推送属性(无前缀列名)

var logDetail = new LogDetail
{
    CallingMethod = "WeatherForecast.Get",
    AuthenticatedUser = User.Identity?.Name,
    StackTrace = Environment.StackTrace,
    CallingApp = "MyDotNetApi"
};

using (LogContext.PushProperty("CallingMethod", logDetail.CallingMethod))
using (LogContext.PushProperty("AuthenticatedUser", logDetail.AuthenticatedUser))
using (LogContext.PushProperty("StackTrace", logDetail.StackTrace))
using (LogContext.PushProperty("CallingApp", logDetail.CallingApp))
{
    Log.Information("API request processed");
}

这种方式下,Azure Table中会直接生成CallingMethod、AuthenticatedUser等独立列。

方式二:推送整个对象(带前缀列名)

因为已启用flattenObjects,直接推送整个LogDetail对象,Sink会自动展开属性,生成带前缀的列名(如LogDetail_CallingMethod):

var logDetail = new LogDetail
{
    CallingMethod = "WeatherForecast.Get",
    AuthenticatedUser = User.Identity?.Name,
    StackTrace = Environment.StackTrace,
    CallingApp = "MyDotNetApi"
};

using (LogContext.PushProperty("LogDetail", logDetail, destructureObjects: true))
{
    Log.Information("API request processed");
}

5. 注意事项

  • Azure Table Storage列名不能包含/、\、#等特殊字符,确保LogDetail的属性名称符合要求
  • 若属性值为复杂类型,扁平化后会自动转换为字符串形式
  • 可结合Serilog的Enricher全局注入通用属性(如AuthenticatedUser),避免重复代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:52:14