Implementace vlastního zprostředkovatele protokolování v .NET
Pro běžné potřeby protokolování je k dispozici mnoho zprostředkovatelů protokolování. Možná budete muset implementovat vlastní ILoggerProvider , pokud některý z dostupných poskytovatelů nevyhovuje potřebám vaší aplikace. V tomto článku se dozvíte, jak implementovat vlastního zprostředkovatele protokolování, který se dá použít k obarvení protokolů v konzole.
Tip
Ukázkový zdrojový kód vlastního zprostředkovatele protokolování je k dispozici v úložišti Docs Na GitHubu. Další informace najdete v tématu GitHub: .NET Docs – Vlastní protokolování konzoly.
Ukázková vlastní konfigurace protokolovacího nástroje
Ukázka vytvoří různé položky barevné konzoly pro každou úroveň protokolu a ID události pomocí následujícího typu konfigurace:
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
};
}
Předchozí kód nastaví výchozí úroveň na Information
, barvu na Green
a EventId
je implicitně 0
.
Vytvoření vlastního protokolovacího nástroje
Název ILogger
kategorie implementace je obvykle zdrojem protokolování. Například typ, ve kterém je protokolovač vytvořen:
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();
}
}
}
Předchozí kód:
- Vytvoří instanci protokolovacího nástroje na název kategorie.
- Vrátí se sem
_getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)
IsEnabled
, takže každýlogLevel
má jedinečný protokolovací nástroj. V této implementaci každá úroveň protokolu vyžaduje explicitní položku konfigurace pro protokol.
Je vhodné volat ILogger.IsEnabled v rámci ILogger.Log implementací, protože Log
je možné volat libovolným příjemcem a neexistují žádné záruky, že byla dříve zkontrolována. Metoda IsEnabled
by měla být ve většině implementací velmi rychlá.
TState state,
Exception? exception,
Protokolovací nástroj se vytvoří instance s name
hodnotou a a , Func<ColorConsoleLoggerConfiguration>
která vrací aktuální konfiguraci – zpracovává aktualizace konfiguračních hodnot monitorovaných prostřednictvím zpětného IOptionsMonitor<TOptions>.OnChange volání.
Důležité
Implementace ILogger.Log zkontroluje, jestli je nastavená config.EventId
hodnota. Pokud config.EventId
není nastavená nebo když odpovídá přesnému logEntry.EventId
, protokolovací nástroj protokoluje barevně.
Vlastní zprostředkovatel protokolovacího nástroje
Objekt ILoggerProvider
je zodpovědný za vytváření instancí protokolovacího nástroje. Není nutné vytvořit instanci protokolovacího nástroje pro každou kategorii, ale dává smysl pro některé protokolovací nástroje, jako je NLog nebo log4net. Tato strategie umožňuje zvolit různé cíle výstupu protokolování pro každou kategorii, jak je znázorněno v následujícím příkladu:
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();
}
}
V předchozím kódu CreateLogger vytvoří jednu instanci ColorConsoleLogger
názvu kategorie a uloží ji do ConcurrentDictionary<TKey,TValue>
. Kromě toho IOptionsMonitor<TOptions> je rozhraní nutné k aktualizaci změn v podkladovém ColorConsoleLoggerConfiguration
objektu.
Chcete-li řídit konfiguraci ColorConsoleLogger
, definujete alias na jeho poskytovateli:
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
Třída ColorConsoleLoggerProvider
definuje dva atributy s oborem třídy:
- UnsupportedOSPlatformAttribute: Typ
ColorConsoleLogger
není v souboru"browser"
. - ProviderAliasAttribute: Oddíly konfigurace mohou definovat možnosti pomocí
"ColorConsole"
klíče.
Konfiguraci je možné zadat u libovolného platného zprostředkovatele konfigurace. Zvažte následující appsettings.json soubor:
{
"Logging": {
"ColorConsole": {
"LogLevelToColorMap": {
"Information": "DarkGreen",
"Warning": "Cyan",
"Error": "Red"
}
}
}
}
Tím se nakonfigurují úrovně protokolu na následující hodnoty:
- LogLevel.Information: ConsoleColor.DarkGreen
- LogLevel.Warning: ConsoleColor.Cyan
- LogLevel.Error: ConsoleColor.Red
Úroveň Information protokolu je nastavena na DarkGreen, která přepíše výchozí hodnotu nastavenou v objektu ColorConsoleLoggerConfiguration
.
Použití a registrace vlastního protokolovacího nástroje
Podle konvence probíhá registrace služeb pro injektáž závislostí jako součást rutiny spouštění aplikace. Registrace probíhá ve Program
třídě nebo může být delegována do Startup
třídy. V tomto příkladu se zaregistrujete přímo z Program.cs.
Chcete-li přidat vlastního zprostředkovatele protokolování a odpovídající protokolovací nástroj, přidejte z ILoggerProviderILoggingBuilder :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();
Vytvoří ILoggingBuilder
jednu nebo více ILogger
instancí. Instance ILogger
jsou používány architekturou k protokolování informací.
Konfigurace ze souboru appsettings.json přepíše následující hodnoty:
Podle konvence se metody ILoggingBuilder
rozšíření používají k registraci vlastního poskytovatele:
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;
}
}
Spuštění této jednoduché aplikace vykreslí barevný výstup do okna konzoly podobně jako na následujícím obrázku: