Konsol günlük biçimlendirme

.NET 5'te, ad alanında Microsoft.Extensions.Logging.Console konsol günlüklerine özel biçimlendirme desteği eklendi. Önceden tanımlanmış üç biçimlendirme seçeneği vardır: Simple, Systemd, ve Json.

Önemli

Daha önce, ConsoleLoggerFormat istenen günlük biçimini seçmek için izin verilen sabit listesi( okunabilir olan , Defaultveya olarak Systemdda bilinen tek satır). Ancak, bunlar özelleştirilebilir değildi ve artık kullanım dışı bırakıldı.

Bu makalede konsol günlüğü biçimlendiricileri hakkında bilgi edinacaksınız. Örnek kaynak kodu aşağıdakilerin nasıl yapılacağını gösterir:

İpucu

Günlük örneği kaynak kodunun tümü, indirilebilmeniz için Samples Browser'da bulunur. Daha fazla bilgi için bkz . Kod örneklerine göz atma: .NET'te günlüğe kaydetme.

Kayıt biçimlendiricisi

Günlük Console sağlayıcısı önceden tanımlanmış birkaç biçimlendiriciye sahiptir ve kendi özel biçimlendiricinizi yazma özelliğini kullanıma sunar. Kullanılabilir biçimlendiricilerden herhangi birini kaydetmek için ilgili Add{Type}Console uzantı yöntemini kullanın:

Kullanılabilir türler Tür kaydetme yöntemi
ConsoleFormatterNames.Json ConsoleLoggerExtensions.AddJsonConsole
ConsoleFormatterNames.Simple ConsoleLoggerExtensions.AddSimpleConsole
ConsoleFormatterNames.Systemd ConsoleLoggerExtensions.AddSystemdConsole

Basit

Konsol biçimlendiricisini Simple kullanmak için ile AddSimpleConsolekaydedin:

using Microsoft.Extensions.Logging;

using ILoggerFactory loggerFactory =
    LoggerFactory.Create(builder =>
        builder.AddSimpleConsole(options =>
        {
            options.IncludeScopes = true;
            options.SingleLine = true;
            options.TimestampFormat = "HH:mm:ss ";
        }));

ILogger<Program> logger = loggerFactory.CreateLogger<Program>();
using (logger.BeginScope("[scope is enabled]"))
{
    logger.LogInformation("Hello World!");
    logger.LogInformation("Logs contain timestamp and log level.");
    logger.LogInformation("Each log message is fit in a single line.");
}

Yukarıdaki örnek kaynak kodunda ConsoleFormatterNames.Simple biçimlendirici kaydedildi. Günlüklere yalnızca her günlük iletisinde zaman ve günlük düzeyi gibi bilgileri sarmalama olanağı sağlamanın yanı sıra, ANSI renk ekleme ve iletilerin girintilenmesine de olanak tanır.

Bu örnek uygulama çalıştırıldığında, günlük iletileri aşağıda gösterildiği gibi biçimlendirilir:

Basit biçimlendiriciyle yazılmış örnek konsol günlükleri.

Sistemli

Konsol ConsoleFormatterNames.Systemd günlükçü:

  • "Syslog" günlük düzeyi biçimini ve önem derecelerini kullanır
  • İletileri renklerle biçimlendirmez
  • İletileri her zaman tek satırda günlüğe kaydeder

Bu genellikle konsol günlüğünü kullanan kapsayıcılar Systemd için yararlıdır. .NET 5 ile konsol Simple günlükçüsü aynı zamanda tek bir satırda oturum açan kompakt bir sürüm sağlar ve önceki örnekte gösterildiği gibi renklerin devre dışı bırakılmasına da olanak tanır.

using Microsoft.Extensions.Logging;

using ILoggerFactory loggerFactory =
    LoggerFactory.Create(builder =>
        builder.AddSystemdConsole(options =>
        {
            options.IncludeScopes = true;
            options.TimestampFormat = "HH:mm:ss ";
        }));

ILogger<Program> logger = loggerFactory.CreateLogger<Program>();
using (logger.BeginScope("[scope is enabled]"))
{
    logger.LogInformation("Hello World!");
    logger.LogInformation("Logs contain timestamp and log level.");
    logger.LogInformation("Systemd console logs never provide color options.");
    logger.LogInformation("Systemd console logs always appear in a single line.");
}

Örnek, aşağıdaki günlük iletilerine benzer bir çıkış oluşturur:

