如何在Blazor Server应用中通过Serilog追踪客户端信息
在Blazor Server中为Serilog添加客户端信息解决方案
核心思路
Blazor Server通过SignalR与客户端通信,每个用户会话对应一个Scoped服务实例。我们可以利用这一特性,在会话初始化时获取客户端IP、User-Agent等信息,再通过Serilog的LogContext将这些信息附加到所有日志条目里。
具体实现步骤
1. 注册基础服务
在Program.cs中注册IHttpContextAccessor(用于获取客户端请求上下文),并添加封装客户端信息的Scoped服务:
builder.Services.AddHttpContextAccessor(); builder.Services.AddScoped<IClientInfoProvider, ClientInfoProvider>();
2. 实现客户端信息获取服务
创建接口和实现类,从HttpContext中提取客户端核心信息:
public interface IClientInfoProvider { string ClientIpAddress { get; } string UserAgent { get; } } public class ClientInfoProvider : IClientInfoProvider { private readonly IHttpContextAccessor _httpContextAccessor; public ClientInfoProvider(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public string ClientIpAddress => _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString() ?? "Unknown"; public string UserAgent => _httpContextAccessor.HttpContext?.Request.Headers["User-Agent"].ToString() ?? "Unknown"; }
3. 配置Serilog启用LogContext
在Program.cs的Serilog配置中,添加FromLogContext enricher,确保日志能捕获上下文附加的信息:
builder.Host.UseSerilog((context, config) => { config .ReadFrom.Configuration(context.Configuration) .Enrich.FromLogContext() // 关键:开启LogContext信息捕获 .WriteTo.File("logs/log-.txt", rollingInterval: RollingInterval.Day); });
4. 在Blazor组件中注入客户端信息到日志上下文
在全局布局组件(如MainLayout.razor)中注入IClientInfoProvider,并在初始化时将客户端信息推入LogContext,这样所有子组件的日志都会自动携带这些信息:
@inject IClientInfoProvider ClientInfoProvider @using Serilog.Context @code { protected override void OnInitialized() { // 推入客户端IP和UserAgent到日志上下文 LogContext.PushProperty("ClientIp", ClientInfoProvider.ClientIpAddress); LogContext.PushProperty("UserAgent", ClientInfoProvider.UserAgent); base.OnInitialized(); } }
5. 验证日志输出
现在在任意组件中使用Serilog记录日志:
Log.Information("用户触发了数据查询操作");
日志文件中会包含附加的客户端字段,示例输出:
[2024-05-20 14:30:00 INF] 用户触发了数据查询操作 {ClientIp: "192.168.1.105", UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"}
注意事项
- 若部署在反向代理(Nginx、IIS等)之后,需配置转发真实客户端IP,否则获取到的是代理服务器的IP。可在
Program.cs中添加:app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); - 若仅需在特定代码块临时添加日志属性,可使用
using语句管理LogContext.PushProperty返回的IDisposable对象,确保上下文及时清理。
内容的提问来源于stack exchange,提问作者FBIT
相关产品推荐
相关产品推荐

