Megosztás:


Konzolnapló formázása

A Microsoft.Extensions.Logging.Console névtér támogatja a konzolnaplók egyéni formázását. Három előre definiált formázási lehetőség érhető el: Simple, Systemdés Json.

Fontos

A .NET 5 előtt az ConsoleLoggerFormat enumerálás lehetővé tette a kívánt naplóformátum kiválasztását, amely lehetett emberi olvasható Default, vagy egysoros, más néven Systemd. Ezek azonban nem testreszabhatók, és most elavultak.

Ebben a cikkben megismerkedhet a konzolnapló-formázókkal. A minta forráskódja bemutatja, hogyan:

  • Regisztráljon új formázót.
  • Jelöljön ki egy regisztrált formázót, amelyet kód vagy konfiguráció használatával szeretne használni.
  • Egyéni formázó implementálása. A konfigurációt a IOptionsMonitor<TOptions> segítségével frissíti, és engedélyezi az egyéni színformázást.

Jótanács

Az összes naplózási példa forráskódja letölthető a Mintaböngészőben . További információ: Kódminták tallózása: Naplózás a .NET-ben.

Formatter regisztrálása

A Console naplózási szolgáltató számos előre definiált formázóval rendelkezik, és lehetővé teszi saját egyéni formázó készítését. Az elérhető formázók regisztrálásához használja a megfelelő Add{Type}Console kiterjesztési metódust:

Elérhető típusok Típus regisztrálásának módja
ConsoleFormatterNames.Json ConsoleLoggerExtensions.AddJsonConsole
ConsoleFormatterNames.Simple ConsoleLoggerExtensions.AddSimpleConsole
ConsoleFormatterNames.Systemd ConsoleLoggerExtensions.AddSystemdConsole

Simple

A Simple konzolformátumító használatához regisztrálja a következővel 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.");
}

Az előző minta forráskódjában a ConsoleFormatterNames.Simple formázót regisztrálták. A naplók nemcsak azt teszik lehetővé, hogy az egyes naplóüzenetekbe becsomagolja az információkat, például az időt és a naplószintet, hanem lehetővé teszik a naplóüzenetek ANSI színekkel történő megjelenítését, valamint a behúzást is.

A mintaalkalmazás futtatásakor a naplóüzenetek az alábbi módon lesznek formázva:

Példa konzolnaplókra, amelyek az egyszerű formázóval íródnak.

Systemd

A ConsoleFormatterNames.Systemd konzolnaplózó:

  • A "Syslog" naplószintű formátumot és a hozzá tartozó súlyossági szinteket használja.
  • Nem formázza a színekkel ellátott üzeneteket.
  • Az üzeneteket mindig egyetlen sorban naplózza.

Ez gyakran hasznos a konténerek esetében, amelyek gyakran használják a Systemd konzol naplózását. A Simple konzolnaplózó egy olyan kompakt verziót is lehetővé tesz, amely egyetlen sorban naplóz, és lehetővé teszi a színek letiltását is egy korábbi mintában látható módon.

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

A példa a következő naplóüzenetekhez hasonló kimenetet hoz létre:

Példa konzolnaplókra, amelyek a Systemd formatterrel íródtak.

Json

A naplók JSON formátumú írásához a Json konzolformázó használható. A minta forráskódja bemutatja, hogyan regisztrálhatja egy ASP.NET Core-alkalmazás. webapp A sablon használatával hozzon létre egy új ASP.NET Core-alkalmazást az új dotnet paranccsal:

dotnet new webapp -o Console.ExampleFormatters.Json

Az alkalmazás futtatásakor a sablonkód használatával az alábbi alapértelmezett naplóformátumot kapja:

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

Alapértelmezés szerint a Simple konzolnapló-formázó van kiválasztva az alapértelmezett konfigurációval. Ezt a AddJsonConsole hívásával módosíthatja:

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

Másik lehetőségként ezt a naplózási konfigurációval is konfigurálhatja, például a appsettings.json fájlban:

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

Futtassa újra az alkalmazást, a fenti módosítással a naplóüzenet mostantól JSON formátumban van formázva:

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

Jótanács

A Json konzolforma-formázó alapértelmezés szerint egyetlen sorban naplózza az egyes üzeneteket. Ha olvashatóbbá szeretné tenni a formázó konfigurálása során, állítsa a következőre JsonWriterOptions.Indentedtrue: .

Caution

A JSON-konzolformázó használatakor ne adjon át olyan naplóüzeneteket, amelyek már szerializáltak JSON-ként. Maga a naplózási infrastruktúra kezeli a naplóüzenetek szerializálását. Ha tehát egy már szerializált naplóüzenetet ad át, az dupla szerializálva lesz, ami hibás kimenetet okoz.

A formázó beállítása a konfigurációval

Az előző minták azt mutatták be, hogyan lehet programkódból regisztrálni egy formázót. Ezt a konfigurációval is megteheti. Fontolja meg az előző webalkalmazás-minta forráskódját, ha a Program.cs fájl meghívása helyett ConfigureLogging frissíti a appsettings.json fájlt, ugyanezt az eredményt érheti el. A frissített appsettings.json fájl a következőképpen konfigurálja a formázót:

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