Systemd biçimlendiricisi ile yazılmış örnek konsol günlükleri.

Json

Günlükleri JSON biçiminde Json yazmak için konsol biçimlendiricisi kullanılır. Örnek kaynak kodu, bir ASP.NET Core uygulamasının bunu nasıl kaydedebileceğini gösterir. webapp Şablonu kullanarak dotnet new komutuyla yeni bir ASP.NET Core uygulaması oluşturun:

dotnet new webapp -o Console.ExampleFormatters.Json

Uygulamayı çalıştırırken şablon kodunu kullanarak aşağıdaki varsayılan günlük biçimini alırsınız:

info: Console.ExampleFormatters.Json.Startup[0]
      Hello .NET friends!
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: .\snippets\logging\console-formatter-json

Varsayılan olarak, Simple konsol günlüğü biçimlendiricisi varsayılan yapılandırmayla seçilir. bunu Program.cs arayarak AddJsonConsoledeğiştirirsiniz:

using System.Text.Json;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Logging.AddJsonConsole(options =>
{
    options.IncludeScopes = false;
    options.TimestampFormat = "HH:mm:ss ";
    options.JsonWriterOptions = new JsonWriterOptions
    {
        Indented = true
    };
});

using IHost host = builder.Build();

var logger =
    host.Services
        .GetRequiredService<ILoggerFactory>()
        .CreateLogger<Program>();

logger.LogInformation("Hello .NET friends!");

await host.RunAsync();

Alternatif olarak, bunu appsettings.json dosyasında bulunan gibi günlük yapılandırmasını kullanarak da yapılandırabilirsiniz:

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        },
        "Console": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft": "Warning",
                "Microsoft.Hosting.Lifetime": "Information"
            },
            "FormatterName": "json",
            "FormatterOptions": {
                "SingleLine": true,
                "IncludeScopes": true,
                "TimestampFormat": "HH:mm:ss ",
                "UseUtcTimestamp": true,
                "JsonWriterOptions": {
                    "Indented": true
                }
            }
        }
    },
    "AllowedHosts": "*"
}

Yukarıdaki değişiklikle uygulamayı yeniden çalıştırın, günlük iletisi artık JSON olarak biçimlendirilir:

{
  "Timestamp": "02:28:19 ",
  "EventId": 0,
  "LogLevel": "Information",
  "Category": "Console.ExampleFormatters.Json.Startup",
  "Message": "Hello .NET friends!",
  "State": {
    "Message": "Hello .NET friends!",
    "{OriginalFormat}": "Hello .NET friends!"
  }
}
{
  "Timestamp": "02:28:21 ",
  "EventId": 14,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Now listening on: https://localhost:5001",
  "State": {
    "Message": "Now listening on: https://localhost:5001",
    "address": "https://localhost:5001",
    "{OriginalFormat}": "Now listening on: {address}"
  }
}
{
  "Timestamp": "02:28:21 ",
  "EventId": 14,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Now listening on: http://localhost:5000",
  "State": {
    "Message": "Now listening on: http://localhost:5000",
    "address": "http://localhost:5000",
    "{OriginalFormat}": "Now listening on: {address}"
  }
}
{
  "Timestamp": "02:28:21 ",
  "EventId": 0,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Application started. Press Ctrl\u002BC to shut down.",
  "State": {
    "Message": "Application started. Press Ctrl\u002BC to shut down.",
    "{OriginalFormat}": "Application started. Press Ctrl\u002BC to shut down."
  }
}
{
  "Timestamp": "02:28:21 ",
  "EventId": 0,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Hosting environment: Development",
  "State": {
    "Message": "Hosting environment: Development",
    "envName": "Development",
    "{OriginalFormat}": "Hosting environment: {envName}"
  }
}
{
  "Timestamp": "02:28:21 ",
  "EventId": 0,
  "LogLevel": "Information",
  "Category": "Microsoft.Hosting.Lifetime",
  "Message": "Content root path: .\\snippets\\logging\\console-formatter-json",
  "State": {
    "Message": "Content root path: .\\snippets\\logging\\console-formatter-json",
    "contentRoot": ".\\snippets\\logging\\console-formatter-json",
    "{OriginalFormat}": "Content root path: {contentRoot}"
  }
}

İpucu

Json Konsol biçimlendiricisi varsayılan olarak her iletiyi tek bir satırda günlüğe kaydeder. Biçimlendiriciyi yapılandırırken daha okunabilir hale getirmek için olarak ayarlayın JsonWriterOptions.Indentedtrue.

