Share via


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 Greenoch 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) in IsEnabled, så var och logLevel 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.EventIdloggar 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 ColorConsoleLoggerav definierar du ett alias på providern:

[UnsupportedOSPlatform("browser")]
[ProviderAlias("ColorConsole")]
public sealed class ColorConsoleLoggerProvider : ILoggerProvider

Klassen ColorConsoleLoggerProvider definierar två attribut med klassomfattning:

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:

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:

Color console logger sample output

Se även