Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In qualità di autore della libreria, l'esposizione del logging è un ottimo modo per fornire ai consumer informazioni dettagliate sulle dinamiche interne della libreria. Queste indicazioni consentono di esporre la registrazione in modo coerente con altre librerie e framework .NET. Aiuta anche a evitare i comuni colli di bottiglia nelle prestazioni.
Quando usare l'interfaccia ILoggerFactory
Quando si scrive una libreria che genera i log, è necessario un ILogger oggetto per registrare i log. Per ottenere tale oggetto, l'API può accettare un ILogger<TCategoryName> parametro oppure può accettare un oggetto ILoggerFactory dopo il quale si chiama ILoggerFactory.CreateLogger. Quale approccio deve essere preferito?
- Quando è necessario un oggetto di registrazione che può essere passato a più classi in modo che tutti possano generare log, usare
ILoggerFactory. È consigliabile che ogni classe crei un log con una categoria separata, denominata nello stesso modo della classe. A tale scopo, è necessario che la factory crei oggetti univociILogger<TCategoryName>per ogni classe che genera log. Esempi comuni includono api del punto di ingresso pubblico per una libreria o costruttori pubblici di tipi che potrebbero creare classi helper internamente. - Quando è necessario un oggetto di registrazione usato solo all'interno di una classe e mai condiviso, usare
ILogger<TCategoryName>, doveTCategoryNameè il tipo che produce i log. Un esempio comune di questo è un costruttore per una classe creata dall'inserimento delle dipendenze.
Se si progetta un'API pubblica che deve rimanere stabile nel tempo, tenere presente che potrebbe essere opportuno effettuare il refactoring dell'implementazione interna in futuro. Anche se una classe non crea inizialmente alcun tipo di helper interno, che potrebbe cambiare man mano che il codice si evolve. L'uso ILoggerFactory di consente di creare nuovi ILogger<TCategoryName> oggetti per qualsiasi nuova classe senza modificare l'API pubblica.
Per altre informazioni, vedere Come vengono applicate le regole di filtro.
Preferisce la registrazione generata dall'origine
L'API ILogger supporta due approcci all'uso dell'API. È possibile chiamare metodi come LoggerExtensions.LogError e LoggerExtensions.LogInformationoppure è possibile usare il generatore di origine di registrazione per definire metodi di registrazione fortemente tipizzato. Per la maggior parte delle situazioni, il source generator è consigliato perché offre prestazioni superiori e una tipizzazione più forte. Isola anche aspetti specifici legati alla registrazione, come i modelli di messaggi, gli ID e i livelli di log dal codice chiamante. L'approccio non generato dall'origine è particolarmente utile per gli scenari in cui si è disposti a rinunciare a tali vantaggi per rendere il codice più conciso.
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);
}
Il codice precedente:
- Definisce un
partial classdenominatoLogMessages, così da poter essere utilizzato per definire metodi di estensione sul tipoILogger. - Decora un
LogProductSaleDetailsmetodo di estensione con l'attributoLoggerMessagee il modelloMessage. - Dichiara
LogProductSaleDetails, che estende ilILoggere accetta unquantitye undescription.
Suggerimento
È possibile entrare nel codice generato dal sorgente durante il debug, perché è incluso nello stesso assembly del codice che lo richiama.
Usare IsEnabled per evitare costose valutazioni dei parametri
Potrebbero verificarsi situazioni in cui la valutazione dei parametri è costosa. Espandendo l'esempio precedente, si supponga che il description parametro sia un string oggetto costoso da calcolare. Forse il prodotto venduto ottiene una descrizione amichevole del prodotto e si basa su una query di database o sulla lettura da un file. In queste situazioni, è possibile indicare al generatore di codice sorgente di ignorare la IsEnabled guard e aggiungere manualmente la IsEnabled guard al sito di chiamata. Ciò consente all'utente di determinare dove viene chiamata la protezione e garantisce che i parametri che potrebbero essere costosi da calcolare vengano valutati solo quando effettivamente necessario. Osservare il codice seguente:
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);
}
Quando viene chiamato il metodo di estensione LogProductSaleDetails, la guardia IsEnabled viene richiamata manualmente e la valutazione costosa dei parametri è limitata solo quando necessario. Osservare il codice seguente:
if (_logger.IsEnabled(LogLevel.Information))
{
// Expensive parameter evaluation
var description = product.GetFriendlyProductDescription();
_logger.LogProductSaleDetails(
quantity,
description);
}
Per altre informazioni, vedere Generazione dell'origine di registrazione in fase di compilazione e registrazione ad alte prestazioni in .NET.
Evitare l'interpolazione di stringhe nella registrazione
Un errore comune consiste nell'usare l'interpolazione di stringhe per compilare messaggi di log. L'interpolazione di stringhe nella registrazione è problematica per le prestazioni, perché la stringa viene valutata anche se il corrispondente LogLevel non è abilitato. Anziché l'interpolazione di stringhe, usare il modello di messaggio di log, la formattazione e l'elenco di argomenti. Per altre informazioni, vedere Registrazione in .NET: Modello di messaggio di log.
Usare le impostazioni predefinite per la registrazione no-op
Quando si utilizza una libreria che espone le API di registrazione che prevedono o ILogger o ILoggerFactory, potrebbero esserci situazioni in cui non si desidera fornire un logger. In questi casi, il pacchetto NuGet Microsoft.Extensions.Logging.Abstractions fornisce impostazioni predefinite di registrazione no-op.
I consumer di libreria possono impostare come impostazione predefinita il logging null se non viene fornito alcunILoggerFactory valore. L'uso della registrazione null differisce dalla definizione dei tipi come annullabili (ILoggerFactory?), poiché i tipi non sono null. Questi tipi basati su praticità non registrano nulla e sono essenzialmente no-ops. È consigliabile usare uno dei tipi di astrazione disponibili, se applicabile: