如何在Blazor Server端以编程方式设置AppSettings中的Serilog UserId值?
在Serilog日志中动态设置UserId的正确方法
你的原有方法无效的原因是:Serilog在应用启动时就完成了配置加载并创建了Logger实例,后续修改Configuration["Serilog:Properties:UserId"]不会同步到已初始化的Serilog配置中——这些全局属性是在Logger创建时就固定下来的。
以下是几种可行的正确方案:
方案1:使用LogContext上下文属性(最推荐)
通过Serilog的LogContext为当前用户的日志添加UserId属性,该方式是线程/请求安全的,适合Blazor多用户场景。
步骤1:修改Serilog配置
在appsettings.json的Serilog节点中添加日志上下文增强配置:
"Serilog": { "Using": [], "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } }, "Enrich": ["FromLogContext"], // 新增此行,启用日志上下文增强 "WriteTo": [ { "Name": "Seq", "Args": { "serverUrl": "https://logging.mysite.com" } } ], "Properties": { "ApplicationName": "TESTApp", "Environment": "DEV" } }
步骤2:在Blazor组件中设置上下文属性
在index.razor中使用LogContext.PushProperty添加UserId:
using Serilog.Context; using System; private IDisposable _userIdProperty; protected override async Task OnInitializedAsync() { var userId = GetUserId(); // 将UserId推入日志上下文,后续当前用户的所有日志都会携带该属性 _userIdProperty = LogContext.PushProperty("UserId", userId); } // 组件销毁时清理上下文属性 public void Dispose() { _userIdProperty?.Dispose(); }
方案2:创建带用户ID的独立Logger实例
如果需要为当前用户创建专属Logger,可以使用ForContext方法:
using Serilog; private ILogger _userLogger; protected override void OnInitialized() { var userId = GetUserId(); // 创建包含当前UserId的Logger实例 _userLogger = Log.ForContext("UserId", userId); } // 使用该Logger记录日志 private void LogUserAction() { _userLogger.Information("用户执行了某项操作"); }
方案3:替换全局Logger(不推荐)
如果一定要修改全局Logger的属性,可以重新创建Logger实例,但该方式在多用户场景下会导致日志混乱(所有用户的日志都会带上最后设置的UserId),仅适合单用户环境:
using Serilog; protected override async Task OnInitializedAsync() { var userId = GetUserId(); var newLogger = new LoggerConfiguration() .ReadFrom.Configuration(Configuration) .Enrich.WithProperty("UserId", userId) .CreateLogger(); // 替换全局Logger Log.Logger = newLogger; }
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