Dikkat

Json konsol biçimlendiricisini kullanırken, JSON olarak serileştirilmiş günlük iletilerini geçirmeyin. Günlük altyapısı günlük iletilerinin seri hale getirilmesini zaten yönetir, dolayısıyla zaten serileştirilmiş bir günlük iletisi geçirecekseniz, çift seri hale getirilir ve bu da hatalı biçimlendirilmiş çıkışa neden olur.

Yapılandırma ile biçimlendirici ayarlama

Önceki örneklerde bir biçimlendiricinin program aracılığıyla nasıl kaydedilecekleri gösterilmiştir. Alternatif olarak, bu yapılandırma ile yapılabilir. Önceki web uygulaması örnek kaynak kodunu göz önünde bulundurun; Program.cs dosyasında çağırmak yerine appsettings.json dosyasını güncelleştirirseniz aynı sonucu elde edebilirsiniz.ConfigureLogging Güncelleştirilmiş appsettings.json dosya biçimlendiriciyi aşağıdaki gibi yapılandıracak:

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        },
        "Console": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft": "Warning",
                "Microsoft.Hosting.Lifetime": "Information"
            },
            "FormatterName": "json",
            "FormatterOptions": {
                "SingleLine": true,
                "IncludeScopes": true,
                "TimestampFormat": "HH:mm:ss ",
                "UseUtcTimestamp": true,
                "JsonWriterOptions": {
                    "Indented": true
                }
            }
        }
    },
    "AllowedHosts": "*"
}

Ayarlanması gereken iki anahtar değeri ve "FormatterOptions"şeklindedir"FormatterName". değeri ayarlanmış "FormatterName" bir biçimlendirici zaten kayıtlıysa, bu biçimlendirici seçilir ve düğüm içinde "FormatterOptions" anahtar olarak sağlandığı sürece özellikleri yapılandırılabilir. Önceden tanımlanmış biçimlendirici adları altında ConsoleFormatterNamesayrılmıştır:

Özel biçimlendirici uygulama

Özel bir biçimlendirici uygulamak için şunları yapmanız gerekir:

Bunu sizin için işlemek için bir uzantı yöntemi oluşturun:

using Microsoft.Extensions.Logging;

namespace Console.ExampleFormatters.Custom;

public static class ConsoleLoggerExtensions
{
    public static ILoggingBuilder AddCustomFormatter(
        this ILoggingBuilder builder,
        Action<CustomOptions> configure) =>
        builder.AddConsole(options => options.FormatterName = "customName")
            .AddConsoleFormatter<CustomFormatter, CustomOptions>(configure);
}

CustomOptions aşağıdaki gibi tanımlanır:

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.Custom;

public sealed class CustomOptions : ConsoleFormatterOptions
{
    public string? CustomPrefix { get; set; }
}

Önceki kodda, seçenekler bir alt sınıfıdır ConsoleFormatterOptions.

The AddConsoleFormatter API:

  • Alt sınıfını kaydeder ConsoleFormatter
  • Yapılandırmayı işler:
    • Seçenekler desenine ve IOptionsMonitor arabirimine göre güncelleştirmeleri eşitlemek için değişiklik belirteci kullanır
using Console.ExampleFormatters.Custom;
using Microsoft.Extensions.Logging;

using ILoggerFactory loggerFactory =
    LoggerFactory.Create(builder =>
        builder.AddCustomFormatter(options =>
            options.CustomPrefix = " ~~~~~ "));

ILogger<Program> logger = loggerFactory.CreateLogger<Program>();
using (logger.BeginScope("TODO: Add logic to enable scopes"))
{
    logger.LogInformation("Hello World!");
    logger.LogInformation("TODO: Add logic to enable timestamp and log level info.");
}

CustomFormatter alt sınıfını ConsoleFormattertanımlayın:

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Options;

namespace Console.ExampleFormatters.Custom;

public sealed class CustomFormatter : ConsoleFormatter, IDisposable
{
    private readonly IDisposable? _optionsReloadToken;
    private CustomOptions _formatterOptions;

    public CustomFormatter(IOptionsMonitor<CustomOptions> options)
        // Case insensitive
        : base("customName") =>
        (_optionsReloadToken, _formatterOptions) =
            (options.OnChange(ReloadLoggerOptions), options.CurrentValue);

    private void ReloadLoggerOptions(CustomOptions options) =>
        _formatterOptions = options;

    public override void Write<TState>(
        in LogEntry<TState> logEntry,
        IExternalScopeProvider? scopeProvider,
        TextWriter textWriter)
    {
        string? message =
            logEntry.Formatter?.Invoke(
                logEntry.State, logEntry.Exception);

        if (message is null)
        {
            return;
        }

        CustomLogicGoesHere(textWriter);
        textWriter.WriteLine(message);
    }

    private void CustomLogicGoesHere(TextWriter textWriter)
    {
        textWriter.Write(_formatterOptions.CustomPrefix);
    }

    public void Dispose() => _optionsReloadToken?.Dispose();
}

Yukarıdaki CustomFormatter.Write<TState> API, her günlük iletisinin çevresinde hangi metnin kaydırıldığını belirler. Bir standart ConsoleFormatter , günlüklerin kapsamları, zaman damgaları ve önem derecesi düzeyini en düşük düzeyde kaydırabilmelidir. Ayrıca, günlük iletilerinde ANSI renklerini kodlayabilir ve istediğiniz girintileri de sağlayabilirsiniz. uygulamasının CustomFormatter.Write<TState> uygulanması bu özelliklere sahip değil.

Biçimlendirmeyi daha fazla özelleştirme konusunda ilham almak için ad alanında Microsoft.Extensions.Logging.Console mevcut uygulamalara bakın:

Özel yapılandırma seçenekleri

Günlük genişletilebilirliğini daha fazla özelleştirmek için türetilmiş ConsoleFormatterOptions sınıfınız herhangi bir yapılandırma sağlayıcısından yapılandırılabilir. Örneğin, özel seçeneklerinizi tanımlamak için JSON yapılandırma sağlayıcısını kullanabilirsiniz. Önce alt sınıfınızı ConsoleFormatterOptions tanımlayın.

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.CustomWithConfig;

public sealed class CustomWrappingConsoleFormatterOptions : ConsoleFormatterOptions
{
    public string? CustomPrefix { get; set; }

    public string? CustomSuffix { get; set; }
}

Yukarıdaki konsol biçimlendirici seçenekleri sınıfı, ön ek ve son eki temsil eden iki özel özellik tanımlar. Ardından, konsol biçimlendirici seçeneklerinizi yapılandıracak appsettings.json dosyasını tanımlayın.

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        },
        "Console": {
            "LogLevel": {
                "Default": "Information",
                "Microsoft": "Warning",
                "Microsoft.Hosting.Lifetime": "Information"
            },
            "FormatterName": "CustomTimePrefixingFormatter",
            "FormatterOptions": {
                "CustomPrefix": "|-<[",
                "CustomSuffix": "]>-|",
                "SingleLine": true,
                "IncludeScopes": true,
                "TimestampFormat": "HH:mm:ss.ffff ",
                "UseUtcTimestamp": true,
                "JsonWriterOptions": {
                    "Indented": true
                }
            }
        }
    },
    "AllowedHosts": "*"
}

Yukarıdaki JSON yapılandırma dosyasında:

  • Düğüm "Logging" bir "Console"tanımlar.
  • Düğüm, "Console" bir özel biçimlendiriciyle eşlenen öğesini belirtir "FormatterName""CustomTimePrefixingFormatter".
  • Düğüm "FormatterOptions" , bir "CustomPrefix"ve "CustomSuffix"öğesinin yanı sıra diğer türetilmiş birkaç seçeneği tanımlar.

İpucu

$.Logging.Console.FormatterOptions JSON yolu ayrılmıştır ve uzantı yöntemi kullanılarak eklendiğinde özel ConsoleFormatterOptions bir yol ile AddConsoleFormatter eşlenir. Bu, kullanılabilir özelliklere ek olarak özel özellikleri tanımlama olanağı sağlar.

Aşağıdakileri CustomDatePrefixingFormattergöz önünde bulundurun:

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Options;

namespace Console.ExampleFormatters.CustomWithConfig;

public sealed class CustomTimePrefixingFormatter : ConsoleFormatter, IDisposable
{
    private readonly IDisposable? _optionsReloadToken;
    private CustomWrappingConsoleFormatterOptions _formatterOptions;

    public CustomTimePrefixingFormatter(
        IOptionsMonitor<CustomWrappingConsoleFormatterOptions> options)
        // Case insensitive
        : base(nameof(CustomTimePrefixingFormatter))
    {
        _optionsReloadToken = options.OnChange(ReloadLoggerOptions);
        _formatterOptions = options.CurrentValue;
    }

    private void ReloadLoggerOptions(CustomWrappingConsoleFormatterOptions options) =>
        _formatterOptions = options;

    public override void Write<TState>(
        in LogEntry<TState> logEntry,
        IExternalScopeProvider? scopeProvider,
        TextWriter textWriter)
    {
        string message =
            logEntry.Formatter(
                logEntry.State, logEntry.Exception);

        if (message == null)
        {
            return;
        }

        WritePrefix(textWriter);
        textWriter.Write(message);
        WriteSuffix(textWriter);
    }

    private void WritePrefix(TextWriter textWriter)
    {
        DateTime now = _formatterOptions.UseUtcTimestamp
            ? DateTime.UtcNow
            : DateTime.Now;

        textWriter.Write($"""
            {_formatterOptions.CustomPrefix} {now.ToString(_formatterOptions.TimestampFormat)}
            """);
    }

    private void WriteSuffix(TextWriter textWriter) =>
        textWriter.WriteLine($" {_formatterOptions.CustomSuffix}");

    public void Dispose() => _optionsReloadToken?.Dispose();
}

Yukarıdaki biçimlendirici uygulamasında:

Özel yapılandırma seçeneklerini kullanmak için, özel biçimlendirici uygulamalarıyla çağrısı ConfigureLogging(IHostBuilder, Action<HostBuilderContext,ILoggingBuilder>)yaparken ekleyin.

using Console.ExampleFormatters.CustomWithConfig;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Logging.AddConsole()
    .AddConsoleFormatter<
        CustomTimePrefixingFormatter, CustomWrappingConsoleFormatterOptions>();

using IHost host = builder.Build();

ILoggerFactory loggerFactory = host.Services.GetRequiredService<ILoggerFactory>();
ILogger<Program> logger = loggerFactory.CreateLogger<Program>();

using (logger.BeginScope("Logging scope"))
{
    logger.LogInformation("Hello World!");
    logger.LogInformation("The .NET developer community happily welcomes you.");
}

Aşağıdaki konsol çıktısı, bunu CustomTimePrefixingFormatterkullanmaktan görmeyi bekleyebileceğinize benzer.

|-<[ 15:03:15.6179 Hello World! ]>-|
|-<[ 15:03:15.6347 The .NET developer community happily welcomes you. ]>-|

Özel renk biçimlendirmesi uygulama

Özel günlük biçimlendiricinizde renk özelliklerini düzgün bir şekilde etkinleştirmek için, günlüklerdeki renkleri etkinleştirmek için yararlı olabilecek bir SimpleConsoleFormatterOptions.ColorBehavior özelliği olduğundan öğesini genişletebilirsinizSimpleConsoleFormatterOptions.

'den SimpleConsoleFormatterOptionstüretilen bir CustomColorOptions oluşturun:

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.Custom;

public class CustomColorOptions : SimpleConsoleFormatterOptions
{
    public string? CustomPrefix { get; set; }
}

Ardından, biçimlendirilmiş günlük iletilerine ANSI kodlu renkleri kolayca eklemenizi sağlayan bir TextWriterExtensions sınıfta bazı uzantı yöntemleri yazın:

namespace Console.ExampleFormatters.Custom;

public static class TextWriterExtensions
{
    const string DefaultForegroundColor = "\x1B[39m\x1B[22m";
    const string DefaultBackgroundColor = "\x1B[49m";

    public static void WriteWithColor(
        this TextWriter textWriter,
        string message,
        ConsoleColor? background,
        ConsoleColor? foreground)
    {
        // Order:
        //   1. background color
        //   2. foreground color
        //   3. message
        //   4. reset foreground color
        //   5. reset background color

        var backgroundColor = background.HasValue ? GetBackgroundColorEscapeCode(background.Value) : null;
        var foregroundColor = foreground.HasValue ? GetForegroundColorEscapeCode(foreground.Value) : null;

        if (backgroundColor != null)
        {
            textWriter.Write(backgroundColor);
        }
        if (foregroundColor != null)
        {
            textWriter.Write(foregroundColor);
        }

        textWriter.WriteLine(message);

        if (foregroundColor != null)
        {
            textWriter.Write(DefaultForegroundColor);
        }
        if (backgroundColor != null)
        {
            textWriter.Write(DefaultBackgroundColor);
        }
    }

