Delen via


Een aangepaste logboekregistratieprovider implementeren in .NET

Er zijn veel providers voor logboekregistratie beschikbaar voor algemene logboekregistratiebehoeften. Mogelijk moet u een aangepaste ILoggerProvider implementatie uitvoeren wanneer een van de beschikbare providers niet aan uw toepassingsbehoeften voldoet. In dit artikel leert u hoe u een aangepaste logboekregistratieprovider implementeert die kan worden gebruikt om logboeken in de console te kleuren.

Tip

De voorbeeldbroncode van de aangepaste logboekregistratieprovider is beschikbaar in de Docs Github-opslagplaats. Zie GitHub: .NET Docs - Aangepaste logboekregistratie van consoles voor meer informatie.

Voorbeeld van aangepaste logboekregistratieconfiguratie

In het voorbeeld worden verschillende vermeldingen in de kleurenconsole per logboekniveau en gebeurtenis-id gemaakt met behulp van het volgende configuratietype:

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
    };
}

De voorgaande code stelt het standaardniveau Informationin op , de kleur op Greenen de EventId is impliciet 0.

De aangepaste logboekregistratie maken

De ILogger naam van de implementatiecategorie is doorgaans de bron voor logboekregistratie. Bijvoorbeeld het type waar de logger wordt gemaakt:

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();
        }
    }
}

Met de voorgaande code wordt:

  • Hiermee maakt u een logboekregistratie-exemplaar per categorienaam.
  • Check in _getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)IsEnabled, dus elk logLevel heeft een unieke logger. In deze implementatie vereist elk logboekniveau een expliciete configuratievermelding voor het logboek.

Het is een goede gewoonte om binnen implementaties aan te roepen ILogger.IsEnabledILogger.Log , omdat Log deze door elke consument kan worden aangeroepen en er geen garanties zijn dat deze eerder is gecontroleerd. De methode moet in de IsEnabled meeste implementaties zeer snel zijn.

TState state,
Exception? exception,

De logger wordt geïnstantieerd met de name en een Func<ColorConsoleLoggerConfiguration>, die de huidige configuratie retourneert. Hiermee worden updates voor de configuratiewaarden verwerkt die via de IOptionsMonitor<TOptions>.OnChange callback worden bewaakt.

Belangrijk

De ILogger.Log implementatie controleert of de config.EventId waarde is ingesteld. Wanneer config.EventId deze niet is ingesteld of overeenkomt met het exacte logEntry.EventId, wordt de logboekregistratie in kleur vastgelegd.

Aangepaste loggerprovider

Het ILoggerProvider object is verantwoordelijk voor het maken van logboekinstanties. Het is niet nodig om een logboekregistratie-exemplaar per categorie te maken, maar het is zinvol voor sommige loggers, zoals NLog of log4net. Met deze strategie kunt u verschillende uitvoerdoelen voor logboekregistratie per categorie kiezen, zoals in het volgende voorbeeld:

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();
    }
}

In de voorgaande code CreateLogger maakt u één exemplaar van de ColorConsoleLogger naam per categorie en slaat u deze op in de ConcurrentDictionary<TKey,TValue>. Daarnaast is de IOptionsMonitor<TOptions> interface vereist om wijzigingen in het onderliggende ColorConsoleLoggerConfiguration object bij te werken.

Als u de configuratie van de ColorConsoleLoggerprovider wilt beheren, definieert u een alias voor de provider:

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

De ColorConsoleLoggerProvider klasse definieert twee kenmerken met klassebereik:

De configuratie kan worden opgegeven met elke geldige configuratieprovider. Houd rekening met het volgende appsettings.json-bestand :

{
    "Logging": {
        "ColorConsole": {
            "LogLevelToColorMap": {
                "Information": "DarkGreen",
                "Warning": "Cyan",
                "Error": "Red"
            }
        }
    }
}

Hiermee configureert u de logboekniveaus op de volgende waarden:

Het Information logboekniveau is ingesteld op DarkGreen, waardoor de standaardwaarde die in het ColorConsoleLoggerConfiguration object is ingesteld, wordt overschreven.

Gebruik en registratie van de aangepaste logboekregistratie

Volgens de conventie vindt het registreren van services voor afhankelijkheidsinjectie plaats als onderdeel van de opstartroutine van een toepassing. De registratie vindt plaats in de Program klasse of kan worden gedelegeerd aan een Startup klasse. In dit voorbeeld registreert u zich rechtstreeks vanuit de Program.cs.

Als u de aangepaste logboekregistratieprovider en de bijbehorende logboekregistratie wilt toevoegen, voegt u een ILoggerProvider met toe vanaf ILoggingBuilder het HostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>)volgende:

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();

Er ILoggingBuilder worden een of meer ILogger exemplaren gemaakt. De ILogger exemplaren worden door het framework gebruikt om de informatie te registreren.

De configuratie van het bestand appsettings.json overschrijft de volgende waarden:

Standaard worden extensiemethoden ILoggingBuilder gebruikt om de aangepaste provider te registreren:

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;
    }
}

Als u deze eenvoudige toepassing uitvoert, wordt de kleuruitvoer weergegeven in het consolevenster, vergelijkbaar met de volgende afbeelding:

Color console logger sample output

Zie ook