我正在使用一种非常典型的设置(我认为)登录我正在编写的.NET Core控制台应用程序:
services.AddLogging(loggingBuilder => {
loggingBuilder.AddConfiguration(Configuration.GetSection("Logging"));
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
});
在我看来,默认输出很难读取,因为它被我不感兴趣的上下文信息所污染:
控制台(第一行中的所有内容都是有害的噪声):
info: MyApp.MyNamespace.OtherNamespace[0]
The message I actually want to see
调试(最多Information:
都是有害的噪声):
MyApp.MyNamespace.OtherNamespace:Information: The message I actually want to see
我认为关闭这些多余的上下文信息会很容易,但是到目前为止,我还是空白。如果不编写ConsoleLogger和DebugLogger的自定义实现,是否可以禁用这些东西? (这时使用Log4Net可能会更容易)。
答案 0 :(得分:0)
这是我最终为解决此问题而写的内容(利用Crayon为控制台输出上色):
public class CleanConsoleLogger : ILogger {
private readonly IAppConfigHelper _configHelper;
public CleanConsoleLogger(IAppConfigHelper configHelper) {
_configHelper = configHelper;
}
public IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => logLevel >= _configHelper.ConsoleLogLevel;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) {
if (!IsEnabled(logLevel)) { return; }
var message = formatter(state, exception);
if (string.IsNullOrEmpty(message)) { return; }
if (exception != null) {
message += $"{Environment.NewLine}{exception}";
}
switch (logLevel) {
case LogLevel.Trace:
Console.Out.WriteLineAsync(Output.BrightBlack(message));
break;
case LogLevel.Debug:
Console.Out.WriteLineAsync(Output.BrightBlack(message));
break;
case LogLevel.Information:
Console.Out.WriteLineAsync(message);
break;
case LogLevel.Warning:
Console.Out.WriteLineAsync(Output.Dim().Yellow().Text(message));
break;
case LogLevel.Error:
Console.Error.WriteLineAsync(Output.BrightRed(message));
break;
case LogLevel.Critical:
Console.Error.WriteLineAsync(Output.BrightRed(message));
break;
}
}
}
public class CleanConsoleLoggerProvider : ILoggerProvider {
private readonly IAppConfigHelper _configHelper;
private readonly ConcurrentDictionary<string, CleanConsoleLogger> _loggers = new ConcurrentDictionary<string, CleanConsoleLogger>();
public CleanConsoleLoggerProvider(IAppConfigHelper configHelper) {
_configHelper = configHelper;
}
public ILogger CreateLogger(string categoryName)
=> _loggers.GetOrAdd(categoryName, name => new CleanConsoleLogger(_configHelper));
public void Dispose() {
_loggers.Clear();
}
}
public static class CleanConsoleLoggerFactoryExtensions {
public static ILoggingBuilder AddCleanConsole(this ILoggingBuilder builder) {
builder.Services.AddSingleton<ILoggerProvider, CleanConsoleLoggerProvider>();
return builder;
}
}
public class CleanDebugLogger : ILogger {
private readonly IAppConfigHelper _configHelper;
public CleanDebugLogger(IAppConfigHelper configHelper) {
_configHelper = configHelper;
}
public IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => Debugger.IsAttached && logLevel >= _configHelper.ConsoleLogLevel;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) {
if (!IsEnabled(logLevel)) { return; }
var message = formatter(state, exception);
if (string.IsNullOrEmpty(message)) { return; }
if (exception != null) {
message += $"{Environment.NewLine}{exception}";
}
Debug.WriteLine(message);
}
}
public class CleanDebugLoggerProvider : ILoggerProvider {
private readonly IAppConfigHelper _configHelper;
private readonly ConcurrentDictionary<string, CleanDebugLogger> _loggers = new ConcurrentDictionary<string, CleanDebugLogger>();
public CleanDebugLoggerProvider(IAppConfigHelper configHelper) {
_configHelper = configHelper;
}
public ILogger CreateLogger(string categoryName)
=> _loggers.GetOrAdd(categoryName, name => new CleanDebugLogger(_configHelper));
public void Dispose() {
_loggers.Clear();
}
}
public static class CleanDebugLoggerFactoryExtensions {
public static ILoggingBuilder AddCleanDebug(this ILoggingBuilder builder) {
builder.Services.AddSingleton<ILoggerProvider, CleanDebugLoggerProvider>();
return builder;
}
}