Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Jako autor knihovny představuje zveřejnění protokolování skvělý způsob, jak uživatelům poskytnout přehled o vnitřních pracovních činnostech vaší knihovny. Tyto pokyny vám pomůžou odhalit protokolování způsobem, který je konzistentní s ostatními knihovnami a architekturami .NET. Pomůže vám také vyhnout se běžným kritickým bodům výkonu.
Kdy použít ILoggerFactory rozhraní
Při zápisu knihovny, která generuje protokoly, potřebujete ILogger objekt k zaznamenání protokolů. Pokud chcete tento objekt získat, vaše rozhraní API může buď přijmout parametr ILogger<TCategoryName>, nebo přijmout ILoggerFactory, po kterém zavolá ILoggerFactory.CreateLogger. Který přístup by měl být upřednostňovaný?
- Pokud potřebujete objekt protokolování, který lze předat do více tříd, aby všechny z nich mohly generovat protokoly, použijte
ILoggerFactory. Doporučuje se, aby každá třída vytvářela logy s oddělenou kategorií, která má stejný název jako třída. K tomu potřebujete, aby továrna vytvořila jedinečnéILogger<TCategoryName>objekty pro každou třídu, která generuje logy. Mezi běžné příklady patří rozhraní API veřejného vstupního bodu pro knihovnu nebo veřejné konstruktory typů, které můžou interně vytvářet pomocné třídy. - Pokud potřebujete objekt protokolování, který se používá pouze v jedné třídě a nikdy nesdílí, použijte
ILogger<TCategoryName>, kdeTCategoryNameje typ, který vytváří protokoly. Běžným příkladem je konstruktor pro třídu vytvořenou vkládáním závislostí.
Pokud navrhujete veřejné rozhraní API, které musí v průběhu času zůstat stabilní, mějte na paměti, že v budoucnu budete chtít refaktorovat interní implementaci. I když třída zpočátku nevytvoří žádné interní pomocné typy, může se to při vývoji kódu změnit. Pomocí ILoggerFactory je možné vytvářet nové ILogger<TCategoryName> objekty pro všechny nové třídy, aniž by se změnilo veřejné rozhraní API.
Další informace naleznete v tématu Jak se používají pravidla filtrování.
Preferujte protokolování generované zdrojem
Rozhraní ILogger API podporuje dva přístupy k používání rozhraní API. Můžete buď volat takové metody, jako LoggerExtensions.LogError a LoggerExtensions.LogInformation, nebo můžete použít generátor zdroje logování k definování silně typovaných metod protokolování. Ve většině situací se doporučuje generátor zdrojového kódu, protože nabízí vynikající výkon a silnější typování. Izoluje také aspekty specifické pro protokolování, jako jsou šablony zpráv, ID a úrovně protokolů, od volajícího kódu. Negenerovaný přístup je primárně užitečný pro scénáře, kdy jste ochotni tyto výhody vzdát, aby byl kód výstižnější.
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);
}
Předchozí kód:
- Definuje
partial classpojmenovanýLogMessages, což jestatic, aby mohly být použity k definování rozšiřujících metod na typuILogger. - Ozdobí rozšiřující metodu
LogProductSaleDetailsatributemLoggerMessageaMessagešablonou. - Deklaruje se
LogProductSaleDetails, který rozšiřujeILoggera přijímáquantityadescription.
Návod
Během ladění můžete vstupovat do zdrojového kódu, protože je součástí stejného sestavení jako kód, který ho volá.
Slouží IsEnabled k zabránění nákladnému vyhodnocení parametrů.
Při vyhodnocování parametrů mohou nastat situace, kdy je vyhodnocení parametrů nákladné. Rozšířením předchozího příkladu description si představte, že parametr je nákladný string pro výpočty. Možná, že produkt, který je prodáván, získá přátelský popis a spoléhá se na dotaz do databáze nebo na čtení ze souboru. V těchto situacích můžete dát generátoru zdroje pokyn, aby přeskočil IsEnabled stráž a ručně přidal IsEnabled stráž v místě volání. To uživateli umožňuje určit, kde se stráž volá, a zajišťuje, že parametry, které by mohly být nákladné na výpočet, se vyhodnocují pouze tehdy, když je to skutečně potřeba. Vezměte v úvahu následující kód:
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);
}
LogProductSaleDetails Při zavolání IsEnabled metody rozšíření je ochrana vyvolána ručně a nákladné vyhodnocení parametrů je omezené na to, kdy je potřeba. Vezměte v úvahu následující kód:
if (_logger.IsEnabled(LogLevel.Information))
{
// Expensive parameter evaluation
var description = product.GetFriendlyProductDescription();
_logger.LogProductSaleDetails(
quantity,
description);
}
Další informace najdete v tématu Generování zdroje protokolování v době kompilace a protokolování s vysokým výkonem v .NET.
Vyhněte se interpolaci řetězců při protokolování
Běžnou chybou je použití interpolace řetězců k vytváření zpráv protokolu. Interpolace řetězců v logování je problematická pro výkon, protože se řetězec vyhodnotí i v případě, že odpovídající LogLevel není povoleno. Místo interpolace řetězců použijte šablonu zprávy protokolu, formátování a seznam argumentů. Další informace naleznete v tématu Protokolování v .NET: Šablona zprávy protokolu.
Použití výchozích hodnot protokolování no-op
Když využíváte knihovnu poskytující rozhraní API pro protokolování, které očekávají buď ILogger nebo ILoggerFactory, může se stát, že nebudete chtít poskytnout logger. V těchto případech balíček NuGet Microsoft.Extensions.Logging.Abstractions poskytuje výchozí nastavení protokolování no-op.
Uživatelé knihovny mohou použít výchozí protokolování s hodnotou null, pokud není poskytováno ILoggerFactory. Použití null logging se liší od definování typů jako nullable (ILoggerFactory?), protože typy nejsou nullovatelné. Tyto typy zaměřené na pohodlí nic nezapisují a v podstatě neprovádí žádnou operaci. Zvažte použití některého z dostupných typů abstrakce, pokud je to možné: