Bagikan melalui


Menerapkan penyedia pengelogan kustom di .NET

Terdapat banyak penyedia layanan pencatatan log tersedia untuk kebutuhan pencatatan log yang umum. Anda mungkin perlu menerapkan ILoggerProvider kustom ketika salah satu penyedia yang tersedia tidak sesuai dengan kebutuhan aplikasi Anda. Dalam artikel ini, Anda akan mempelajari cara menerapkan penyedia pengelogan kustom yang dapat digunakan untuk mewarnai log di konsol.

Nasihat

Contoh kode sumber penyedia pengelogan kustom tersedia di repositori GitHub Docs . Untuk informasi selengkapnya, lihat GitHub: .NET Docs - Console Custom Logging.

Contoh konfigurasi pencatat kustom

Sampel membuat entri konsol warna yang berbeda per tingkat log dan ID peristiwa menggunakan jenis konfigurasi berikut:

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

Kode sebelumnya mengatur tingkat default ke Information, warna ke Green, dan EventId secara implisit 0.

Membuat pencatat kustom

Nama kategori implementasi ILogger biasanya merupakan sumber pengelogan. Misalnya, jenis pencatat yang dibuat:

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

Kode sebelumnya:

  • Membuat instans pencatat per nama kategori.
  • Memeriksa _getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel) di IsEnabled, sehingga setiap logLevel memiliki perekam unik. Dalam implementasi ini, setiap tingkat log memerlukan entri konfigurasi eksplisit untuk dicatat.

Ini adalah praktik yang baik untuk memanggil ILogger.IsEnabled dalam implementasi ILogger.Log karena Log dapat dipanggil oleh konsumen mana pun, dan tidak ada jaminan bahwa itu sebelumnya diperiksa. Metode IsEnabled harus sangat cepat dalam sebagian besar implementasi.

TState state,
Exception? exception,

Logger dibuat dengan name dan Func<ColorConsoleLoggerConfiguration>, yang mengembalikan konfigurasi saat iniā€”ini menangani pembaruan nilai konfigurasi yang dipantau melalui callback IOptionsMonitor<TOptions>.OnChange.

Penting

Implementasi ILogger.Log memeriksa apakah nilai config.EventId ditetapkan. Ketika config.EventId tidak diatur atau ketika sesuai tepat dengan logEntry.EventId, log dicatat dalam warna.

Penyedia pencatat kustom

Objek ILoggerProvider bertanggung jawab untuk membuat instans pencatat. Tidak perlu membuat instans pencatat per kategori, tetapi masuk akal untuk beberapa pencatat, seperti NLog atau log4net. Strategi ini memungkinkan Anda memilih target output pengelogan yang berbeda per kategori, seperti dalam contoh berikut:

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

Dalam kode sebelumnya, CreateLogger membuat satu instans ColorConsoleLogger per nama kategori dan menyimpannya di ConcurrentDictionary<TKey,TValue>. Selain itu, antarmuka IOptionsMonitor<TOptions> diperlukan untuk memperbarui perubahan pada objek ColorConsoleLoggerConfiguration yang mendasar.

Untuk mengontrol konfigurasi ColorConsoleLogger, Anda menentukan alias pada penyedianya:

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

Kelas ColorConsoleLoggerProvider mendefinisikan dua atribut cakupan kelas:

Konfigurasi dapat ditentukan dengan penyedia konfigurasi yang valid . Pertimbangkan file appsettings.json berikut:

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

Ini mengonfigurasi tingkat log ke nilai berikut:

Tingkat log Information diatur ke DarkGreen, yang menggantikan nilai default yang diatur dalam objek ColorConsoleLoggerConfiguration.

Penggunaan dan pendaftaran pencatat kustom

Menurut konvensi, mendaftarkan layanan untuk injeksi dependensi terjadi sebagai bagian dari rutinitas startup aplikasi. Pendaftaran terjadi di kelas Program, atau dapat didelegasikan ke kelas Startup. Dalam contoh ini, Anda akan mendaftar langsung dari Program.cs.

Untuk menambahkan penyedia pengelogan kustom dan pencatat terkait, tambahkan ILoggerProvider dengan ILoggingBuilder dari 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 membuat satu atau beberapa instans ILogger. Instans ILogger digunakan oleh kerangka kerja untuk mencatat informasi.

Konfigurasi dari file appsettings.json mengambil alih nilai berikut:

Menurut konvensi, metode ekstensi pada ILoggingBuilder digunakan untuk mendaftarkan penyedia kustom:

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

Menjalankan aplikasi sederhana ini akan merender output warna ke jendela konsol yang mirip dengan gambar berikut:

contoh hasil keluaran pencatat konsol warna

Lihat juga