.NET'te özel günlük sağlayıcısı uygulama

Yaygın günlük gereksinimleri için kullanılabilecek birçok günlük sağlayıcısı vardır. Kullanılabilir sağlayıcılardan biri uygulama gereksinimlerinize uygun olmadığında özel ILoggerProvider bir uygulama yapmanız gerekebilir. Bu makalede, konsoldaki günlükleri renklendirmek için kullanılabilecek bir özel günlük sağlayıcısı uygulamayı öğreneceksiniz.

İpucu

Özel günlük sağlayıcısı örnek kaynak kodu, Docs Github deposunda bulunur. Daha fazla bilgi için bkz . GitHub: .NET Docs - Konsol Özel Günlüğü.

Örnek özel günlükçü yapılandırması

Örnek, aşağıdaki yapılandırma türünü kullanarak günlük düzeyi ve olay kimliği başına farklı renk konsolu girişleri oluşturur:

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

Yukarıdaki kod varsayılan düzeyi Informationolarak ayarlar, renk Greenolarak ve EventId örtük olarak 0şeklindedir.

Özel günlükçü oluşturma

Uygulama ILogger kategorisi adı genellikle günlük kaynağıdır. Örneğin, günlükçü oluşturulduğu tür:

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

Yukarıdaki kod:

  • Kategori adı başına günlükçü örneği oluşturur.
  • her birinin IsEnabledbenzersiz bir günlükçüye sahip olması logLevel için içinde denetimler _getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel) gerçekleştirir. Bu uygulamada, her günlük düzeyinin günlüğe kaydedilmesi için açık bir yapılandırma girişi gerekir.

Herhangi bir tüketici tarafından çağrılabildiğinden ve daha önce denetlendiğinin garantisi olmadığından, uygulamalar Log içinde ILogger.Log çağrı ILogger.IsEnabled yapmak iyi bir uygulamadır. Yöntemin IsEnabled çoğu uygulamada çok hızlı olması gerekir.

TState state,
Exception? exception,

Günlükçü, geçerli yapılandırmayı name döndüren ve Func<ColorConsoleLoggerConfiguration>ile örneği oluşturulur; bu işlem, yapılandırma değerlerine yapılan güncelleştirmeleri geri çağırma aracılığıyla IOptionsMonitor<TOptions>.OnChange izlendiği şekilde işler.

Önemli

Uygulama, ILogger.Log değerin config.EventId ayarlandığını denetler. Ayarlanmadığında config.EventId veya tam logEntry.EventIdile eşleştiğinde günlükçü renkli olarak günlüğe kaydeder.

Özel günlükçü sağlayıcısı

ILoggerProvider nesnesi günlükçü örnekleri oluşturmakla sorumludur. Kategori başına günlükçü örneği oluşturmak gerekli değildir, ancak NLog veya log4net gibi bazı günlükçüler için mantıklıdır. Bu strateji, aşağıdaki örnekte olduğu gibi kategori başına farklı günlük çıkış hedefleri seçmenize olanak tanır:

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

Yukarıdaki kodda, CreateLogger kategori adı başına tek bir örneğini ColorConsoleLogger oluşturur ve içinde ConcurrentDictionary<TKey,TValue>depolar. Ayrıca, temel alınan ColorConsoleLoggerConfiguration nesnedeki IOptionsMonitor<TOptions> değişiklikleri güncelleştirmek için arabirim gereklidir.

yapılandırmasını ColorConsoleLoggerdenetlemek için sağlayıcısında bir diğer ad tanımlarsınız:

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

ColorConsoleLoggerProvider sınıfı iki sınıf kapsamlı özniteliği tanımlar:

Yapılandırma, geçerli herhangi bir yapılandırma sağlayıcısıyla belirtilebilir. Aşağıdaki appsettings.json dosyasını göz önünde bulundurun:

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

Bu, günlük düzeylerini aşağıdaki değerlerle yapılandırılır:

Günlük Information düzeyi olarak ayarlanır DarkGreenve nesnede ColorConsoleLoggerConfiguration ayarlanan varsayılan değeri geçersiz kılar.

Özel günlükçü kullanımı ve kaydı

Kural gereği, bağımlılık ekleme için hizmetlerin kaydedilmesi, bir uygulamanın başlangıç yordamının bir parçası olarak gerçekleşir. Kayıt sınıfında gerçekleşir Program veya bir Startup sınıfa temsilci olarak atanabilir. Bu örnekte doğrudan Program.cs kaydolacaksınız.

Özel günlük sağlayıcısını ve ilgili günlükçü'leri eklemek için öğesinden HostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>)ile ILoggerProviderILoggingBuilder ekleyin:

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

bir ILoggingBuilder veya daha fazla ILogger örnek oluşturur. Örnekler ILogger , bilgileri günlüğe kaydetmek için çerçeve tarafından kullanılır.

appsettings.json dosyasındaki yapılandırma aşağıdaki değerleri geçersiz kılar:

Kural gereği, uzantı ILoggingBuilder yöntemleri özel sağlayıcıyı kaydetmek için kullanılır:

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

Bu basit uygulamanın çalıştırılması, konsol penceresine aşağıdaki görüntüye benzer şekilde renk çıkışı oluşturur:

Color console logger sample output

Ayrıca bkz.