Bagikan melalui


Pemformatan log konsol

Namespace Microsoft.Extensions.Logging.Console menyediakan dukungan untuk pemformatan kustom di log konsol. Ada tiga opsi pemformatan yang telah ditentukan sebelumnya yang tersedia: Simple, , Systemddan Json.

Penting

Sebelum .NET 5, ConsoleLoggerFormat enum mengizinkan memilih format log yang diinginkan, baik yang mudah dibaca manusia, yang merupakan Default, maupun satu baris yang juga dikenal sebagai Systemd. Akan tetapi, ini tidak dapat disesuaikan, dan sekarang telah dihentikan penggunaannya.

Dalam artikel ini, Anda akan mempelajari tentang pemformat log konsol. Kode sumber sampel menunjukkan cara:

  • Daftarkan formatter baru.
  • Pilih formatter yang terdaftar untuk digunakan, baik melalui kode atau konfigurasi.
  • Menerapkan formatter kustom. Anda memperbarui konfigurasi melalui IOptionsMonitor<TOptions> dan mengaktifkan pemformatan warna kustom.

Petunjuk / Saran

Semua contoh kode sumber pencatatan log tersedia di Sampel Browser untuk diunduh. Untuk informasi selengkapnya, lihat Menelusuri sampel kode: Pengelogan di .NET.

Mendaftarkan pemformat

PenyediaConsole pengelogan memiliki beberapa pemformat yang telah ditentukan sebelumnya, dan mengekspos kemampuan untuk menulis formatter kustom Anda sendiri. Untuk mendaftarkan salah satu formatter yang tersedia, gunakan metode ekstensi yang Add{Type}Console sesuai:

Jenis yang tersedia Metode untuk mendaftarkan jenis
ConsoleFormatterNames.Json ConsoleLoggerExtensions.AddJsonConsole
ConsoleFormatterNames.Simple ConsoleLoggerExtensions.AddSimpleConsole
ConsoleFormatterNames.Systemd ConsoleLoggerExtensions.AddSystemdConsole

Simple

Untuk menggunakan formatter konsol Simple, daftarkan dengan AddSimpleConsole:

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.");
}

Dalam sampel kode sumber sebelumnya, ConsoleFormatterNames.Simple pemformat telah didaftarkan. Ini menyediakan log dengan kemampuan untuk tidak hanya membungkus informasi seperti waktu dan tingkat log di setiap pesan log, tetapi juga memungkinkan penyematan warna ANSI dan indentasi pesan.

Saat aplikasi sampel ini dijalankan, pesan log diformat seperti yang ditunjukkan di bawah ini:

Contoh log konsol yang ditulis dengan formatter sederhana.

Systemd

Pencatat ConsoleFormatterNames.Systemd konsol:

  • Menggunakan format tingkat log dan tingkat keparahan "Syslog".
  • Tidak memformat pesan dengan warna.
  • Selalu mencatat pesan dalam satu baris.

Ini biasanya berguna untuk kontainer, yang sering menggunakan pengelogan Systemd konsol. Pencatat Simple konsol juga memungkinkan versi ringkas yang mencatat dalam satu baris, dan juga memungkinkan penonaktifan warna seperti yang ditunjukkan pada sampel sebelumnya.

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.");
}

Contoh menghasilkan output yang mirip dengan pesan log berikut:

Contoh log konsol yang ditulis dengan pemformat Systemd.

Json

Untuk menulis log dalam format JSON, Json formatter konsol digunakan. Kode sumber sampel menunjukkan bagaimana aplikasi ASP.NET Core dapat mendaftarkannya. Dengan menggunakan templat webapp, buat aplikasi ASP.NET Core baru dengan perintah dotnet new:

dotnet new webapp -o Console.ExampleFormatters.Json

Saat menjalankan aplikasi, menggunakan kode templat, Anda mendapatkan format log default di bawah ini:

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

Secara default, Simple formatter log konsol dipilih dengan konfigurasi default. Anda mengubah ini dengan memanggil AddJsonConsole di Program.cs:

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

Atau, Anda juga dapat mengonfigurasi ini menggunakan konfigurasi pengelogan, seperti yang ditemukan dalam file appsettings.json :

{
    "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": "*"
}

Jalankan aplikasi lagi, dengan perubahan di atas, pesan log sekarang diformat sebagai JSON:

{
  "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}"
  }
}

Petunjuk / Saran

Formatter Json konsol, secara default, mencatat setiap pesan dalam satu baris. Untuk membuatnya lebih mudah dibaca saat mengonfigurasi formatter, atur JsonWriterOptions.Indented ke true.

Perhatian

Saat menggunakan formatter konsol JSON, jangan meneruskan pesan log yang telah diserialisasikan sebagai JSON. Infrastruktur pengelogan itu sendiri mengelola serialisasi pesan log. Jadi, jika Anda meneruskan pesan log yang sudah diserialisasi, pesan tersebut akan diserialisasi ulang, sehingga menghasilkan output yang rusak.

Atur pemformat dengan konfigurasi

Sampel sebelumnya menunjukkan cara mendaftarkan pemformat secara terprogram. Atau, ini dapat dilakukan dengan konfigurasi. Pertimbangkan kode sumber sampel aplikasi web sebelumnya, jika Anda memperbarui file appsettings.json daripada memanggil ConfigureLogging dalam file Program.cs , Anda bisa mendapatkan hasil yang sama. File yang diperbarui appsettings.json akan mengonfigurasi formatter sebagai berikut:

{
    "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": "*"
}

Dua nilai kunci yang perlu diatur adalah "FormatterName" dan "FormatterOptions". Jika formatter dengan nilai yang ditetapkan untuk "FormatterName" sudah terdaftar, formatter tersebut dipilih, dan propertinya dapat dikonfigurasi selama mereka disediakan sebagai kunci di dalam node "FormatterOptions". Nama formatter yang telah ditentukan sebelumnya dicadangkan di bawah ConsoleFormatterNames:

Menerapkan pemformat kustom

Untuk menerapkan formatter kustom, Anda perlu:

Buat metode ekstensi untuk menangani ini untuk Anda:

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

didefinisikan CustomOptions sebagai berikut:

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.Custom;

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

Dalam kode sebelumnya, opsinya adalah subkelas dari ConsoleFormatterOptions.

AddConsoleFormatter API:

  • Mendaftarkan subkelas dari ConsoleFormatter.
  • Mengelola konfigurasi. Ini menggunakan token perubahan untuk menyinkronkan pembaruan, berdasarkan pola opsi, dan antarmuka IOptionsMonitor .
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 Tentukan subkelas dari ConsoleFormatter:

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

API sebelumnya CustomFormatter.Write<TState> menentukan teks apa yang dibungkus di sekitar setiap pesan log. Standar ConsoleFormatter seharusnya dapat meliputi cakupan, stempel waktu, dan tingkat keparahan dari log pada tingkat minimum. Selain itu, Anda dapat mengodekan warna ANSI dalam pesan log, dan memberikan indentasi yang diinginkan juga. Implementasi CustomFormatter.Write<TState> tidak memiliki kemampuan ini.

Untuk inspirasi tentang menyesuaikan pemformatan lebih lanjut, lihat implementasi yang ada di Microsoft.Extensions.Logging.Console namespace:

Opsi konfigurasi kustom

Untuk menyesuaikan ekstensibilitas pengelogan lebih lanjut, kelas turunan ConsoleFormatterOptions Anda dapat dikonfigurasi dari penyedia konfigurasi apa pun. Misalnya, Anda dapat menggunakan penyedia konfigurasi JSON untuk menentukan opsi kustom Anda. Pertama-tama tentukan subkelas Anda ConsoleFormatterOptions .

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.CustomWithConfig;

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

    public string? CustomSuffix { get; set; }
}

Kelas opsi pemformat konsol sebelumnya mendefinisikan dua properti kustom, mewakili awalan dan akhiran. Selanjutnya, tentukan file appsettings.json yang akan mengonfigurasi opsi formatter konsol Anda.

{
    "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": "*"
}

Dalam file konfigurasi JSON sebelumnya:

  • Simpul "Logging" mendefinisikan "Console".
  • Simpul "Console" menyebutkan "FormatterName" dari "CustomTimePrefixingFormatter", yang dipetakan ke formatter kustom.
  • Simpul "FormatterOptions" mendefinisikan "CustomPrefix", dan "CustomSuffix", serta beberapa opsi turunan lainnya.

Petunjuk / Saran

Jalur $.Logging.Console.FormatterOptions JSON dicadangkan dan akan dipetakan ke ConsoleFormatterOptions kustom ketika ditambahkan menggunakan metode ekstensi AddConsoleFormatter. Ini menyediakan kemampuan untuk menentukan properti kustom, selain properti yang tersedia.

Pertimbangkan hal berikut CustomDatePrefixingFormatter:

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

Dalam implementasi formatter sebelumnya:

  • CustomWrappingConsoleFormatterOptions dipantau untuk mendeteksi perubahan, dan diperbarui sesuai dengan perubahan tersebut.
  • Pesan yang ditulis dibungkus dengan awalan yang dikonfigurasi, dan akhiran.
  • Tanda waktu ditambahkan setelah awalan, tetapi sebelum pesan menggunakan nilai ConsoleFormatterOptions.UseUtcTimestamp dan ConsoleFormatterOptions.TimestampFormat yang telah dikonfigurasi.

Untuk menggunakan opsi konfigurasi khusus dengan implementasi formatter khusus, tambahkan ketika memanggil ConfigureLogging(IHostBuilder, Action<HostBuilderContext,ILoggingBuilder>).

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.");
}

Output konsol berikut mirip dengan yang mungkin Anda harapkan saat menggunakan CustomTimePrefixingFormatter ini.

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

Menerapkan pemformatan warna kustom

Untuk mengaktifkan kemampuan warna dengan benar dalam pemformat pengelogan kustom, Anda dapat memperluas SimpleConsoleFormatterOptions karena memiliki properti SimpleConsoleFormatterOptions.ColorBehavior yang dapat berguna untuk mengaktifkan warna dalam log.

Buat CustomColorOptions yang berasal dari SimpleConsoleFormatterOptions:

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.Custom;

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

Selanjutnya, tulis beberapa metode ekstensi di TextWriterExtensions kelas yang memungkinkan penyematan warna berkode ANSI dengan nyaman dalam pesan log yang diformat:

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

Pemformat warna kustom yang menangani penerapan warna kustom dapat didefinisikan sebagai berikut:

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

Ketika Anda menjalankan aplikasi, log akan menampilkan CustomPrefix pesan dalam warna hijau ketika FormatterOptions.ColorBehavior adalah Enabled.

Nota

Ketika LoggerColorBehavior adalah Disabled, pesan log tidak menginterpretasikan kode warna ANSI yang disematkan dalam pesan log. Sebaliknya, mereka mengeluarkan pesan mentah. Misalnya, pertimbangkan hal berikut:

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

Ini akan menghasilkan string secara langsung, dan tidak diberi warna.

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

Lihat juga