Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Istnieje wielu usługodawców logowania dostępnych dla typowych wymagań logowania. Może jednak być konieczne zaimplementowanie niestandardowego ILoggerProvider , gdy jeden z dostępnych dostawców nie odpowiada potrzebom aplikacji. Z tego artykułu dowiesz się, jak zaimplementować niestandardowego dostawcę logowania, który może służyć do kolorowania logów w konsoli programu.
Wskazówka
Przykładowy kod źródłowy niestandardowego dostawcy logowania jest dostępny w repozytorium Docs w GitHub.
Przykładowa niestandardowa konfiguracja rejestratora
Przykładowy rejestrator tworzy kolorowe wpisy konsoli według poziomu logu i identyfikatora zdarzenia, przy użyciu następującego typu konfiguracji:
using Microsoft.Extensions.Logging;
public sealed class ColorConsoleLoggerConfiguration
{
public int EventId { get; set; }
public Dictionary<LogLevel, ConsoleColor> LogLevelToColorMap { get; set; } = new()
{
[LogLevel.Information] = ConsoleColor.Green
};
}
Powyższy kod ustawia domyślny kolor dla poziomu Information na Green. Wartość EventId jest niejawnie 0.
Utwórz niestandardowy rejestrator
Poniższy fragment kodu przedstawia implementację ILogger :
using Microsoft.Extensions.Logging;
public sealed class ColorConsoleLogger(
string name,
Func<ColorConsoleLoggerConfiguration> getCurrentConfig) : ILogger
{
public IDisposable? BeginScope<TState>(TState state)
where TState : notnull => default!;
public bool IsEnabled(LogLevel logLevel) =>
getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel);
public void Log<TState>(
LogLevel logLevel,
EventId eventId,
TState state,
Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
ColorConsoleLoggerConfiguration config = getCurrentConfig();
if (config.EventId == 0 || config.EventId == eventId.Id)
{
ConsoleColor originalColor = Console.ForegroundColor;
Console.ForegroundColor = config.LogLevelToColorMap[logLevel];
Console.WriteLine($"[{eventId.Id,2}: {logLevel,-12}]");
Console.ForegroundColor = originalColor;
Console.Write($" {name} - ");
Console.ForegroundColor = config.LogLevelToColorMap[logLevel];
Console.Write($"{formatter(state, exception)}");
Console.ForegroundColor = originalColor;
Console.WriteLine();
}
}
}
Każde wystąpienie rejestratora jest tworzone przez przekazanie nazwy kategorii, która jest zazwyczaj typem, w którym rejestrator jest tworzony. Metoda IsEnabled sprawdza getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel), czy żądany poziom dziennika jest włączony, czyli znajduje się w słowniku poziomów dziennika konfiguracji.
Dobrym rozwiązaniem jest wywołanie ILogger.IsEnabled w ramach implementacji ILogger.Log, ponieważ Log może być wywoływana przez dowolnego konsumenta i nie ma gwarancji, że została ona wcześniej sprawdzona. Metoda IsEnabled powinna być bardzo szybka w większości implementacji.
if (!IsEnabled(logLevel))
{
return;
}
Rejestrator jest tworzony przy użyciu name oraz Func<ColorConsoleLoggerConfiguration>, który zwraca bieżącą konfigurację.
Ważne
Implementacja ILogger.Log sprawdza, czy ustawiono wartość config.EventId. Jeśli config.EventId nie jest ustawione lub gdy dokładnie odpowiada logEntry.EventId, rejestrator wyświetla informacje w kolorze.
Niestandardowy dostawca rejestratora
Obiekt ILoggerProvider jest odpowiedzialny za tworzenie instancji loggera. Nie jest konieczne utworzenie wystąpienia rejestratora dla każdej kategorii, ale w przypadku niektórych rejestratorów, takich jak NLog lub log4net, może to mieć sens. Ta strategia pozwala wybrać różne cele wyjściowe rejestrowania dla każdej kategorii, jak w poniższym przykładzie:
using System.Collections.Concurrent;
using System.Runtime.Versioning;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
{
private readonly IDisposable? _onChangeToken;
private ColorConsoleLoggerConfiguration _currentConfig;
private readonly ConcurrentDictionary<string, ColorConsoleLogger> _loggers =
new(StringComparer.OrdinalIgnoreCase);
public ColorConsoleLoggerProvider(
IOptionsMonitor<ColorConsoleLoggerConfiguration> config)
{
_currentConfig = config.CurrentValue;
_onChangeToken = config.OnChange(updatedConfig => _currentConfig = updatedConfig);
}
public ILogger CreateLogger(string categoryName) =>
_loggers.GetOrAdd(categoryName, name => new ColorConsoleLogger(name, GetCurrentConfig));
private ColorConsoleLoggerConfiguration GetCurrentConfig() => _currentConfig;
public void Dispose()
{
_loggers.Clear();
_onChangeToken?.Dispose();
}
}
W poprzednim kodzie CreateLogger(String) tworzy pojedyncze wystąpienie ColorConsoleLogger dla każdej nazwy kategorii i przechowuje je w ConcurrentDictionary<TKey,TValue>.
Klasa jest ozdobiona dwoma ColorConsoleLoggerProvider atrybutami:
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
-
UnsupportedOSPlatformAttribute: Typ
ColorConsoleLoggerjest nieobsługiwany w"browser". -
ProviderAliasAttribute: sekcje konfiguracji mogą definiować opcje przy użyciu klucza
"ColorConsole".
Konfigurację można określić przy użyciu dowolnego prawidłowego dostawcy konfiguracji . Rozważ następujący plik appsettings.json :
{
"Logging": {
"ColorConsole": {
"LogLevelToColorMap": {
"Information": "DarkGreen",
"Warning": "Cyan",
"Error": "Red"
}
}
}
}
Plik appsettings.json określa, że kolor Information poziomu dziennika to DarkGreen, który zastępuje wartość domyślną ustawioną ColorConsoleLoggerConfiguration w obiekcie.
Użycie i rejestracja niestandardowego rejestratora
Zgodnie z konwencją usługi są rejestrowane do wstrzykiwania zależności w ramach procedury uruchamiania aplikacji. W tym przykładzie usługa rejestrowania jest rejestrowana bezpośrednio z pliku Program.cs .
Aby dodać niestandardowego dostawcę logowania i odpowiedni logger, dodaj element ILoggerProvider, wywołując niestandardową metodę rozszerzającą, AddColorConsoleLogger na ILoggingBuilder z właściwości IHostApplicationBuilder.Logging.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddColorConsoleLogger(configuration =>
{
// Replace value of "Cyan" from appsettings.json.
configuration.LogLevelToColorMap[LogLevel.Warning]
= ConsoleColor.DarkCyan;
// Replace value of "Red" from appsettings.json.
configuration.LogLevelToColorMap[LogLevel.Error]
= ConsoleColor.DarkRed;
});
using IHost host = builder.Build();
ILogger<Program> logger = host.Services.GetRequiredService<ILogger<Program>>();
logger.LogDebug(1, "Does this line get hit?"); // Not logged
logger.LogInformation(3, "Nothing to see here."); // Logs in ConsoleColor.DarkGreen
logger.LogWarning(5, "Warning... that was odd."); // Logs in ConsoleColor.DarkCyan
logger.LogError(7, "Oops, there was an error."); // Logs in ConsoleColor.DarkRed
logger.LogTrace(5, "== 120."); // Not logged
await host.RunAsync();
Zgodnie z konwencją metody rozszerzeń w ILoggingBuilder są używane do rejestrowania dostawcy niestandardowego:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
public static class ColorConsoleLoggerExtensions
{
public static ILoggingBuilder AddColorConsoleLogger(
this ILoggingBuilder builder)
{
builder.AddConfiguration();
builder.Services.TryAddEnumerable(
ServiceDescriptor.Singleton<ILoggerProvider, ColorConsoleLoggerProvider>());
LoggerProviderOptions.RegisterProviderOptions
<ColorConsoleLoggerConfiguration, ColorConsoleLoggerProvider>(builder.Services);
return builder;
}
public static ILoggingBuilder AddColorConsoleLogger(
this ILoggingBuilder builder,
Action<ColorConsoleLoggerConfiguration> configure)
{
builder.AddColorConsoleLogger();
builder.Services.Configure(configure);
return builder;
}
}
ILoggingBuilder tworzy jedno lub więcej wystąpień ILogger. Wystąpienia ILogger są używane przez platformę do rejestrowania informacji.
Kod wystąpienia zastępuje wartości kolorów z pliku appsettings.json dla LogLevel.Warning i LogLevel.Error.
Po uruchomieniu tej prostej aplikacji renderuje ona kolorowe dane wyjściowe w oknie konsoli, podobnie jak na poniższej ilustracji:
przykładowe dane wyjściowe rejestratora kolorów konsoli