FilterLoggingBuilderExtensions.AddFilter重载String参数含义及日志内容过滤
关于FilterLoggingBuilderExtensions.AddFilter的Func参数及按日志消息过滤的方法
一、AddFilter重载中Func参数的String含义
以AddFilter(ILoggingBuilder, Func<string, string, LogLevel, bool>)为例,两个string参数的定义明确如下:
- 第一个参数:日志类别(Logger Category):即创建
ILogger<T>时泛型T的全名;若手动创建Logger(如loggerFactory.CreateLogger("MyCustomCategory")),则为传入的自定义类别字符串。 - 第二个参数:日志提供者名称(Logger Provider Name):对应具体日志输出组件的类型全名,比如控制台日志的
Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider、文件日志的Serilog.Extensions.Logging.SerilogLoggerProvider等。
该重载仅能根据日志类别、提供者和级别做前置过滤,无法获取日志的具体消息内容——因为此时日志尚未完成格式化,消息内容还未生成。
二、按日志消息内容过滤的实现方法
由于默认过滤器链条在日志消息格式化前执行,要实现按消息内容过滤,需在消息生成后再做判断,可通过自定义ILogger包装类实现:
步骤1:创建自定义Logger包装类
public class MessageFilterLogger : ILogger { private readonly ILogger _innerLogger; private readonly Func<string, bool> _messageFilter; public MessageFilterLogger(ILogger innerLogger, Func<string, bool> messageFilter) { _innerLogger = innerLogger; _messageFilter = messageFilter; } public IDisposable BeginScope<TState>(TState state) => _innerLogger.BeginScope(state); public bool IsEnabled(LogLevel logLevel) => _innerLogger.IsEnabled(logLevel); public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { // 先格式化生成日志消息 var message = formatter(state, exception); // 应用消息过滤规则,符合条件才记录 if (_messageFilter(message)) { _innerLogger.Log(logLevel, eventId, state, exception, formatter); } } }
步骤2:创建对应的LoggerProvider
public class MessageFilterLoggerProvider : ILoggerProvider { private readonly ILoggerProvider _innerProvider; private readonly Func<string, bool> _messageFilter; public MessageFilterLoggerProvider(ILoggerProvider innerProvider, Func<string, bool> messageFilter) { _innerProvider = innerProvider; _messageFilter = messageFilter; } public ILogger CreateLogger(string categoryName) { var innerLogger = _innerProvider.CreateLogger(categoryName); return new MessageFilterLogger(innerLogger, _messageFilter); } public void Dispose() => _innerProvider.Dispose(); }
步骤3:在LoggingBuilder中注册并使用
public static ILoggingBuilder AddMessageFilter(this ILoggingBuilder builder, Func<string, bool> messageFilter) { var innerProvider = builder.Services.FirstOrDefault(s => s.ServiceType == typeof(ILoggerProvider))?.ImplementationInstance as ILoggerProvider; if (innerProvider != null) { builder.Services.Replace(ServiceDescriptor.Singleton<ILoggerProvider>(new MessageFilterLoggerProvider(innerProvider, messageFilter))); } return builder; } // 使用示例:过滤包含"敏感信息"的日志 builder.Logging.AddMessageFilter(message => !message.Contains("敏感信息"));
简化方案(第三方日志框架)
若使用Serilog等第三方日志框架,可直接利用其内置过滤能力,示例如下:
Log.Logger = new LoggerConfiguration() .Filter.ByExcluding(logEvent => logEvent.MessageTemplate.Text.Contains("敏感信息")) .WriteTo.Console() .CreateLogger();
内容的提问来源于stack exchange,提问作者Rev
相关产品推荐
相关产品推荐

