Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In .NET 5 wurde unterstützung für benutzerdefinierte Formatierungen zu Konsolenprotokollen im Microsoft.Extensions.Logging.Console
Namespace hinzugefügt. Es stehen drei vordefinierte Formatierungsoptionen zur Verfügung: Simple
, , Systemd
und Json
.
Von Bedeutung
Zuvor konnte das ConsoleLoggerFormat-Enum verwendet werden, um das gewünschte Protokollformat auszuwählen, entweder menschenlesbar, was das Default
ist, oder eine einzelne Zeile, die auch als Systemd
bekannt ist. Diese waren jedoch nicht anpassbar und sind jetzt veraltet.
In diesem Artikel erfahren Sie mehr über Konsolenprotokollformatierer. Der Beispielquellcode veranschaulicht folgendes:
- Registrieren Sie einen neuen Formatierer
- Wählen Sie einen registrierten Formatierer zur Verwendung aus.
- Entweder über Code oder Konfiguration
- Implementieren eines benutzerdefinierten Formatierers
- Aktualisieren der Konfiguration über IOptionsMonitor<TOptions>
- Benutzerdefinierte Farbformatierung aktivieren
Tipp
Der gesamte Quellcode des Protokollierungsbeispiels steht im Beispielbrowser zum Download zur Verfügung. Weitere Informationen finden Sie unter Durchsuchen von Codebeispielen: Protokollierung in .NET.
Registrieren eines Formatierers
Der Console
Protokollierungsanbieter verfügt über mehrere vordefinierte Formatierer und macht die Möglichkeit verfügbar, einen eigenen benutzerdefinierten Formatierer zu erstellen. Verwenden Sie die entsprechende Add{Type}Console
Erweiterungsmethode, um einen der verfügbaren Formatierer zu registrieren:
Verfügbare Typen | Methode zum Registrieren des Typs |
---|---|
ConsoleFormatterNames.Json | ConsoleLoggerExtensions.AddJsonConsole |
ConsoleFormatterNames.Simple | ConsoleLoggerExtensions.AddSimpleConsole |
ConsoleFormatterNames.Systemd | ConsoleLoggerExtensions.AddSystemdConsole |
Einfach
Um den Simple
Konsolenformatierer zu verwenden, registrieren Sie ihn bei 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.");
}
Im vorangehenden Beispielquellcode wurde der Formatierer ConsoleFormatterNames.Simple registriert. Er bietet für Protokolle nicht nur die Möglichkeit, Informationen wie z. B. Zeit und Protokollgrad in jeder Protokollmeldung zu umschließen, sondern ermöglicht auch die Einbettung von ANSI-Farben und Einzüge für Meldungen.
Wenn diese Beispiel-App ausgeführt wird, werden die Protokollmeldungen wie unten dargestellt formatiert:
Systemd
Der ConsoleFormatterNames.Systemd Konsolenprotokollierer:
- Sie verwendet das Protokolliergradformat und die Schweregrade von Syslog.
- Formatiert keine Nachrichten mit Farben.
- Protokolliert immer Nachrichten in einer einzelnen Zeile.
Dies ist häufig nützlich für Container, die häufig die Systemd
Konsolenprotokollierung verwenden. Mit .NET 5 ermöglicht der Simple
Konsolenprotokollierer auch eine kompakte Version, die sich in einer einzelnen Zeile anmeldet, und ermöglicht außerdem das Deaktivieren von Farben, wie in einem früheren Beispiel gezeigt.
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.");
}
Das Beispiel erzeugt eine Ausgabe ähnlich wie die folgenden Protokollmeldungen:
Json
Zum Schreiben von Protokollen in einem JSON-Format wird der Json
Konsolenformatierer verwendet. Der Beispielquellcode zeigt, wie eine ASP.NET Core-App sie möglicherweise registriert. Erstellen Sie mithilfe der webapp
Vorlage eine neue ASP.NET Core-App mit dem neuen Befehl dotnet :
dotnet new webapp -o Console.ExampleFormatters.Json
Wenn Sie die App mit dem Vorlagencode ausführen, erhalten Sie das folgende Standardprotokollformat:
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
Standardmäßig ist der Simple
Konsolenprotokollformatierer mit Standardkonfiguration ausgewählt. Sie ändern dies durch Aufrufen AddJsonConsole
der 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();
Alternativ können Sie dies auch mithilfe der Protokollierungskonfiguration konfigurieren, z. B. die in der appsettings.json Datei enthalten ist:
{
"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": "*"
}
Führen Sie die App mit der oben genannten Änderung erneut aus, die Protokollnachricht ist jetzt als JSON formatiert.
{
"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}"
}
}
Tipp
Der Json
Konsolenformatierer protokolliert standardmäßig jede Nachricht in einer einzelnen Zeile. Um die Lesbarkeit beim Konfigurieren des Formatierers zu verbessern, legen Sie die JsonWriterOptions.Indented Einstellung auf true
.
Vorsicht
Wenn Sie den Json-Konsolenformatierer verwenden, übergeben Sie keine Protokollmeldungen, die bereits als JSON serialisiert wurden. Die Protokollierungsinfrastruktur selbst verwaltet bereits die Serialisierung von Protokollnachrichten. Wenn Sie also eine bereits serialisierte Protokollnachricht übergeben möchten, wird sie doppelt serialisiert, wodurch die falsch formatierte Ausgabe verursacht wird.
Einstellen des Formatierers durch Konfiguration
In den vorherigen Beispielen wurde gezeigt, wie ein Formatierer programmatisch registriert werden kann. Alternativ lässt sich dies über die Konfiguration erledigen. Berücksichtigen Sie den vorherigen Quellcode der Webanwendung, wenn Sie die appsettings.json Datei aktualisieren und nicht in der ConfigureLogging
Datei aufrufen, könnten Sie dasselbe Ergebnis erzielen. Die aktualisierte appsettings.json
Datei würde den Formatierer wie folgt konfigurieren:
{
"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": "*"
}
Die beiden Schlüsselwerte, die festgelegt werden müssen, sind "FormatterName"
und "FormatterOptions"
. Wenn ein Formatierer mit dem festgelegten "FormatterName"
Wert bereits registriert ist, wird dieser Formatierer ausgewählt, und seine Eigenschaften können so konfiguriert werden, dass sie als Schlüssel innerhalb des "FormatterOptions"
Knotens bereitgestellt werden. Die vordefinierten Formatierernamen sind unter ConsoleFormatterNames reserviert:
Implementieren eines benutzerdefinierten Formatierers
Um einen benutzerdefinierten Formatierer zu implementieren, müssen Sie:
- Erstellen einer Unterklasse von ConsoleFormatter, dies stellt Ihren benutzerdefinierten Formatierer dar
- Registrieren Sie Ihren benutzerdefinierten Formatierer über
Erstellen Sie eine Erweiterungsmethode, um dies für Sie zu behandeln:
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);
}
Dies CustomOptions
ist wie folgt definiert:
using Microsoft.Extensions.Logging.Console;
namespace Console.ExampleFormatters.Custom;
public sealed class CustomOptions : ConsoleFormatterOptions
{
public string? CustomPrefix { get; set; }
}
Im vorherigen Code sind die Optionen eine Unterklasse von ConsoleFormatterOptions.
Die AddConsoleFormatter
API:
- Registriert eine Unterklasse von
ConsoleFormatter
- Sie übernimmt die Konfiguration:
- Verwendet ein Änderungstoken zum Synchronisieren von Updates basierend auf dem Optionsmuster und der IOptionsMonitor-Schnittstelle
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.");
}
Definieren einer CustomFormatter
Unterklasse von 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();
}
Die vorangehende CustomFormatter.Write<TState>
API legt fest, welcher Text jede Protokollnachricht einrahmt. Ein Standard-ConsoleFormatter
sollte zumindest Bereiche, Zeitstempel und den Schweregrad von Protokollen umschließen können. Darüber hinaus können Sie ANSI-Farben in den Protokollmeldungen codieren und auch gewünschte Einzüge bereitstellen. Die Implementierung der CustomFormatter.Write<TState>
weist diese Fähigkeiten nicht auf.
Inspiration zur weiteren Anpassung der Formatierung finden Sie in den vorhandenen Implementierungen im Microsoft.Extensions.Logging.Console
Namespace:
Benutzerdefinierte Konfigurationsoptionen
Um die Protokollierungserweiterung weiter anzupassen, kann Ihre abgeleitete ConsoleFormatterOptions Klasse von jedem Konfigurationsanbieter konfiguriert werden. Sie können beispielsweise den JSON-Konfigurationsanbieter verwenden, um Ihre benutzerdefinierten Optionen zu definieren. Definieren Sie zuerst Ihre ConsoleFormatterOptions Unterklasse.
using Microsoft.Extensions.Logging.Console;
namespace Console.ExampleFormatters.CustomWithConfig;
public sealed class CustomWrappingConsoleFormatterOptions : ConsoleFormatterOptions
{
public string? CustomPrefix { get; set; }
public string? CustomSuffix { get; set; }
}
Die obige Konsolenformatieroptionenklasse definiert zwei benutzerdefinierte Eigenschaften, die ein Präfix und Suffix darstellen. Definieren Sie als Nächstes die appsettings.json Datei, die die Optionen für die Konsolenformatierung konfiguriert.
{
"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": "*"
}
In der vorherigen JSON-Konfigurationsdatei:
- Der
"Logging"
Knoten definiert ein"Console"
. - Der
"Console"
-Knoten gibt ein"FormatterName"
-Objekt von"CustomTimePrefixingFormatter"
an, das einem benutzerdefinierten Formatierer zugeordnet wird. - Der
"FormatterOptions"
Knoten definiert ein"CustomPrefix"
, und"CustomSuffix"
, sowie einige andere abgeleitete Optionen.
Tipp
Der $.Logging.Console.FormatterOptions
JSON-Pfad ist reserviert und wird einer benutzerdefinierten ConsoleFormatterOptions Zuordnung zugeordnet, wenn sie mithilfe der AddConsoleFormatter Erweiterungsmethode hinzugefügt wird. Dies bietet die Möglichkeit, benutzerdefinierte Eigenschaften zusätzlich zu den verfügbaren eigenschaften zu definieren.
Beachten Sie Folgendes 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();
}
In der oben stehenden Formatierungsimplementierung ist Folgendes passiert:
- Das
CustomWrappingConsoleFormatterOptions
-Objekt wird auf Änderungen überwacht und entsprechend aktualisiert. - Geschriebene Nachrichten werden mit dem konfigurierten Präfix und Suffix umschlossen.
- Ein Zeitstempel wird nach dem Präfix, aber vor der Nachricht hinzugefügt, wobei die konfigurierten ConsoleFormatterOptions.UseUtcTimestamp und ConsoleFormatterOptions.TimestampFormat Werte verwendet werden.
Fügen Sie beim Aufrufen von ConfigureLogging(IHostBuilder, Action<HostBuilderContext,ILoggingBuilder>) hinzu, um benutzerdefinierte Konfigurationsoptionen mit benutzerdefinierten Formatiererimplementierungen zu verwenden.
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.");
}
Die folgende Konsolenausgabe ähnelt dem, was Sie erwarten könnten, wenn Sie CustomTimePrefixingFormatter
verwenden.
|-<[ 15:03:15.6179 Hello World! ]>-|
|-<[ 15:03:15.6347 The .NET developer community happily welcomes you. ]>-|
Implementieren von benutzerdefinierter Farbformatierung
Um Farbfunktionen im benutzerdefinierten Protokollierungsformatierer ordnungsgemäß zu aktivieren, können Sie SimpleConsoleFormatterOptions erweitern, da es die SimpleConsoleFormatterOptions.ColorBehavior-Eigenschaft hat, die nützlich sein kann, um Farben in Protokollen zu aktivieren.
Erstellen Sie ein CustomColorOptions
, das von SimpleConsoleFormatterOptions
abgeleitet ist.
using Microsoft.Extensions.Logging.Console;
namespace Console.ExampleFormatters.Custom;
public class CustomColorOptions : SimpleConsoleFormatterOptions
{
public string? CustomPrefix { get; set; }
}
Schreiben Sie als Nächstes einige Erweiterungsmethoden in eine TextWriterExtensions
Klasse, mit der ANSI-codierte Farben bequem in formatierte Protokollmeldungen eingebettet werden können:
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
};
}
Ein benutzerdefinierter Farbformatierer, der das Anwenden benutzerdefinierter Farben behandelt, kann wie folgt definiert werden:
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();
}
Wenn Sie die Anwendung ausführen, wird in den Protokollen die CustomPrefix
Meldung in der Farbe Grün angezeigt, wenn FormatterOptions.ColorBehavior
Enabled
ist.
Hinweis
Wenn LoggerColorBehavior auf Disabled
festgelegt ist, werden keine eingebetteten ANSI-Farbcodes in Protokollmeldungen interpretiert. Stattdessen geben sie die unformatierte Nachricht aus. Betrachten Sie beispielsweise Folgendes:
logger.LogInformation("Random log \x1B[42mwith green background\x1B[49m message");
Hierdurch wird die ausführliche Zeichenfolge ohne Farbformatierung ausgegeben.
Random log \x1B[42mwith green background\x1B[49m message