Registro em aplicações C#: melhores práticas na prática
Registro não é apenas gravar mensagens em um arquivo. É uma ferramenta essencial de monitoramento, depuração e auditoria de qualquer aplicação de produção em C#. Um registro configurado corretamente permite encontrar rapidamente as causas de falhas, analisar o comportamento do sistema e prevenir incidentes. Neste artigo, abordaremos as melhores práticas de registro em .NET que você pode aplicar imediatamente em seus projetos.
1. Escolha da biblioteca: Serilog vs NLog vs ILogger integrado
No .NET moderno, existem três abordagens principais para registro. Vamos analisar seus pontos fortes.
- ILogger integrado (Microsoft.Extensions.Logging) — uma interface abstrata básica. Está integrado ao ASP.NET Core e é minimamente configurável. Adequado para projetos simples, mas requer provedores de terceiros para cenários avançados.
- Serilog — o padrão de facto na indústria. Suporta registro estruturado "pronto para uso", um rico ecossistema de sinks (destinos) e configuração simples através de configuração.
- NLog — um framework maduro com roteamento flexível e suporte a sistemas legados. Destaca-se pelo alto desempenho e configuração detalhada de regras.
Recomendação: para novos projetos, use Serilog — ele se integra melhor com práticas modernas (ELK, Application Insights). Para sistemas de alta carga onde o desempenho é crítico, considere NLog.
// Exemplo de configuração mínima do Serilog em Program.csusing Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();
try{ Log.Information("Aplicação iniciada"); // seu código}catch (Exception ex){ Log.Fatal(ex, "Erro crítico ao iniciar");}finally{ Log.CloseAndFlush();}2. Níveis de registro: quando e o que registrar
A escolha incorreta do nível de registro é um dos erros mais comuns. Vamos analisar cada nível e sua finalidade.
- Trace / Verbose — apenas para depuração pelo desenvolvedor. Nunca ative em produção sem extrema necessidade.
- Debug — informações de diagnóstico para desenvolvimento. Pode ser ativado temporariamente para encontrar um problema.
- Information — operação normal da aplicação: requisições, operações bem-sucedidas, eventos de negócio. Nível principal em produção.
- Warning — problema potencial: pouco espaço em disco, novas tentativas, API obsoleta.
- Error — exceções e falhas que a aplicação tratou, mas o usuário percebeu o problema.
- Fatal / Critical — erros irrecuperáveis que exigem intervenção imediata do administrador.
// Exemplo de uso correto dos níveispublic class OrderService{ private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger) { _logger = logger; }
public async Task<Order> CreateOrderAsync(CreateOrderRequest request) { _logger.LogInformation("Criando pedido para o usuário {UserId}", request.UserId);
try { var order = await _repository.SaveAsync(request); _logger.LogInformation("Pedido {OrderId} criado com sucesso", order.Id); return order; } catch (Exception ex) { _logger.LogError(ex, "Erro ao criar pedido para o usuário {UserId}", request.UserId); throw; } }}3. Registro estruturado: por que é importante
O registro textual tradicional (através de