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

无法将用户信息写入Serilog纯文本日志的问题求助

解决Serilog本地文件日志中用户信息的记录问题

咱们一步步来解决你遇到的两个核心问题:HttpContext获取用户为null,以及Enrich的信息在纯文本日志里看不到的问题。

1. 解决HttpContext.Current返回null的问题

你用静态类HTMLHelperExtensions获取HttpContext.Current的方式在ASP.NET MVC里并不靠谱——这个静态上下文在异步操作、某些初始化场景下会变成null。其实你的HomeController本身就继承自Controller,自带User属性,直接用它就稳多了!

把你的调用代码改成这样:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
        // 直接用Controller的User属性,还能处理匿名用户的情况
        var currentUser = User.Identity?.Name ?? "Anonymous";
        Log.Information("Application initial load. Included in Audit Log: {auditLog}. User: {User}", true, currentUser); 
        // other code 
        return View(); 
    } 
}

这样就彻底避开了HttpContext.Current的坑,而且代码更简洁。

2. 把Enrich的信息写入本地文件日志

你说.Enrich.WithEnvironmentUserName()能工作,但纯文本日志看不到——这是因为Serilog的File sink默认的输出模板不会包含这些Enrich出来的属性。咱们只需要自定义outputTemplate,把需要的属性加进去就行。

修改你的日志配置代码:

Log.Logger = new LoggerConfiguration() 
    .Enrich.WithEnvironmentUserName() 
    .WriteTo.File( 
        "fileLocation.txt",
        restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information, 
        rollingInterval: RollingInterval.Infinite, 
        fileSizeLimitBytes: 10485760, //10MiB 
        retainedFileCountLimit: 50,
        // 自定义输出模板,把EnvironmentUserName加进去
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} | 系统用户名: {EnvironmentUserName}{NewLine}{Exception}"
    ) 
    .WriteTo.Seq("http://localhost:5341") 
    .CreateLogger();

现在本地日志文件里就会自动带上EnvironmentUserName的值,不用每次写日志都手动传这个参数。

3. 进阶:自定义用户信息Enricher(推荐)

如果你想记录的是登录系统的用户,而不是服务器的系统用户名,咱们可以自定义一个Enricher,让所有日志自动带上当前登录用户的信息,省得每次写日志都要传用户参数。

先写一个自定义的Enricher类:

public class CurrentUserEnricher : ILogEventEnricher
{
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        var httpContext = HttpContext.Current;
        // 获取当前登录用户,没有的话显示Anonymous
        var userName = httpContext?.User?.Identity?.Name ?? "Anonymous";
        // 把用户信息作为属性添加到日志中
        logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("CurrentUser", userName));
    }
}

然后在日志配置里启用这个Enricher,同时修改File的输出模板:

Log.Logger = new LoggerConfiguration() 
    .Enrich.WithEnvironmentUserName()
    .Enrich.With<CurrentUserEnricher>() // 添加自定义的用户信息Enricher
    .WriteTo.File( 
        "fileLocation.txt",
        restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information, 
        rollingInterval: RollingInterval.Infinite, 
        fileSizeLimitBytes: 10485760, 
        retainedFileCountLimit: 50,
        // 现在可以同时显示系统用户名和登录用户
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj} | 系统用户: {EnvironmentUserName} | 登录用户: {CurrentUser}{NewLine}{Exception}"
    ) 
    .WriteTo.Seq("http://localhost:5341") 
    .CreateLogger();

这样之后,不管你在哪个控制器、哪个地方写日志,都会自动带上当前登录用户的信息,本地文件和Seq里都能看到,非常方便!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:17:25