无法将用户信息写入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
相关产品推荐
相关产品推荐

