我正在通过下面的LoggerConfiguration创建自定义列.然后,使用中间件和我编写的UsernameColumnWriter类,我想在本专栏中打印发出请求时在PostgreSQL上登录的用户名.表和列正在形成,没有任何问题.但是,当我发出请求时,USER_NAME列仍然为空,尽管创建了日志(log)记录.

Serilog配置:

Logger log = new LoggerConfiguration()
.WriteTo.PostgreSQL(builder.Configuration.GetConnectionString("3pmConnectionString"),
    "Logs",
    needAutoCreateTable: true,
    columnOptions: new Dictionary<string, ColumnWriterBase>
    {
        {"message", new RenderedMessageColumnWriter(NpgsqlDbType.Text)},
        {"message_template", new MessageTemplateColumnWriter(NpgsqlDbType.Text)},
        {"level", new LevelColumnWriter(true , NpgsqlDbType.Varchar)},
        {"time_stamp", new TimestampColumnWriter(NpgsqlDbType.Timestamp)},
        {"exception", new ExceptionColumnWriter(NpgsqlDbType.Text)},
        {"log_event", new LogEventSerializedColumnWriter(NpgsqlDbType.Json)},
        {"user_name", new UsernameColumnWriter()}
    })
.WriteTo.Debug()
.WriteTo.Console()
.MinimumLevel.Information()
.CreateLogger();

builder.Host.UseSerilog(log);

中间件:

app.UseSerilogRequestLogging();
app.UseHttpLogging();

app.UseAuthentication();
app.UseAuthorization();

app.Use(async (context, next) => {
    var username = context.User?.Identity?.IsAuthenticated != null || true ? 
        context.User.Identity.Name : null;
    LogContext.PushProperty("user_name", username);
    await next();
});

我的班级:

    public class UsernameColumnWriter : ColumnWriterBase {
        public UsernameColumnWriter() : base(NpgsqlDbType.Varchar) {
        }

        public override object GetValue(LogEvent logEvent, IFormatProvider formatProvider = null) {
        var (username, value) = logEvent.Properties.FirstOrDefault(p => p.Key == "user_name");
        return value?.ToString() ?? null;
    }
}

推荐答案

您希望使用LogContext中的属性,但您的配置缺少必需的部分:

...
.Enrich.FromLogContext()
...

因此,您的最终配置应该如下所示:

Logger log = new LoggerConfiguration()
.WriteTo.PostgreSQL(builder.Configuration.GetConnectionString("3pmConnectionString"),
    "Logs",
    needAutoCreateTable: true,
    columnOptions: new Dictionary<string, ColumnWriterBase>
    {
        {"message", new RenderedMessageColumnWriter(NpgsqlDbType.Text)},
        {"message_template", new MessageTemplateColumnWriter(NpgsqlDbType.Text)},
        {"level", new LevelColumnWriter(true , NpgsqlDbType.Varchar)},
        {"time_stamp", new TimestampColumnWriter(NpgsqlDbType.Timestamp)},
        {"exception", new ExceptionColumnWriter(NpgsqlDbType.Text)},
        {"log_event", new LogEventSerializedColumnWriter(NpgsqlDbType.Json)},
        {"user_name", new UsernameColumnWriter()}
    })
.WriteTo.Debug()
.WriteTo.Console()
.MinimumLevel.Information()
.Enrich.FromLogContext() // <--
.CreateLogger();

Csharp相关问答推荐

如何在asp.net C#中获取视频文件的视频时长?

元素存在方法是否损坏

使用ElasticsearchClient设置忽略属性.默认MappingFor<>

为什么这个Reflection. Emit代码会导致一个DDL ViolationException?

REST API端点中异步后台代码执行的类型

模型绑定RazorPage表单

Mongo作为.NET中Testcontainers的副本集

JSON空引用异常仅在调试器中忽略try-Catch块,但在其他上下文中捕获得很好

为什么在使用动态obj+类obj时会调用串联?

如何将此方法参数化并使其更灵活?

如何通过属性初始化器强制初始化继承记录内的属性?

.NET并发词典交换值

交替的奇数

当使用Dapper映射DBNull时,我可以抛出异常吗?

使用System.Text.Json进行序列化时发生StackOverflow异常

同一组件的多个实例触发相同的事件处理程序

在使用UserManager时,如何包含与其他实体的关系?

如何在mediatr命令中访问HttpContext而不安装弃用的nuget包

实体框架-IsRequired()与OnDelete()

如何从非异步任务中正确返回TypeResult