Anmerkung
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen, dich anzumelden oder die Verzeichnisse zu wechseln.
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen , die Verzeichnisse zu wechseln.
Als Bibliotheksentwickler ist es eine hervorragende Möglichkeit, Protokollierung zu ermöglichen, um den Verbrauchern einen Einblick in die Funktionsweise Ihrer Bibliothek zu bieten. Dieser Leitfaden hilft Ihnen, die Protokollierung auf eine Weise verfügbar zu machen, die mit anderen .NET-Bibliotheken und Frameworks konsistent ist. Es hilft Ihnen auch, häufige Leistungsengpässe zu vermeiden.
Wann soll die Schnittstelle ILoggerFactory verwendet werden?
Beim Schreiben einer Bibliothek, die Protokolle ausgibt, benötigen Sie ein ILogger Objekt, um die Protokolle aufzuzeichnen. Um dieses Objekt abzurufen, kann Ihre API entweder einen ILogger<TCategoryName>-Parameter akzeptieren oder einen ILoggerFactory-Aufruf entgegennehmen, nach dem Sie ILoggerFactory.CreateLogger aufrufen. Welcher Ansatz sollte bevorzugt werden?
- Wenn Sie ein Protokollierungsobjekt benötigen, das an mehrere Klassen übergeben werden kann, damit alle Protokolle ausgeben können, verwenden Sie
ILoggerFactory. Es wird empfohlen, dass jede Klasse Protokolle mit einer separaten Kategorie erstellt, die identisch mit der Klasse ist. Dazu benötigen Sie die Factory, um eindeutigeILogger<TCategoryName>Objekte für jede Klasse zu erstellen, die Protokolle ausgibt. Häufige Beispiele sind öffentliche Einstiegspunkt-APIs für eine Bibliothek oder öffentliche Konstruktoren von Typen, die Hilfsklassen intern erstellen können. - Wenn Sie ein Protokollierungsobjekt benötigen, das nur innerhalb einer Klasse verwendet und nie freigegeben wird, verwenden Sie
ILogger<TCategoryName>, wobeiTCategoryNameder Typ ist, der die Protokolle erzeugt. Ein gängiges Beispiel hierfür ist ein Konstruktor für eine Klasse, die durch Abhängigkeitsinjektion erstellt wurde.
Wenn Sie eine öffentliche API entwerfen, die im Laufe der Zeit stabil bleiben muss, denken Sie daran, dass Sie ihre interne Implementierung in Zukunft umgestalten möchten. Auch wenn eine Klasse anfänglich keine internen Hilfstypen erstellt, kann dies sich ändern, wenn sich der Code weiterentwickelt. Die Verwendung ILoggerFactory bietet Platz für das Erstellen neuer ILogger<TCategoryName> Objekte für alle neuen Klassen, ohne die öffentliche API zu ändern.
Weitere Informationen finden Sie unter Anwenden von Filterregeln.
Bevorzugt quellgenerierte Protokollierung
Die ILogger API unterstützt zwei Ansätze für die Verwendung der API. Sie können Methoden wie LoggerExtensions.LogError und LoggerExtensions.LogInformation aufrufen, oder Sie können den Protokollierungsquellgenerator verwenden, um stark typisierte Protokollierungsmethoden zu definieren. In den meisten Fällen wird der Quellgenerator empfohlen, da er eine überlegene Leistung und eine stärkere Eingabe bietet. Außerdem werden protokollierungsspezifische Bedenken wie Nachrichtenvorlagen, IDs und Protokollebenen vom aufrufenden Code isoliert. Der nicht aus der Quelle generierte Ansatz ist in erster Linie nützlich für Szenarien, in denen Sie bereit sind, diese Vorteile aufzugeben, um den Code präziser zu gestalten.
using Microsoft.Extensions.Logging;
namespace Logging.LibraryAuthors;
internal static partial class LogMessages
{
[LoggerMessage(
Message = "Sold {Quantity} of {Description}",
Level = LogLevel.Information)]
internal static partial void LogProductSaleDetails(
this ILogger logger,
int quantity,
string description);
}
Der vorherige Code:
- Definiert einen
partial classbenanntenLogMessagesNamen,staticder so verwendet werden kann, dass er zum Definieren von Erweiterungsmethoden für denILoggerTyp verwendet werden kann. - Schmückt eine
LogProductSaleDetailsErweiterungsmethode mit demLoggerMessageAttribut und derMessageVorlage. - Deklariert
LogProductSaleDetails, dasILoggererweitert und einquantitysowie eindescriptionakzeptiert.
Tipp
Sie können während des Debuggens in den quellcodegenerierten Code eintauchen, da er Teil derselben Assembly ist wie der Code, der ihn aufruft.
Wird IsEnabled verwendet, um teure Parameterauswertung zu vermeiden
Es kann Situationen geben, in denen die Auswertung von Parametern teuer ist. Erweitern wir das vorherige Beispiel: Stellen Sie sich vor, der description Parameter ist ein string, der aufwändig zu berechnen ist. Vielleicht erhält das verkaufte Produkt eine freundliche Produktbeschreibung und basiert auf einer Datenbankabfrage oder dem Lesen aus einer Datei. In diesen Situationen können Sie den Quellgenerator anweisen, den IsEnabled Schutz zu überspringen und den IsEnabled Schutz an der Anrufstelle manuell hinzuzufügen. Auf diese Weise kann der Benutzer ermitteln, wo der Schutz aufgerufen wird, und stellt sicher, dass Parameter, die möglicherweise teuer zu berechnen sind, nur ausgewertet werden, wenn sie wirklich benötigt werden. Beachten Sie den folgenden Code:
using Microsoft.Extensions.Logging;
namespace Logging.LibraryAuthors;
internal static partial class LogMessages
{
[LoggerMessage(
Message = "Sold {Quantity} of {Description}",
Level = LogLevel.Information,
SkipEnabledCheck = true)]
internal static partial void LogProductSaleDetails(
this ILogger logger,
int quantity,
string description);
}
Wenn die LogProductSaleDetails Erweiterungsmethode aufgerufen wird, wird der IsEnabled Guard manuell aktiviert, und die aufwändige Auswertung des Parameters erfolgt nur bei Bedarf. Beachten Sie den folgenden Code:
if (_logger.IsEnabled(LogLevel.Information))
{
// Expensive parameter evaluation
var description = product.GetFriendlyProductDescription();
_logger.LogProductSaleDetails(
quantity,
description);
}
Weitere Informationen finden Sie unter Kompilierungszeitprotokollierungsquellengenerierung und Hochleistungsprotokollierung in .NET.
Vermeiden der Zeichenfolgeninterpolation bei der Protokollierung
Ein häufiger Fehler besteht darin, die Zeichenfolgeninterpolation zum Erstellen von Protokollmeldungen zu verwenden. Die Zeichenfolgeninterpolation in der Protokollierung ist für die Leistung problematisch, da die Zeichenfolge ausgewertet wird, auch wenn die entsprechende LogLevel nicht aktiviert ist. Verwenden Sie anstelle der Zeichenfolgeninterpolation die Protokollnachrichtenvorlage, Formatierung und Argumentliste. Weitere Informationen finden Sie unter Protokollierung in .NET: Protokollnachrichtenvorlage.
Verwenden von no-op Protokollierungsstandardeinstellungen
Wenn Sie eine Bibliothek verwenden, die Protokollierungs-APIs bereitstellt, die entweder ein ILogger oder ein ILoggerFactory erwarten, kann es vorkommen, dass Sie keinen Logger bereitstellen möchten. In diesen Fällen stellt das NuGet-Paket "Microsoft.Extensions.Logging.Abstractions " no-op Protokollierungsstandard bereit.
Bibliotheksnutzer können standardmäßig null-Protokollierung verwenden, wenn kein ILoggerFactory bereitgestellt wird. Die Verwendung der NULL-Protokollierung unterscheidet sich von der Definition von Typen als *nullable* (ILoggerFactory?), da die Typen nicht-nullfähig sind. Diese benutzerfreundlichen Typen protokollieren nichts und sind im Wesentlichen Leerlaufoperationen. Erwägen Sie ggf. die Verwendung der verfügbaren Abstraktionstypen: