Implementera en anpassad loggningsprovider i .NET
Det finns många tillgängliga loggningsproviders för vanliga loggningsbehov. Du kan behöva implementera en anpassad ILoggerProvider när en av de tillgängliga leverantörerna inte passar dina programbehov. I den här artikeln får du lära dig hur du implementerar en anpassad loggningsprovider som kan användas för att färglägga loggar i konsolen.
Dricks
Exempelkällkoden för den anpassade loggningsprovidern finns på Docs Github-lagringsplatsen. Mer information finns i GitHub: .NET Docs – Konsol anpassad loggning.
Exempel på anpassad loggningskonfiguration
Exemplet skapar olika färgkonsolposter per loggnivå och händelse-ID med hjälp av följande konfigurationstyp:
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
};
}
Föregående kod anger standardnivån till Information
, färgen till Green
och EventId
är implicit 0
.
Skapa den anpassade loggaren
Namnet ILogger
på implementeringskategorin är vanligtvis loggningskällan. Till exempel typen där loggaren skapas:
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();
}
}
}
Koden ovan:
- Skapar en loggerinstans per kategorinamn.
- Checkar
_getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)
inIsEnabled
, så var ochlogLevel
en har en unik loggare. I den här implementeringen kräver varje loggnivå en explicit konfigurationspost för att logga.
Det är en bra idé att anropa ILogger.IsEnabled inom ILogger.Log implementeringar eftersom Log
kan anropas av alla konsumenter och det finns inga garantier för att det har kontrollerats tidigare. Metoden IsEnabled
bör vara mycket snabb i de flesta implementeringar.
TState state,
Exception? exception,
Loggern instansieras med name
och , Func<ColorConsoleLoggerConfiguration>
som returnerar den aktuella konfigurationen – detta hanterar uppdateringar av konfigurationsvärdena som övervakas via återanropet IOptionsMonitor<TOptions>.OnChange .
Viktigt!
Implementeringen ILogger.Log kontrollerar om värdet config.EventId
har angetts. När config.EventId
inte har angetts eller när det matchar den exakta logEntry.EventId
loggar loggaren i färg.
Anpassad loggningsprovider
Objektet ILoggerProvider
ansvarar för att skapa loggningsinstanser. Det är inte nödvändigt att skapa en loggningsinstans per kategori, men det är bra för vissa loggare, till exempel NLog eller log4net. Med den här strategin kan du välja olika utdatamål för loggning per kategori, som i följande exempel:
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();
}
}
I föregående kod CreateLogger skapar du en enda instans av ColorConsoleLogger
namnet per kategori och lagrar den i ConcurrentDictionary<TKey,TValue>
. Dessutom krävs gränssnittet IOptionsMonitor<TOptions> för att uppdatera ändringar i det underliggande ColorConsoleLoggerConfiguration
objektet.
Om du vill styra konfigurationen ColorConsoleLogger
av definierar du ett alias på providern:
[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider
Klassen ColorConsoleLoggerProvider
definierar två attribut med klassomfattning:
- UnsupportedOSPlatformAttribute: Typen
ColorConsoleLogger
stöds inte i"browser"
. - ProviderAliasAttribute: Konfigurationsavsnitt kan definiera alternativ med hjälp av
"ColorConsole"
nyckeln.
Konfigurationen kan anges med valfri giltig konfigurationsprovider. Överväg följande appsettings.json fil:
{
"Logging": {
"ColorConsole": {
"LogLevelToColorMap": {
"Information": "DarkGreen",
"Warning": "Cyan",
"Error": "Red"
}
}
}
}
Detta konfigurerar loggnivåerna till följande värden:
- LogLevel.Information: ConsoleColor.DarkGreen
- LogLevel.Warning: ConsoleColor.Cyan
- LogLevel.Error: ConsoleColor.Red
Loggnivån Information är inställd på DarkGreen, vilket åsidosätter standardvärdet som angetts i ColorConsoleLoggerConfiguration
objektet.
Användning och registrering av den anpassade loggaren
Enligt konventionen sker registrering av tjänster för beroendeinmatning som en del av startrutinen för ett program. Registreringen sker i Program
klassen eller kan delegeras till en Startup
klass. I det här exemplet registrerar du dig direkt från Program.cs.
Om du vill lägga till den anpassade loggningsprovidern och motsvarande loggning lägger du till en ILoggerProvider med ILoggingBuilder från 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();
ILoggingBuilder
Skapar en eller flera ILogger
instanser. Instanserna ILogger
används av ramverket för att logga informationen.
Konfigurationen från appsettings.json-filen åsidosätter följande värden:
Enligt konventionen används tilläggsmetoder på ILoggingBuilder
för att registrera den anpassade providern:
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;
}
}
Om du kör det här enkla programmet återges färgutdata till konsolfönstret som liknar följande bild: