Bagikan melalui


Pemformatan log konsol

Di .NET 5, dukungan untuk pemformatan kustom ditambahkan ke log konsol di Microsoft.Extensions.Logging.Console namespace. Ada tiga opsi pemformatan yang telah ditentukan sebelumnya yang tersedia: Simple, , Systemddan Json.

Penting

Sebelumnya, ConsoleLoggerFormat enum diizinkan untuk memilih format log yang diinginkan, baik yang dapat dibaca manusia yang merupakan Default, atau baris tunggal yang juga dikenal sebagai Systemd. Namun, ini tidak dapat disesuaikan, dan sekarang tidak digunakan lagi.

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

  • Mendaftarkan formatter baru
  • Pilih formatter terdaftar yang akan digunakan
  • Menerapkan pemformat kustom

Tip

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

Mendaftarkan pemformat

Penyedia Console 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

Sederhana

Untuk menggunakan Simple formatter konsol, 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 kode sumber sampel sebelumnya, ConsoleFormatterNames.Simple pemformat 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 dan tingkat log "Syslog" dan tingkat keparahan
  • Tidak memformat pesan dengan warna
  • Selalu mencatat pesan dalam satu baris

Ini biasanya berguna untuk kontainer, yang sering menggunakan pengelogan Systemd konsol. Dengan .NET 5, pencatat Simple konsol juga mengaktifkan 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. webapp Menggunakan templat, buat aplikasi ASP.NET Core baru dengan perintah baru dotnet:

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

Tip

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 sudah mengelola serialisasi pesan log, jadi jika Anda meneruskan pesan log yang sudah diserialisasikan—itu akan diserialisasikan ganda, sehingga menyebabkan output salah bentuk.

Atur pemformat dengan konfigurasi

Sampel sebelumnya telah 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, pemformat tersebut dipilih, dan propertinya dapat dikonfigurasi selama disediakan sebagai kunci di dalam simpul "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.

The AddConsoleFormatter API:

  • Mendaftarkan subkelas dari ConsoleFormatter
  • Menangani konfigurasi:
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 harus dapat membungkus cakupan, stempel waktu, dan tingkat keparahan log minimal. Selain itu, Anda dapat mengodekan warna ANSI dalam pesan log, dan memberikan indentasi yang diinginkan juga. Implementasi dari kurangnya CustomFormatter.Write<TState> 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" menentukan "FormatterName" dari "CustomTimePrefixingFormatter", yang memetakan ke formatter kustom.
  • Simpul "FormatterOptions" mendefinisikan "CustomPrefix", dan "CustomSuffix", serta beberapa opsi turunan lainnya.

Tip

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

Pertimbangkan CustomDatePrefixingFormatter berikut:

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:

Untuk menggunakan opsi konfigurasi kustom, dengan implementasi formatter kustom, tambahkan saat 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 apa yang mungkin Anda harapkan untuk dilihat dari menggunakan ini CustomTimePrefixingFormatter.

|-<[ 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 SimpleConsoleFormatterOptions.ColorBehavior properti yang dapat berguna untuk mengaktifkan warna dalam log.

CustomColorOptions Buat 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.

Catatan

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 verbatim, dan tidak berwarna.

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

Lihat juga