A két kulcsérték, amelyeket be kell állítani: "FormatterName" és "FormatterOptions". Ha már regisztrálva van egy olyan formázó, amelynek az értéke meg van adva "FormatterName", akkor az a formázó kerül kiválasztásra, és tulajdonságai konfigurálhatók, amennyiben kulcsként vannak megadva a "FormatterOptions" csomópontban. Az előre definiált formázónevek a ConsoleFormatterNames alatt vannak fenntartva:

Egyéni formázó implementálása

Egyéni formázó implementálásához a következőkre van szükség:

Hozzon létre egy bővítménymetódust a kezeléshez:

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

A CustomOptions definíció a következő:

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.Custom;

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

Az előző kódban a beállítások a ConsoleFormatterOptions egy alosztálya.

Az AddConsoleFormatter API:

  • Az alosztályát regisztrálja ConsoleFormatter.
  • Kezeli a konfigurációt. Változtatási tokent használ a frissítések szinkronizálásához az opciós minta és az IOptionsMonitor felület alapján.
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 osztály alosztályának definiálásaConsoleFormatter:

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

Az előző CustomFormatter.Write<TState> API határozza meg, hogy az egyes naplóüzenetek milyen szövegbe burkolhatók. Egy szabványnak ConsoleFormatter legalább a hatóköröket, az időbélyegeket és a naplók súlyossági szintjeit támogatnia kell. Emellett a naplóüzenetekben ANSI-színeket is kódolhat, és a kívánt behúzásokat is megadhat. A megvalósítás nem rendelkezik ezekkel a CustomFormatter.Write<TState> képességekkel.

A formázás további testreszabásával kapcsolatos inspirációért tekintse meg a névtér meglévő Microsoft.Extensions.Logging.Console implementációit:

Egyéni konfigurációs beállítások

A naplózás bővíthetőségének további testreszabásához a származtatott ConsoleFormatterOptions osztály bármely konfigurációszolgáltatótól konfigurálható. Használhatja például a JSON-konfigurációszolgáltatót az egyéni beállítások meghatározásához. Először határozza meg a(z) ConsoleFormatterOptions alosztályt.

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.CustomWithConfig;

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

    public string? CustomSuffix { get; set; }
}

Az előző konzolformátum-beállításosztály két egyéni tulajdonságot határoz meg, amelyek egy előtagot és utótagot jelölnek. Ezután adja meg a appsettings.json fájlt, amely konfigurálja a konzolformázási beállításokat.

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

Az előző JSON-konfigurációs fájlban:

  • A "Logging" csomópont definiál egy "Console".
  • A "Console" csomópont egy "FormatterName" típusú "CustomTimePrefixingFormatter"-t ad meg, amely egy egyéni formázóra van leképezve.
  • A "FormatterOptions" csomópont definiál egy "CustomPrefix", és "CustomSuffix", valamint néhány más származtatott lehetőséget.

Jótanács

A $.Logging.Console.FormatterOptions JSON-elérési út fenntartott, és a kiterjesztési metódus használatával történő hozzáadáskor egy egyedi ConsoleFormatterOptions-hez lesz leképezve AddConsoleFormatter. Így az elérhető tulajdonságok mellett egyéni tulajdonságokat is meghatározhat.

Vegye figyelembe a következőket 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();
}

Az előző formázási implementációban:

  • A CustomWrappingConsoleFormatterOptions rendszer figyeli a módosításokat, és ennek megfelelően frissül.
  • Az írott üzenetek a konfigurált előtaggal és utótaggal vannak becsomagolva.
  • Az előtag után, de az üzenet előtt időbélyeg kerül hozzáadásra a konfigurált ConsoleFormatterOptions.UseUtcTimestamp és ConsoleFormatterOptions.TimestampFormat értékek használatával.

Ha egyéni konfigurációs beállításokat szeretne használni, egyéni formázó implementációkkal, adja hozzá híváskor 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.");
}

A következő konzolkimenet ahhoz hasonló, amit várhat, ha ezt CustomTimePrefixingFormatter használja.

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

Egyéni színformázás implementálása

Annak érdekében, hogy helyesen engedélyezze a színfunkciókat az egyéni naplózó formátumban, kibővítheti a SimpleConsoleFormatterOptions elemet, mivel a SimpleConsoleFormatterOptions.ColorBehavior tulajdonsága hasznos lehet a naplók színeinek engedélyezéséhez.

Hozzon létre egy olyant CustomColorOptions , amely a következőből SimpleConsoleFormatterOptionsszármazik:

using Microsoft.Extensions.Logging.Console;

namespace Console.ExampleFormatters.Custom;

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

Ezután írjon néhány bővítménymetelyt egy TextWriterExtensions osztályba, amely lehetővé teszi az ANSI-kódolt színek kényelmes beágyazását a formázott naplóüzenetekbe:

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

Az egyéni színeket kezelő egyéni színformáló a következőképpen definiálható:

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

Az alkalmazás futtatásakor a naplók zöld színnel jelenítik meg az CustomPrefix üzenetet, amikor FormatterOptions.ColorBehavior egyenlő Enabled.

Megjegyzés:

Amikor LoggerColorBehaviorDisabled, a naplóüzenetek nem értelmezik a beágyazott ANSI-színkódokat. Ehelyett a nyers üzenetet adják ki. Vegyük például a következőket:

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

Ez a pontos sztringet adja ki, és nincs színezve.

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

Lásd még