    static string GetForegroundColorEscapeCode(ConsoleColor color) =>
        color switch
        {
            ConsoleColor.Black => "\x1B[30m",
            ConsoleColor.DarkRed => "\x1B[31m",
            ConsoleColor.DarkGreen => "\x1B[32m",
            ConsoleColor.DarkYellow => "\x1B[33m",
            ConsoleColor.DarkBlue => "\x1B[34m",
            ConsoleColor.DarkMagenta => "\x1B[35m",
            ConsoleColor.DarkCyan => "\x1B[36m",
            ConsoleColor.Gray => "\x1B[37m",
            ConsoleColor.Red => "\x1B[1m\x1B[31m",
            ConsoleColor.Green => "\x1B[1m\x1B[32m",
            ConsoleColor.Yellow => "\x1B[1m\x1B[33m",
            ConsoleColor.Blue => "\x1B[1m\x1B[34m",
            ConsoleColor.Magenta => "\x1B[1m\x1B[35m",
            ConsoleColor.Cyan => "\x1B[1m\x1B[36m",
            ConsoleColor.White => "\x1B[1m\x1B[37m",

            _ => DefaultForegroundColor
        };

    static string GetBackgroundColorEscapeCode(ConsoleColor color) =>
        color switch
        {
            ConsoleColor.Black => "\x1B[40m",
            ConsoleColor.DarkRed => "\x1B[41m",
            ConsoleColor.DarkGreen => "\x1B[42m",
            ConsoleColor.DarkYellow => "\x1B[43m",
            ConsoleColor.DarkBlue => "\x1B[44m",
            ConsoleColor.DarkMagenta => "\x1B[45m",
            ConsoleColor.DarkCyan => "\x1B[46m",
            ConsoleColor.Gray => "\x1B[47m",

            _ => DefaultBackgroundColor
        };
}

Özel renklerin uygulanmasını işleyen bir özel renk biçimlendirici aşağıdaki gibi tanımlanabilir:

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Options;

namespace Console.ExampleFormatters.Custom;

public sealed class CustomColorFormatter : ConsoleFormatter, IDisposable
{
    private readonly IDisposable? _optionsReloadToken;
    private CustomColorOptions _formatterOptions;

    private bool ConsoleColorFormattingEnabled =>
        _formatterOptions.ColorBehavior == LoggerColorBehavior.Enabled ||
        _formatterOptions.ColorBehavior == LoggerColorBehavior.Default &&
        System.Console.IsOutputRedirected == false;

    public CustomColorFormatter(IOptionsMonitor<CustomColorOptions> options)
        // Case insensitive
        : base("customName") =>
        (_optionsReloadToken, _formatterOptions) =
            (options.OnChange(ReloadLoggerOptions), options.CurrentValue);

    private void ReloadLoggerOptions(CustomColorOptions options) =>
        _formatterOptions = options;

    public override void Write<TState>(
        in LogEntry<TState> logEntry,
        IExternalScopeProvider? scopeProvider,
        TextWriter textWriter)
    {
        if (logEntry.Exception is null)
        {
            return;
        }

        string? message =
            logEntry.Formatter?.Invoke(
                logEntry.State, logEntry.Exception);

        if (message is null)
        {
            return;
        }

        CustomLogicGoesHere(textWriter);
        textWriter.WriteLine(message);
    }

    private void CustomLogicGoesHere(TextWriter textWriter)
    {
        if (ConsoleColorFormattingEnabled)
        {
            textWriter.WriteWithColor(
                _formatterOptions.CustomPrefix ?? string.Empty,
                ConsoleColor.Black,
                ConsoleColor.Green);
        }
        else
        {
            textWriter.Write(_formatterOptions.CustomPrefix);
        }
    }

    public void Dispose() => _optionsReloadToken?.Dispose();
}

Uygulamayı çalıştırdığınızda, günlükler olduğunda iletiyi yeşil FormatterOptions.ColorBehaviorEnabledrenkte gösterirCustomPrefix.

Not

olduğundaLoggerColorBehavior, günlük iletileri ekli ANSI renk kodlarını günlük iletileri içinde yorumlamaz.Disabled Bunun yerine ham iletinin çıktısını alır. Örneğin, aşağıdakileri göz önünde bulundurun:

logger.LogInformation("Random log \x1B[42mwith green background\x1B[49m message");

Bu, ayrıntılı dizenin çıkışını verir ve renklendirilmemiştir.

Random log \x1B[42mwith green background\x1B[49m message

Ayrıca bkz.