Aracılığıyla paylaş


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

Yaygın günlük gereksinimleri için birçok günlük sağlayıcısı vardır. Ancak, 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.

Tavsiye

Özel günlük sağlayıcısı örnek kaynak kodu , docs GitHub deposunda bulunur.

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

Örnek günlükçü, 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
    };
}

Önceki kod, Information düzeyi için varsayılan rengi Green olarak ayarlar. EventId örtük olarak 0'dır.

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

Aşağıdaki kod parçacığı ILogger'in uygulanmasını göstermektedir:

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

Her kayıtçı örneği, genellikle kayıtçının oluşturulduğu tip olan bir kategori adı geçirilerek oluşturulur. IsEnabled yöntemi, istenen günlük düzeyinin etkinleştirilip etkinleştirilmediğini anlamak için getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel)’i ve yapılandırmanın günlük düzeyleri sözlüğünü kontrol eder.

ILogger.IsEnabled herhangi bir tüketici tarafından çağrılabildiğinden ve daha önce denetlendiğinin garantisi olmadığından ILogger.Log uygulamalar içinde Log çağırmak iyi bir uygulamadır. IsEnabled yöntemi çoğu uygulamada çok hızlı olmalıdır.

if (!IsEnabled(logLevel))
{
    return;
}

Kayıt cihazı, name ve geçerli yapılandırmayı döndüren bir Func<ColorConsoleLoggerConfiguration> ile örneklenir.

Önemli

ILogger.Log uygulaması, config.EventId değerinin ayarlandığını denetler. config.EventId ayarlanmadığında veya tam logEntry.EventIdile eşleştiğinde, kayıt cihazı renkli olarak kaydeder.

Özel kayıt tutucu sağlayıcısı

ILoggerProvider nesnesi logger ö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();
    }
}

Önceki kodda, CreateLogger(String) kategori adı başına ColorConsoleLogger tek bir örneğini oluşturur ve ConcurrentDictionary<TKey,TValue>içinde depolar.

ColorConsoleLoggerProvider sınıfı iki öznitelikle dekore edilmiştir:

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

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

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

appsettings.json dosyası, günlük düzeyinin renginin, ColorConsoleLoggerConfiguration nesnesinde ayarlanan varsayılan değeri geçersiz kılan DarkGreen olduğunu belirtir.

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

Kural gereği, hizmetler bir uygulamanın başlangıç yordamının bir parçası olarak bağımlılık ekleme için kaydedilir. Bu örnekte loglama servisi doğrudan Program.cs dosyasından kayıt edilir.

Özel günlük sağlayıcısını ve karşılık gelen logger'ları eklemek için, IHostApplicationBuilder.Logging özelliğindeki ILoggingBuilder üzerinde bir özel uzantı yöntemi olan AddColorConsoleLogger çağrısını yaparak bir ILoggerProvider 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 value of "Cyan" from appsettings.json.
    configuration.LogLevelToColorMap[LogLevel.Warning]
        = ConsoleColor.DarkCyan;
    // Replace value of "Red" from appsettings.json.
    configuration.LogLevelToColorMap[LogLevel.Error]
        = ConsoleColor.DarkRed;
});

using IHost host = builder.Build();

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

Kural gereği, özel sağlayıcıyı kaydetmek için ILoggingBuilder uzantı yöntemleri 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;
    }
}

ILoggingBuilder bir veya daha fazla ILogger örneği oluşturur. ILogger örnekleri, bilgileri günlüklemek için altyapı tarafından kullanılır.

Örnek oluşturma kodu, appsettings.json dosyasından LogLevel.Warning ve LogLevel.Error için renk değerlerini geçersiz kılar.

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

Renkli konsol kayıt tutucu örnek çıktısı

Ayrıca bakınız