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áhá také vyhnout se běžným kritickým bodům výkonu, které nemusí být jinak zřejmé.
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 a poté zavolat 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 protokoly se samostatnou kategorií, která je pojmenovaná stejně jako třída. K tomu potřebujete, aby továrna vytvořila jedinečnéILogger<TCategoryName>objekty pro každou třídu, která logy generuje. 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 pomocí vkládání 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. Použití ILoggerFactory umožňuje vytváření nových objektů ILogger<TCategoryName> pro jakékoli nové třídy, aniž by se měnilo veřejné 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 metody jako LoggerExtensions.LogError a LoggerExtensions.LogInformation, nebo můžete použít generátor logovacího zdroje k definování silně typovaných metod protokolování. Ve většině situací se doporučuje generátor zdroje, 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, ve kterých 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 classpojmenovanouLogMessages, což jestatic, aby ji bylo možné použít k definování rozšiřujících metod na typuILogger. - Ozdobí rozšiřující metodu
LogProductSaleDetailsatributemLoggerMessageaMessagešablonou. - Deklaruje
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ů.
Mohou nastat situace, kdy je vyhodnocení parametrů nákladné. Představte si rozšíření předchozího příkladu: parametr description je string nákladný na výpočet. Možná produkt, který se prodává, obdrží přívětivý popis a spoléhá na dotaz do databáze nebo čtení ze souboru. V těchto situacích můžete dát pokyn generátoru zdroje, aby ochranu IsEnabled přeskočil a ručně přidal IsEnabled ochranu na místo volání. To uživateli umožňuje určit, kde se ochrana volá, a zajišťuje, aby parametry, které by mohly být nákladné na výpočet, byly vyhodnocovány pouze tehdy, když jsou 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 rámci protokolování je problematická z hlediska výkonu, protože řetězec se vyhodnotí, i když odpovídající LogLevel není povolen. 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žijte výchozí nastavení protokolování no-op
Může se stát, že používáte knihovnu, která zveřejňuje rozhraní API protokolování a očekává buď ILogger nebo ILoggerFactory, ale vy nechcete 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 protokolování s hodnotou null jako výchozí, pokud není ILoggerFactory k dispozici. Použití nulového protokolování se liší od definování typů jako nulových (ILoggerFactory?), protože typy nejsou nulové. Tyto typy založené na pohodlí nic nezapíše a jsou v podstatě no-ops. Zvažte použití některého z dostupných typů abstrakce, pokud je to možné: