Introdução: Por que o logging é a base de uma aplicação estável
Qualquer desenvolvedor, especialmente iniciante, mais cedo ou mais tarde se depara com uma situação em que a aplicação falha e é impossível entender o motivo. Sem logs, você está cego. O logging não é apenas gravar mensagens em um arquivo, mas uma ferramenta poderosa de monitoramento, depuração e análise do comportamento do programa. No ecossistema C# (.NET), existem vários frameworks maduros que permitem configurar a saída de logs de forma flexível. Neste artigo, vamos abordar as melhores práticas de logging para iniciantes: desde a escolha da biblioteca até a saída estruturada de dados.
1. Escolha da biblioteca de logging: NLog vs Serilog
Para aplicações .NET, existem dois principais players: NLog e Serilog. Ambos são gratuitos, ativamente mantidos e possuem milhares de integrações. Qual escolher?
NLog
- Simplicidade de configuração via XML ou código.
- Excelente desempenho sob alta carga.
- Suporte nativo para rotação de arquivos, envio de e-mail, gravação em banco de dados.
- Adequado para projetos que precisam de um início rápido sem dependências extras.
Serilog
- Foco em logging estruturado (structured logging).
- Os logs são armazenados não como strings, mas como objetos com campos — isso simplifica a busca e a análise.
- Ideal para microsserviços e sistemas onde os logs são coletados no Elasticsearch ou Grafana.
- A sintaxe com placeholders
{Property}torna o código mais legível.
Dica para iniciantes: Comece com Serilog se planeja trabalhar com ferramentas modernas de monitoramento. Se o projeto for pequeno e local, o NLog será suficiente.
// Exemplo de configuração do Serilog em Program.cs (.NET 6+)using Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();
var builder = WebApplication.CreateBuilder(args);builder.Host.UseSerilog(); // Conecta Serilog ao host2. Níveis de logging: quando e o que registrar
Um dos erros mais comuns de iniciantes é registrar tudo indiscriminadamente no nível Info ou Error. Isso polui os logs e os torna inúteis. No .NET, os seguintes níveis são adotados (em ordem crescente de importância):
- Trace — detalhes mínimos: entrada/saída de métodos, iterações de loops. Usado apenas em depuração profunda.
- Debug — informações de depuração para o desenvolvedor: valores de variáveis, estado de objetos.
- Information — eventos-chave da aplicação: inicialização, parada, processamento bem-sucedido de uma requisição.
- Warning — problemas potenciais que não interrompem o funcionamento: requisição lenta, versão desatualizada de API.
- Error — exceções e falhas que exigem intervenção: erro de banco de dados, timeout.
- Fatal — erros críticos após os quais a aplicação não pode continuar funcionando.
// Exemplo de uso de diferentes níveisILogger<MyService> _logger;
public async Task ProcessOrderAsync(int orderId){ _logger.LogInformation("Início do processamento do pedido {OrderId}", orderId);
try { var result = await _repository.GetOrderAsync(orderId); if (result == null) { _logger.LogWarning("Pedido {OrderId} não encontrado", orderId); return; } // ... lógica } catch (Exception ex) { _logger.LogError(ex, "Erro ao processar o pedido {OrderId}", orderId); throw; // Propaga para cima se não for possível recuperar }}Melhor prática