Implementowanie niestandardowego dostawcy rejestrowania na platformie .NET
Istnieje wiele dostawców rejestrowania dostępnych dla typowych potrzeb rejestrowania. Może być konieczne zaimplementowanie niestandardowego ILoggerProvider , gdy jeden z dostępnych dostawców nie odpowiada potrzebom aplikacji. W tym artykule dowiesz się, jak zaimplementować niestandardowego dostawcę rejestrowania, który może służyć do kolorowania dzienników w konsoli programu .
Napiwek
Przykładowy kod źródłowy niestandardowego dostawcy rejestrowania jest dostępny w repozytorium GitHub witryny Docs. Aby uzyskać więcej informacji, zobacz GitHub: .NET Docs — rejestrowanie niestandardowe konsoli.
Przykładowa niestandardowa konfiguracja rejestratora
Przykład tworzy różne wpisy konsoli kolorów na poziom dziennika i identyfikator 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 poziom na Information
, kolor na Green
, a element EventId
jest niejawnie 0
.
Tworzenie niestandardowego rejestratora
ILogger
Nazwa kategorii implementacji jest zazwyczaj źródłem rejestrowania. Na przykład typ, w którym jest tworzony rejestrator:
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();
}
}
}
Powyższy kod ma następujące działanie:
- Tworzy wystąpienie rejestratora na nazwę kategorii.
- Zaewidencjonuj
_getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)
elementIsEnabled
, więc każdy z nichlogLevel
ma unikatowy rejestrator. W tej implementacji każdy poziom dziennika wymaga jawnego wpisu konfiguracji do rejestrowania.
Dobrym rozwiązaniem jest wywołanie ILogger.IsEnabled implementacji, ILogger.Log ponieważ Log
może być wywoływane przez dowolnego konsumenta i nie ma żadnych gwarancji, że został on wcześniej sprawdzony. Metoda IsEnabled
powinna być bardzo szybka w większości implementacji.
TState state,
Exception? exception,
Rejestrator jest tworzone wystąpienie elementu name
i Func<ColorConsoleLoggerConfiguration>
, który zwraca bieżącą konfigurację — obsługuje aktualizacje wartości konfiguracji monitorowanych za pośrednictwem wywołania zwrotnego IOptionsMonitor<TOptions>.OnChange .
Ważne
Implementacja ILogger.Log sprawdza, czy wartość jest ustawiona config.EventId
. Jeśli config.EventId
nie jest ustawiona lub gdy jest zgodna z dokładną logEntry.EventId
wartością , rejestrator rejestruje kolor.
Niestandardowy dostawca rejestratora
Obiekt ILoggerProvider
jest odpowiedzialny za tworzenie wystąpień rejestratora. Nie jest konieczne utworzenie wystąpienia rejestratora dla każdej kategorii, ale ma sens w przypadku niektórych rejestratorów, takich jak NLog lub log4net. 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 tworzy pojedyncze wystąpienie ColorConsoleLogger
nazwy kategorii i przechowuje je w pliku ConcurrentDictionary<TKey,TValue>
. IOptionsMonitor<TOptions> Ponadto interfejs jest wymagany do aktualizowania zmian w obiekcie bazowymColorConsoleLoggerConfiguration
.
Aby kontrolować konfigurację programu ColorConsoleLogger
, należy zdefiniować alias u jego dostawcy:
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
Klasa ColorConsoleLoggerProvider
definiuje dwa atrybuty o zakresie klasy:
- UnsupportedOSPlatformAttribute
ColorConsoleLogger
: typ nie jest obsługiwany w elemecie"browser"
. - ProviderAliasAttribute: Sekcje konfiguracji mogą definiować opcje przy użyciu
"ColorConsole"
klucza.
Konfigurację można określić za pomocą dowolnego prawidłowego dostawcy konfiguracji. Rozważ następujący plik appsettings.json :
{
"Logging": {
"ColorConsole": {
"LogLevelToColorMap": {
"Information": "DarkGreen",
"Warning": "Cyan",
"Error": "Red"
}
}
}
}
Spowoduje to skonfigurowanie poziomów dziennika na następujące wartości:
- LogLevel.Information: ConsoleColor.DarkGreen
- LogLevel.Warning: ConsoleColor.Cyan
- LogLevel.Error: ConsoleColor.Red
Poziom Information dziennika jest ustawiony na DarkGreenwartość , która zastępuje wartość domyślną ustawioną ColorConsoleLoggerConfiguration
w obiekcie.
Użycie i rejestracja niestandardowego rejestratora
Zgodnie z konwencją rejestrowanie usług do wstrzykiwania zależności odbywa się w ramach procedury uruchamiania aplikacji. Rejestracja odbywa się w Program
klasie lub może być delegowana do Startup
klasy. W tym przykładzie zarejestrujesz się bezpośrednio z Program.cs.
Aby dodać niestandardowego dostawcę rejestrowania i odpowiadający mu rejestrator, dodaj element ILoggerProvider z ILoggingBuilder elementu HostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>):
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 warning value from appsettings.json of "Cyan"
configuration.LogLevelToColorMap[LogLevel.Warning] = ConsoleColor.DarkCyan;
// Replace warning value from appsettings.json of "Red"
configuration.LogLevelToColorMap[LogLevel.Error] = ConsoleColor.DarkRed;
});
using IHost host = builder.Build();
var 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();
Obiekt ILoggingBuilder
tworzy co najmniej jedno ILogger
wystąpienie. Wystąpienia ILogger
są używane przez platformę do rejestrowania informacji.
Konfiguracja z pliku appsettings.json zastępuje następujące wartości:
Zgodnie z konwencją metody rozszerzeń są ILoggingBuilder
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;
}
}
Uruchomienie tej prostej aplikacji spowoduje renderowanie danych wyjściowych koloru w oknie konsoli, podobnie jak na poniższej ilustracji: