Por que sua aplicação C# está gritando e você não ouve?
\nImagine: você lança uma nova versão de um microsserviço em C# à meia-noite. Tudo funciona perfeitamente... nos primeiros 10 minutos. E então — puf! — os usuários reclamam de lentidão, e você está diante de um arquivo de log de 2 GB tentando encontrar uma agulha no palheiro. Familiar? Se não, ou você é um gênio ou nunca lidou com monitoramento de verdade.
\nNeste artigo, vamos mostrar como transformar o caos dos logs em um sistema organizado. Você aprenderá a configurar o logging em C# para não enlouquecer nos deploys e a construir um monitoramento de aplicações que realmente ajuda, não apenas desenha gráficos bonitos.
\n\nPor onde começar: a filosofia do logging correto
\nMuitos desenvolvedores pensam: "Vou usar Console.WriteLine e está tudo certo". Spoiler: não, não está. O verdadeiro logging em C# é o structured logging (logging estruturado). Em vez de strings como:
\nLog.Info("User " + userId + " comprou item " + itemId);\nVocê escreve:
\nLog.Information("User {UserId} comprou item {ItemId}", userId, itemId);\nA diferença é colossal. No segundo caso, você pode filtrar logs por UserId, criar dashboards e encontrar problemas rapidamente. Essa é a base do diagnóstico de erros em C# em produção.
Escolhendo a biblioteca: Serilog vs NLog vs log4net
\nNo ecossistema .NET, existem três principais players. Vamos compará-los com base em critérios importantes para projetos reais:
\n- \n
- Serilog — o favorito do .NET moderno. Ideal para structured logging, fácil de configurar, suporta sinks (saída para arquivo, banco, Elasticsearch). Recomendo para novos projetos. \n
- NLog — um veterano com configuração flexível via XML/JSON. Ótimo para sistemas legados onde já é utilizado. \n
- log4net — o mais antigo, é melhor não mexer sem extrema necessidade. Suporte capenga, structured logging com gambiarras. \n
Para rastreamento .NET em aplicações modernas, Serilog é a escolha nº 1. Vamos configurá-lo em 5 minutos.
\n\nConfiguração do Serilog em C#: guia passo a passo
\nInstale os pacotes via NuGet:
\ndotnet add package Serilog\ndotnet add package Serilog.Sinks.Console\ndotnet add package Serilog.Sinks.File\ndotnet add package Serilog.Sinks.Seq\nAgora, a configuração mínima no Program.cs para ASP.NET Core:
using Serilog;\n\nLog.Logger = new LoggerConfiguration()\n .MinimumLevel.Information()\n .WriteTo.Console()\n .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day)\n .WriteTo.Seq("http://localhost:5341") // para monitoramento avançado\n .CreateLogger();\n\ntry\n{\n Log.Information("Iniciando aplicação web");\n var builder = WebApplication.CreateBuilder(args);\n builder.Host.UseSerilog(); // integração com o host\n // ... resto da configuração\n var app = builder.Build();\n app.Run();\n}\ncatch (Exception ex)\n{\n Log.Fatal(ex, "Aplicação encerrada inesperadamente");\n}\nfinally\n{\n Log.CloseAndFlush();\n}\nObserve o rollingInterval — os logs serão rotacionados diariamente, em vez de crescerem infinitamente. Essa é a base do logging assíncrono em produção.
Logs estruturados: como extrair o máximo de valor
\nSuponha que temos um método de processamento de pedido. Sem estruturação, você escreveria:
\nlogger.LogInformation("Processando pedido {OrderId} para usuário {UserId}", order.Id, user.Id);\nCom Serilog, isso se transforma em um objeto JSON que pode ser parseado. E se você adicionar contexto via ILogger<T>:
public class OrderService\n{\n private readonly ILogger<OrderService> _logger;\n\n public OrderService(ILogger<OrderService> logger)\n {\n _logger = logger;\n }\n\n public async Task ProcessOrderAsync(Order order, User user)\n {\n _logger.LogInformation("Processando pedido {OrderId} para usuário {UserId}", order.Id, user.Id);\n // lógica do pedido\n }\n}\nIsso permite buscas precisas e correlação de eventos — essencial para observabilidade em sistemas distribuídos.
\n\nMonitoramento com Application Insights: indo além dos logs
\nLogs são ótimos, mas para um monitoramento de aplicações completo, você precisa de métricas e traces. O Application Insights (Azure) se integra perfeitamente com Serilog:
\ndotnet add package Microsoft.ApplicationInsights.AspNetCore\ndotnet add package Serilog.Sinks.ApplicationInsights\nConfigure no appsettings.json:
{\n "ApplicationInsights": {\n "InstrumentationKey": "sua-chave-aqui"\n }\n}\nE no Program.cs:
builder.Services.AddApplicationInsightsTelemetry();\n\nLog.Logger = new LoggerConfiguration()\n .WriteTo.ApplicationInsights(builder.Services.BuildServiceProvider().GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces)\n .CreateLogger();\nAgora você tem logs, métricas e traces centralizados. Quando algo der errado, você não precisa mais caçar manualmente — os dados estarão organizados e prontos para análise.
\n\nBoas práticas para logging em produção
\n- \n
- Use níveis de log corretamente:
Verbosepara desenvolvimento,Informationpara fluxos normais,Warningpara situações inesperadas,Errorpara falhas,Fatalpara crashes. \n - Evite logs excessivos: Logar cada requisição pode gerar ruído. Foque em eventos de negócio e erros. \n
- Proteja dados sensíveis: Nunca logue senhas, tokens ou informações pessoais (LGPD/GDPR). \n
- Centralize os logs: Use ferramentas como Seq, Elasticsearch ou Application Insights para agregar logs de múltiplos serviços. \n
Com essas práticas, seu logging C# passará de um amontoado de texto para uma ferramenta poderosa de diagnóstico. E quando a aplicação "gritar", você estará pronto para ouvir e agir.