使用ILoggerFactory/ILoggingBuilder时为NLog设置自定义日志命名空间后缀
实现方案
有两种适配不同场景的方案可选:
方案1:自定义ILoggerFactory包装(通用方案)
该方案会修改Logger实际的分类名称,兼容所有依赖ILoggerFactory的第三方逻辑,即使第三方库需要用分类名做过滤也能正常生效。
实现步骤
- 自定义带后缀转发的ILogger实现:
public class SuffixedLogger : ILogger { private readonly ILogger _innerLogger; public SuffixedLogger(ILogger innerLogger) { _innerLogger = innerLogger; } 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) { _innerLogger.Log(logLevel, eventId, state, exception, formatter); } }
- 自定义带后缀处理的ILoggerFactory包装类:
public class SuffixedLoggerFactory : ILoggerFactory { private readonly ILoggerFactory _innerFactory; private readonly string _suffix; public SuffixedLoggerFactory(ILoggerFactory innerFactory, string suffix) { _innerFactory = innerFactory; _suffix = suffix.Trim('.'); } public ILogger CreateLogger(string categoryName) { var suffixedCategory = $"{categoryName}.{_suffix}"; var innerLogger = _innerFactory.CreateLogger(suffixedCategory); return new SuffixedLogger(innerLogger); } public void AddProvider(ILoggerProvider provider) => _innerFactory.AddProvider(provider); public void Dispose() => _innerFactory.Dispose(); }
- 替换原有工厂注入逻辑:
// 先创建原生NLog工厂 var nativeFactory = LoggerFactory.Create(builder => builder.AddNLog()); // 包装为带后缀的工厂,传入你需要的后缀foo var factory = new SuffixedLoggerFactory(nativeFactory, "foo");
后续直接将包装后的factory传给第三方库使用即可。
方案2:修改NLog输出布局(轻量方案)
如果仅需要在日志输出内容中显示带后缀的命名空间,不需要修改Logger实际的分类名,可以直接修改NLog配置的布局规则,无需修改C#注入代码。
只需要将布局中的${logger}变量修改为${logger}.foo即可,示例配置:
<targets> <target xsi:type="Console" name="console" layout="${longdate} ${level:uppercase=true} ${logger}.foo ${message}${newline}${exception:format=tostring}" /> </targets>
内容的提问来源于stack exchange,提问作者Dominic Boexler
相关产品推荐
相关产品推荐

