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. Kullanılabilir sağlayıcılardan biri uygulama gereksinimlerinize uygun olmadığında özel bir ILoggerProvider uygulamanız gerekebilir. Bu makalede, konsoldaki günlükleri renklendirmek için kullanılabilecek bir özel günlük sağlayıcısı uygulamayı öğreneceksiniz.

Bahşiş

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

Ö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 ayarlanır ve EventId örtük olarak 0.

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

ILogger uygulama kategori adı genellikle günlük kaynağıdır. Örneğin, kaydedicinin 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();
        }
    }
}

Önceki kod:

  • Her kategori adı için bir kayıt tutucu nesnesi oluşturur.
  • _getCurrentConfig().LogLevelToColorMap.ContainsKey(logLevel), her logLevel'nin benzersiz bir günlükçüye sahip olması için IsEnabled'i denetler. Bu uygulamada, her günlük düzeyinin günlüğe kaydedilmesi için açık bir yapılandırma girişi gerekir.

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

TState state,
Exception? exception,

Kayıt tutucu, name ve geçerli yapılandırmayı döndüren bir Func<ColorConsoleLoggerConfiguration>ile oluşturulur; bu, yapılandırma değerlerindeki güncelleştirmeleri IOptionsMonitor<TOptions>.OnChange geri çağırma mekanizması aracılığıyla izleyerek işler.

Ö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 kategori adı başına ColorConsoleLogger tek bir örneğini oluşturur ve ConcurrentDictionary<TKey,TValue>içinde depolar. Ayrıca, temel alınan ColorConsoleLoggerConfiguration nesnesine yapılan değişiklikleri güncelleştirmek için IOptionsMonitor<TOptions> arabirimi gerekir.

ColorConsoleLoggeryapılandırmasını kontrol etmek için sağlayıcısında bir takma 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, 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"
            }
        }
    }
}

Günlük düzeyleri aşağıdaki değerlerle yapılandırır:

Information günlük düzeyi, ColorConsoleLoggerConfiguration nesnesinde ayarlanan varsayılan değeri geçersiz kılan DarkGreenolarak ayarlanır.

Ö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 Program sınıfında gerçekleşir veya bir Startup sınıfına yetkilendirilebilir. Bu örnekte, doğrudan Program.cs'den kaydolacaksınız.

Özel günlük sağlayıcısını ve ilgili günlükçüleri eklemek için, HostingHostBuilderExtensions.ConfigureLogging(IHostBuilder, Action<ILoggingBuilder>)'den ILoggingBuilder'i içeren 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 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 bir veya daha fazla ILogger örneği oluşturur. ILogger örnekleri, bilgileri günlüklemek için altyapı tarafından kullanılır.

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

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

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

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

Ayrıca bkz.