wwa*_*rby 20 logging .net-core asp.net-core-2.0
我正在使用一个非常典型的(我认为)设置来登录我正在编写的 .NET Core 控制台应用程序:
services.AddLogging(loggingBuilder => {
loggingBuilder.AddConfiguration(Configuration.GetSection("Logging"));
loggingBuilder.AddConsole();
loggingBuilder.AddDebug();
});
Run Code Online (Sandbox Code Playgroud)
在我看来,默认输出很难阅读,因为它被我不感兴趣的上下文信息污染了:
控制台(第一行的所有内容都是不需要的噪音):
info: MyApp.MyNamespace.OtherNamespace[0]
The message I actually want to see
Run Code Online (Sandbox Code Playgroud)
调试(一切Information:
都是不必要的噪音):
MyApp.MyNamespace.OtherNamespace:Information: The message I actually want to see
Run Code Online (Sandbox Code Playgroud)
我以为关闭这些多余的上下文信息很容易,但到目前为止我还是一片空白。是否可以在不编写 ConsoleLogger 和 DebugLogger 的自定义实现的情况下禁用此功能?(此时使用 Log4Net 可能会更容易)。
这是我最终为解决此问题而编写的内容(使用Crayon为控制台输出着色):
using System;
using System.Collections.Concurrent;
using Crayon;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Kope.Pilot.Hrs.Utils.Logging
{
public class CleanConsoleLogger : ILogger
{
public LogLevel LogLevel { get; set; } = LogLevel.Information;
public IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => logLevel >= this.LogLevel;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
return;
string message = formatter(state, exception);
if (exception != null)
message += $"{Environment.NewLine}{exception}";
switch (logLevel)
{
case LogLevel.Trace:
Console.Out.WriteLineAsync(Output.Bright.Black(message));
break;
case LogLevel.Debug:
Console.Out.WriteLineAsync(Output.Bright.Black(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.Bright.Red(message));
break;
case LogLevel.Critical:
Console.Error.WriteLineAsync(Output.Bright.Red(message));
break;
}
}
}
public class CleanConsoleLoggerProvider : ILoggerProvider
{
private readonly ConcurrentDictionary<string, CleanConsoleLogger> _loggers = new ConcurrentDictionary<string, CleanConsoleLogger>();
public ILogger CreateLogger(string categoryName)
=> _loggers.GetOrAdd(categoryName, name => new CleanConsoleLogger());
public void Dispose()
{
_loggers.Clear();
}
}
public static class CleanConsoleLoggerFactoryExtensions
{
public static ILoggingBuilder AddCleanConsole(this ILoggingBuilder builder)
{
builder.Services.AddSingleton<ILoggerProvider, CleanConsoleLoggerProvider>();
return builder;
}
}
}
Run Code Online (Sandbox Code Playgroud)