Identity Server在Serilog中生成过多冗余日志,能否通过源上下文过滤?
可以通过源上下文过滤结合消息内容匹配的方式实现需求,你之前的过滤规则未生效,是因为Identity Server的日志源上下文前缀为IdentityServer,不属于你配置的Microsoft/Microsoft.AspNetCore前缀覆盖范围。
方案1:纯配置文件实现(推荐)
- 第一步:先安装NuGet依赖包
Serilog.Expressions用于支持配置文件内的过滤表达式 - 第二步:修改appsettings.json中的Serilog配置,完整配置参考如下:
"Serilog": { "Using": [ "Serilog.Sinks.Seq", "Serilog", "Serilog.Expressions" ], "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Error", "Microsoft.AspNetCore": "Error", "IdentityServer": "Information" } }, "Filter": [ { "Name": "ByExcluding", "Args": { "expression": "StartsWith(SourceContext, 'IdentityServer') and not Contains(@Message, 'User Logged in')" } } ], "WriteTo": [ { "Name": "Seq", "Args": { "serverUrl": "http://seqserver" } } ], "Enrich": [ "FromLogContext", "WithMachineName" ], "Properties": { "Application": "App" } }
方案2:代码硬编码过滤实现
无需修改配置文件,直接调整Program.cs中的Serilog注册逻辑即可,修改后参考代码如下:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseSerilog((context, config) => { config.ReadFrom.Configuration(context.Configuration) .Enrich.FromLogContext() .Enrich.WithProperty("Environment", context.HostingEnvironment) // 新增过滤规则 .Filter.ByExcluding(logEvent => { // 提取源上下文 if (logEvent.Properties.TryGetValue("SourceContext", out var sourceCtxVal) && sourceCtxVal is Serilog.Events.ScalarValue scalarVal && scalarVal.Value is string sourceCtx) { // 匹配IdentityServer前缀且不包含登录日志的内容 if (sourceCtx.StartsWith("IdentityServer") && !logEvent.RenderMessage().Contains("User Logged in")) { return true; } } return false; }); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
优化建议
如果怕误命中其他包含「User Logged in」的无关日志,可以先在Seq中查看正常用户登录日志的EventId属性值,将过滤规则改为精确匹配EventId,逻辑会更稳定。比如配置文件的表达式可修改为:"expression": "StartsWith(SourceContext, 'IdentityServer') and EventId != 1001"
请将1001替换为你实际环境中登录日志对应的EventId值。
内容的提问来源于stack exchange,提问作者yithril
相关产品推荐
相关产品推荐

