ASP.NET Core Serilog 未将属性推送到其自定义列

Jia*_*nYA 6 c# asp.net asp.net-mvc asp.net-core

appsettings.json我的 Serilog 安装有此设置

"Serilog": {
  "MinimumLevel": "Information",
  "Enrich": [ "LogUserName" ],
  "Override": {
    "Microsoft": "Critical"
  },
  "WriteTo": [
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "Server=.\\SQLEXPRESS;Database=Apple;Trusted_Connection=True;MultipleActiveResultSets=true;,
        "schemaName": "Apple",
        "tableName": "EventLogs",
        "columnOptionsSection": {
          "customColumns": [
            {
              "ColumnName": "UserName",
              "DataType": "nvarchar",
              "DataLength": 256,
              "AllowNull": true
            }
          ]
        }
      }
    }
  ]
},
Run Code Online (Sandbox Code Playgroud)

我还有一个名为的自定义丰富器LogUserName,它应该将用户用户名添加到UserName数据库中调用的列中。

这是丰富器:

public class LogUserName
{
    private readonly RequestDelegate next;

    public LogUserName(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        LogContext.PushProperty("UserName", context.User.Identity.Name);
        await next(context);
        //return next(context);
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经添加.Enrich.FromLogContext()到我的Program.cs.

到目前为止,我可以UserName在属性标签中看到 ,但无法将其推送到列中。

编辑:

我将这个模型用于数据库日志:

public class EventLogs
{
    [Key]
    public int Id { get; set; }
    public string Level { get; set; }
    public DateTime TimeStamp { get; set; }
    public string UserName { get; set; }
    public string Properties { get; set; }
    public string LogEvent { get; set; }
    public string Exception { get; set; }
    public string Message { get; set; }
    public string MessageTemplate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

mas*_*son 4

您的丰富器无效。你混淆了两个概念。向日志上下文添加属性与创建实际的丰富器不同。实际的丰富器应该实现 ILogEventEnricher,如本示例所示。

您实际创建的是 ASP.NET 中间件。LogContext.PushProprety 返回一个 IDisposable 并应包装在 using 语句中,然后 using 语句块内的任何内容都应具有带有附加属性的日志上下文。如文档中所示。

LogUserName解决此问题的一种方法是从丰富器配置中删除。然后将您的中间件更改为:

public class LogUserNameMiddleware
{
    private readonly RequestDelegate next;

    public LogUserNameMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        using(LogContext.PushProperty("UserName", context.User.Identity.Name))
        {
            await next(context);
        }       
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您还没有这样做,您需要告诉 ASP.NET Core 有关中间件的信息。

public static class LogUserNameMiddlewareExtensions
{
    public static IApplicationBuilder UseLogUserNameMiddleware(
        this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<LogUserNameMiddleware>();
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Startup.Configure 方法中,您可以将中间件添加到管道中:

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.UseLogUserNameMiddleware();
        //your other middleware
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果没有登录用户,您可能需要清理中间件来处理,这样您就不会收到 NullReferenceException。