Megosztás a következőn keresztül:


Egyéni naplózási szolgáltató implementálása a .NET-ben

Számos naplózási szolgáltató érhető el a gyakori naplózási igényekhez. Előfordulhat, hogy egyéni ILoggerProvider kell implementálnia, ha az egyik elérhető szolgáltató nem felel meg az alkalmazás igényeinek. Ebből a cikkből megtudhatja, hogyan valósíthat meg egyéni naplózási szolgáltatót, amely a konzol naplóinak színezésére használható.

Borravaló

Az egyéni naplózási szolgáltató példaforráskódja a Docs GitHub-adattár érhető el. További információkért lásd: GitHub: .NET Docs – Console Custom Logging.

Minta egyéni naplózó konfigurációja

A minta naplószintenként és eseményazonosítónként különböző színkonzol-bejegyzéseket hoz létre a következő konfigurációtípus használatával:

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

Az előző kód az alapértelmezett szintet Information-ra, a színt Green-re, és a EventId-t implicit módon 0-ra állítja.

Az egyéni naplózó létrehozása

A ILogger megvalósítás kategória neve általában a naplózási forrásként jelenik meg. Például a naplózó létrehozásának típusa:

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

Az előző kód:

  • Létrehoz egy naplózópéldányt minden kategórianévhez.
  • Ellenőrzi _getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)-IsEnabled, így minden logLevel-nek egyedi naplózója van. Ebben az implementációban minden naplószinthez explicit konfigurációs bejegyzés szükséges a naplózáshoz.

Ajánlott a ILogger.IsEnabled-t a ILogger.Log implementációkon belül meghívni, mivel Log-t bármely fogyasztó is meghívhatja, és nincs garancia arra, hogy korábban ellenőrizték. A IsEnabled módszernek nagyon gyorsnak kell lennie a legtöbb implementációban.

TState state,
Exception? exception,

A naplózót létrehozzák a name és egy Func<ColorConsoleLoggerConfiguration>segítségével, amely visszaadja az aktuális konfigurációt – ez a IOptionsMonitor<TOptions>.OnChange visszahíváson keresztül figyelemmel kísérve kezeli a konfigurációs értékek frissítéseit.

Fontos

A ILogger.Log implementáció ellenőrzi, hogy a config.EventId érték be van-e állítva. Ha a config.EventId nincs beállítva, vagy ha a config.EventId pontosan megegyezik a(z) logEntry.EventId-nel, akkor a naplózó színesen rögzít.

Egyéni naplózási szolgáltató

A ILoggerProvider objektum felelős a naplózópéldányok létrehozásáért. Nem szükséges kategóriánként létrehozni egy naplózópéldányt, de van értelme néhány naplózónak, például az NLognak vagy a log4netnek. Ez a stratégia lehetővé teszi, hogy kategóriánként különböző naplózási kimeneti célokat válasszon, ahogyan az alábbi példában is látható:

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

Az előző kódban a CreateLogger minden kategórianévhez egyetlen példányt hoz létre a ColorConsoleLogger-ből, és azt a ConcurrentDictionary<TKey,TValue>tárolja. Emellett a IOptionsMonitor<TOptions> felületre is szükség van a mögöttes ColorConsoleLoggerConfiguration objektum módosításainak frissítéséhez.

A ColorConsoleLoggerkonfigurációjának szabályozásához definiáljon egy aliast a szolgáltatójánál:

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

A ColorConsoleLoggerProvider osztály két osztályhatókörű attribútumot határoz meg:

A konfiguráció bármely érvényes konfigurációszolgáltatóvaladható meg. Vegye figyelembe a következő appsettings.json fájlt:

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

Ez a naplószinteket a következő értékekre konfigurálja:

A Information naplószint DarkGreenértékre van állítva, amely felülírja a ColorConsoleLoggerConfiguration objektumban beállított alapértelmezett értéket.

Az egyéni naplózó használata és regisztrálása

A függőséginjektálási szolgáltatások regisztrálása konvenció szerint az alkalmazás indítási rutinjának részeként történik. A regisztráció az Program osztályban történik, vagy delegálható egy Startup osztályba. Ebben a példában közvetlenül a Program.csfog regisztrálni.

Az egyéni naplózási szolgáltató és naplózó hozzáadásához illessze be a ILoggerProviderILoggingBuilder-t a HostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>)-be:

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

A ILoggingBuilder létrehoz egy vagy több ILogger példányt. A keretrendszer a ILogger-példányokat használja az adatok naplózásához.

A appsettings.json fájl konfigurációja felülbírálja a következő értékeket:

A konvenció szerint a kiterjesztési metódusokkal a ILoggingBuilder-on regisztrálják az egyéni szolgáltatót.

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

Az egyszerű alkalmazás futtatása a következő képhez hasonló színkimenetet jelenít meg a konzolablakban:

Színes konzol naplózó mintakimenet

Lásd még: