Registro em log e rastreamento no .NET

O código pode ser instrumentado para produzir um log, que serve como registro de eventos interessantes que ocorreram durante a execução do programa. Para entender o comportamento do aplicativo, basta analisar os logs. O registro em log e o rastreamento encapsulam essa técnica. O .NET acumulou várias APIs de registro em log diferentes ao longo de seu histórico e este artigo ajudará você a entender quais opções estão disponíveis.

Os termos "registro em log" e "rastreamento" geralmente são sinônimos. A distinção é que a saída de registro em log deve ser coletada o tempo todo e, portanto, deve ter uma sobrecarga baixa. O rastreamento normalmente é mais invasivo e coleta mais informações de partes mais profundas do aplicativo e do runtime do .NET. Ele é usado ao diagnosticar problemas específicos ou automaticamente por curtos períodos de tempo como parte de sistemas de análise de desempenho mais profundos.

Outro pivô no termo de rastreamento é Rastreamento distribuído. O rastreamento distribuído coleta dados de tempo e atividade de alto nível para sistemas baseados em solicitação e correlaciona as solicitações entre serviços para dar uma visão de como cada solicitação é processada pelo sistema completo.

Principais diferenças entre as APIs de registro em log

Registro em log estruturado

As APIs de registro em log podem ser estruturadas ou não estruturadas:

  • Não estruturadas: as entradas de log têm conteúdo em formato de texto livre, destinado à visualização por humanos.
  • Estruturadas: as entradas de log têm um esquema bem definido e podem ser codificadas em diferentes formatos binários ou textuais. Esses logs foram projetados para serem traduzidos e consultados por computador, permitindo que tanto humanos quanto sistemas automatizados trabalhem com eles com facilidade.

As APIs que dão suporte ao registro em log estruturado são as mais indicadas para usos não triviais. Elas oferecem mais funcionalidade, flexibilidade e desempenho com pouca diferença de usabilidade.

Configuração

Para casos de uso simples, talvez você queira usar APIs que gravam mensagens diretamente no console ou em um arquivo. Mas para a maioria dos projetos de software será útil configurar quais eventos de log são registrados e como eles são persistidos. Por exemplo, ao executar em um ambiente de desenvolvimento local, talvez você queira gerar texto sem formatação no console a fim de facilitar a legibilidade. Em seguida, quando o aplicativo é implantado em um ambiente de produção, você pode migrar para o armazenamento dos logs em um banco de dados dedicado ou em um conjunto de arquivos sequenciais. APIs que contam com boas opções de configuração facilitam essas transições, ao passo que opções menos configuráveis exigem a atualização do código de instrumentação a cada etapa para implementar as alterações.

Coletores

A maioria das APIs de registro em log permite que as mensagens de log sejam enviadas para diferentes destinos chamados de coletores. Algumas APIs têm muitos coletores predefinidos, ao passo que outras têm apenas alguns. Se não houver nenhum coletor predefinido, geralmente existirá uma API de extensibilidade que permitirá criar um coletor personalizado, embora isso exija escrever um pouco mais de código.

APIs de registro em log do .NET

ILogger

Na maioria dos casos, seja para a adição de registro em log a um projeto existente ou para a criação de um projeto, a infraestruturaILogger é uma boa opção padrão. ILogger dá suporte a log estruturado rápido, configuração flexível e uma coleção de coletores comuns incluindo o console, que é o que você vê ao executar um aplicativo ASP.NET. Além disso, a interface ILogger também pode servir como uma fachada em várias implementações de log de terceiros que oferecem funcionalidade e extensibilidade avançadas.

O ILogger fornece a história de log para a implementação do OpenTelemetry para .NET, que permite a saída de logs do seu aplicativo para uma variedade de sistemas de APM, permitindo a análise posterior.

EventSource

O EventSource é uma API de rastreamento mais antiga e de alto desempenho com log estruturado. Ele foi originalmente projetado para integrar-se bem ao ETW (Rastreamento de Eventos para Windows), mas posteriormente foi estendido para dar suporte ao rastreamento entre plataformas do EventPipe e ao EventListener para coletores personalizados. Em comparação com ILogger, EventSource tem relativamente poucos coletores de registro em log predefinidos e não há suporte interno para configurar por meio de arquivos de configuração separados. EventSource é excelente se você quiser um controle mais rígido sobre a integração com o ETW ou com o EventPipe, mas para registro em log de uso geral, ILogger é mais flexível e fácil de usar.

Trace

System.Diagnostics.Trace e System.Diagnostics.Debug são as APIs de registro em log mais antigas do .NET. Essas classes têm APIs de configuração flexíveis e um grande ecossistema de coletores, mas só dão suporte ao registro em log não estruturado. No .NET Framework elas podem ser configuradas por meio de um arquivo app.config, mas no .NET Core, não há nenhum mecanismo de configuração interno baseado em arquivo. Normalmente, eles são usados para produzir a saída de diagnóstico para o desenvolvedor durante a execução no depurador. A equipe do .NET continua a dar suporte a essas APIs para fins de compatibilidade com versões anteriores, mas nenhuma nova funcionalidade será adicionada. Essas APIs são uma boa opção para aplicativos que já as utilizam. Para aplicativos mais recentes que ainda não se comprometeram com uma API de registro em log, ILogger pode oferecer funcionalidades melhores.

APIs de registro em log especializadas

Console

A classe System.Console tem os métodos Write e WriteLine que podem ser usados em cenários simples de registro em log. É muito fácil começar a usar essas APIs, mas a solução não fica tão flexível quanto se utilizasse uma API de registro em log de uso geral. O console permite apenas o registro em log não estruturado e não há suporte para configuração a fim de selecionar quais mensagens de log são habilitadas ou redirecionar para outro coletor. O uso das APIs ILogger ou Trace com um coletor de console não requer muito mais esforços e mantém o registro em log configurável.

DiagnosticSource

System.Diagnostics.DiagnosticSource destina-se ao registro em log no qual as mensagens de log serão analisadas de modo síncrono em processo, em vez de serializadas para qualquer armazenamento. Isso permite que a origem e o ouvinte troquem objetos .NET arbitrários como mensagens, enquanto a maioria das APIs de registro em log exige que o evento de log seja serializável. Essa técnica também pode ser extremamente rápida, tratando eventos de log em dezenas de nanossegundos se o ouvinte for implementado com eficiência. As ferramentas que usam essas APIs geralmente agem mais como criadores de perfil no processo, embora a API não imponha nenhuma restrição aqui.

EventLog

System.Diagnostics.EventLog é uma API somente do Windows que grava mensagens no Windows EventLog. Em muitos casos, usar o ILogger com um coletor opcional do EventLog em execução no Windows pode oferecer funcionalidades semelhantes, sem acoplar fortemente o aplicativo ao sistema operacional Windows.