Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Como autor de biblioteca, a exposição do registro em log é uma ótima maneira de fornecer aos consumidores uma visão do funcionamento interno da sua biblioteca. Essas diretrizes ajudam você a expor o log de uma maneira consistente com outras bibliotecas e estruturas do .NET. Ele também ajuda você a evitar gargalos de desempenho comuns que podem não ser óbvios de outra forma.
Quando usar a ILoggerFactory interface
Ao escrever uma biblioteca que emite logs, você precisa de um ILogger objeto para gravar os logs. Para obter esse objeto, sua API pode aceitar um ILogger<TCategoryName> parâmetro ou pode aceitar um ILoggerFactory após o qual você chama ILoggerFactory.CreateLogger. Qual abordagem deve ser preferida?
Quando você precisar de um objeto de log que possa ser passado para várias classes, de modo que todas elas possam emitir logs, use
ILoggerFactory. É recomendável que cada classe crie logs com uma categoria separada, nomeada da mesma forma que a classe. Para isso, é necessário que a fábrica crie objetos únicosILogger<TCategoryName>para cada classe que emite logs. Exemplos comuns incluem APIs de ponto de entrada público para uma biblioteca ou construtores públicos de tipos que podem criar classes auxiliares internamente.Quando você precisar de um objeto de log que seja usado apenas dentro de uma classe e nunca compartilhado, use
ILogger<TCategoryName>, ondeTCategoryNameé o tipo que produz os logs. Um exemplo comum disso é um construtor para uma classe criada por injeção de dependência.
Se você estiver criando uma API pública que deve permanecer estável ao longo do tempo, tenha em mente que talvez deseje refatorar sua implementação interna no futuro. Mesmo que uma classe não crie nenhum tipo auxiliar interno inicialmente, isso pode mudar à medida que o código evolui. O uso ILoggerFactory acomoda a criação de novos ILogger<TCategoryName> objetos para novas classes sem alterar a API pública.
Para obter mais informações, consulte Como as regras de filtragem são aplicadas.
Preferir log gerado pela origem
A ILogger API dá suporte a duas abordagens para usar a API. Você pode chamar métodos como LoggerExtensions.LogError e LoggerExtensions.LogInformation, ou pode utilizar o gerador de origens de registro em log para definir métodos de registro fortemente tipados. Para a maioria das situações, o gerador de origem é recomendado porque oferece desempenho superior e digitação mais forte. Ele também isola preocupações específicas de registro em log, como modelos de mensagens, IDs e níveis de log do código de chamada. A abordagem não gerada pela fonte é útil principalmente para cenários em que você está disposto a desistir dessas vantagens para tornar o código mais 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);
}
O código anterior:
- Define um
partial classnomeadoLogMessages, que éstaticpara que ele possa ser usado para definir métodos de extensão noILoggertipo. - Decora um método de extensão
LogProductSaleDetailscom o atributoLoggerMessagee o modeloMessage. - Declara
LogProductSaleDetails, que estende oILoggere aceita umquantitye umdescription.
Dica
Você pode entrar no código gerado pela origem durante a depuração, pois ele faz parte do mesmo assembly que o código que o chama.
Usar IsEnabled para evitar avaliação de parâmetros dispendiosa
Pode haver situações em que a avaliação de parâmetros é cara. Expandindo o exemplo anterior, imagine que o parâmetro description é um string cuja computação é dispendiosa. Talvez o produto que está sendo vendido obtenha uma descrição amigável do produto e dependa de uma consulta de banco de dados ou leitura de um arquivo. Nessas situações, você pode instruir o gerador de código-fonte a ignorar a proteção IsEnabled e adicionar manualmente a proteção IsEnabled no local da chamada. Isso permite que o usuário determine onde o guarda é chamado e garante que os parâmetros que podem ser caros para a computação sejam avaliados apenas quando realmente necessário. Considere o seguinte código:
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 o método de extensão LogProductSaleDetails é chamado, a proteção IsEnabled é invocada manualmente e a avaliação do parâmetro dispendioso é limitada ao momento em que é necessário. Considere o seguinte código:
if (_logger.IsEnabled(LogLevel.Information))
{
// Expensive parameter evaluation
var description = product.GetFriendlyProductDescription();
_logger.LogProductSaleDetails(
quantity,
description);
}
Para obter mais informações, confira Geração de origens de registro em log em tempo de compilação e Registro em log de alto desempenho no .NET.
Evite a interpolação de cadeia de caracteres no registro em log
Um erro comum é usar a interpolação de cadeia de caracteres para criar mensagens de log. A interpolação de cadeia de caracteres no log é problemática para o desempenho, pois a cadeia de caracteres é avaliada mesmo se o correspondente LogLevel não estiver habilitado. Em vez da interpolação da cadeia de caracteres, utilize o modelo de mensagens de log, a formatação e a lista de argumentos. Para obter mais informações, consulte Log no .NET: modelo de mensagem de log.
Utilize os padrões de registro em log sem operações
Pode haver ocasiões em que você pode consumir uma biblioteca que expõe APIs de registro em log que esperam um ILogger ou ILoggerFactory, para as quais você não deseja fornecer um agente. Nesses casos, o pacote NuGet Microsoft.Extensions.Logging.Abstractions fornece padrões de log sem operação.
Os consumidores de biblioteca podem usar o padrão de registro em log nulo se nenhum ILoggerFactory for fornecido. O uso do log nulo difere da definição de tipos como anuláveis (ILoggerFactory?), pois os tipos não são nulos. Esses tipos baseados em conveniência não registram nada em log e são essencialmente sem operações. Considere usar qualquer um dos tipos de abstração disponíveis quando aplicável: