CodeGym /Cursos /C# SELF /Logging: Microsoft.Extensi...

Logging: Microsoft.Extensions.Logging

C# SELF
Nível 64 , Lição 0
Disponível

1. Introdução

Em programação logging não é só "mostrar algo no console". Logging é sua caixa-preta, GPS-tracker e indicador tudo-em-um. Sem logs um grande programa vira uma caixa-preta-mistério: "por que o serviço travou?", "por que o usuário não recebeu o e-mail?", "alguém ao menos rodou esse módulo nos últimos 3 meses?" — muitas vezes só dá pra responder essas perguntas se os logs estiverem armazenados e acessíveis.

Por que o logging é necessário na prática?

Busca e diagnóstico de erros
Se o programa caiu — os logs vão contar onde e por quê. Se não caiu, mas está se comportando de forma estranha — os logs vão mostrar os passos que levaram a isso.

Monitoramento do estado
Pelos logs dá pra saber se o sistema está funcionando agora, quantas requisições chegam ao servidor, se erros aparecem, quem e o que está fazendo.

Segurança
Log de tentativas de acesso não autorizado, atividade suspeita, falhas de autenticação.

Auditoria
Quem fez o quê e quando. Se um admin mal-intencionado saiu e apagou dados, pelos logs dá pra reconstruir tudo (ou pelo menos entender o que ele fez).

Suporte no desenvolvimento e operação
Logs não são só para o desenvolvedor, mas também para o tester, operador, admin. Depois de seis meses você vai se agradecer: 'Obrigado por ter adicionado logs!'

De Console.WriteLine ao logging industrial

A reação inicial de quem está começando: "Sério, não basta só Console.WriteLine?". Para programas pequenos de estudo isso realmente é suficiente. Mas quando a aplicação roda no servidor, trabalha em paralelo, ou é usada por dezenas ou centenas de usuários, o console já não ajuda. É preciso:

  • Separar informação importante da informação de debug.
  • Enviar logs não só ao console, mas também para arquivos, bancos de dados, sistemas centralizados.
  • Alterar o nível de verbosidade dos logs (mínimo — só erros, máximo — tudo mesmo).
  • Complementar automaticamente as entradas com data, hora e metadata adicional.
  • Configurar de forma flexível.
  • E o mais importante — não ficar mudando o código só pra redirecionar os logs pra outro lugar.

Aí começa a era dos "loggers de verdade".

2. Fundamentos de um sistema moderno de logging no .NET

No ecossistema .NET existe um framework padrão, poderoso e flexível para logging — Microsoft.Extensions.Logging. Faz parte da "nova onda" de bibliotecas .NET que vieram com o ASP.NET Core, mas hoje é usado em todo lugar: servidor, desktop e até mobile.

O que torna esse framework bom?

  • Abstração — não te prende a uma implementação específica (o logger pode escrever em arquivo, console, cloud ou em todos ao mesmo tempo).
  • Suporte a níveis de logging (Trace, Debug, Information, Warning, Error, Critical).
  • Integração com o DI-container e suporte em todas as aplicações .NET modernas.
  • Ecossistema rico de extensões: suporte a logging estruturado, formatters avançados e integrações.

Conceitos e classes principais

Vamos conhecer os objetos-chave que vamos usar com Microsoft.Extensions.Logging:

Classe/Interface Finalidade
ILogger<T>
Interface para logging, tipada pelo tipo
ILogger
Interface genérica de logger
ILoggerFactory
Fábrica para criar instâncias de loggers
ILoggingBuilder
Permite configurar logging na aplicação
LogLevel
Enumeração de níveis de log (Trace, Debug, Information, ...)

Níveis de logging

Separar mensagens por nível de importância permite filtrar o "ruído" e achar o que importa:

Nível (LogLevel) Quando usar?
Trace
Debug super detalhado, "ruído", dados temporários
Debug
Informação principal para depuração
Information
Mensagens de eventos chaves para funcionamento normal
Warning
Avisos sobre possíveis problemas, mas o sistema continua
Error
Erros que exigem atenção, mas a aplicação ainda está viva
Critical
Falhas críticas que ameaçam todo o sistema

3. Prática: adicionando logging na nossa aplicação

Vamos evitar código abstrato e continuar desenvolvendo nossa aplicação de demonstração. Suponha que já temos uma classe Calculator simples, que vamos expandir ao longo do curso.

Exemplo: calculadora básica

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
    // Outros métodos...
}

Agora vamos embutir logging nela. Para isso precisamos da interface ILogger<Calculator>, que iremos receber de fora (por exemplo, via Dependency Injection, DI).

using Microsoft.Extensions.Logging;

public class Calculator
{
    private readonly ILogger<Calculator> _logger;

    public Calculator(ILogger<Calculator> logger)
    {
        _logger = logger;
    }

    public int Add(int a, int b)
    {
        int result = a + b;
        _logger.LogInformation("Execução de adição: {A} + {B} = {Result}", a, b, result);
        return result;
    }
}

Curiosidade:
Em vez de concatenar strings, os loggers suportam templates e parâmetros nomeados ({A}, {B}, {Result}), o que permite logs estruturados e fáceis de processar e buscar automaticamente depois.

4. Como criar e configurar um logger em um aplicativo de console

1. Adicionando pacotes NuGet

No seu projeto você vai precisar de:

  • Microsoft.Extensions.Logging
  • Microsoft.Extensions.Logging.Console (se quiser escrever no console)
  • (opcional) outros providers, se precisar

2. Configurando o logger

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

// Criamos o DI-container
var serviceProvider = new ServiceCollection()
    .AddLogging(builder => {
        builder.AddConsole(); // Saída para o console
        builder.SetMinimumLevel(LogLevel.Debug); // Nível mínimo de logs
    })
    .BuildServiceProvider();

// Pegamos a instância do logger do tipo necessário
var logger = serviceProvider.GetRequiredService<ILogger<Calculator>>();

var calculator = new Calculator(logger);
calculator.Add(5, 3); // A mensagem vai para os logs

Erro típico de quem está começando
"Por que o log não aparece no console?" — verifique se o provider necessário foi adicionado (.AddConsole()) e se o nível mínimo de logging foi corretamente definido (SetMinimumLevel). Se o nível estiver mais alto, as mensagens podem simplesmente ser "filtradas"!

5. Dicas úteis

Logando erros e situações anômalas

Suponha que queremos logar divisão por zero. Vamos adicionar o método correspondente:

public int Divide(int a, int b)
{
    if (b == 0)
    {
        _logger.LogError("Tentativa de divisão por zero! a={A}", a);
        throw new DivideByZeroException();
    }
    int result = a / b;
    _logger.LogInformation("Execução de divisão: {A} / {B} = {Result}", a, b, result);
    return result;
}

Por que isso é importante?
Em aplicações reais, quando algo dá errado, logs com nível Error normalmente chamam atenção especial: eles são enviados automaticamente para admins, aparecem em monitoramento e acionam alerts/notificações.

Uso de categorias e tags (scopes)

O logger no .NET suporta os chamados scopes — metadados adicionais que são automaticamente adicionados a todos os logs durante um bloco de código. Por exemplo, ao processar uma requisição web ou uma sessão de usuário, você pode adicionar o identificador ao scope.

using (_logger.BeginScope("UserId: {UserId}", 42))
{
    _logger.LogInformation("Iniciou o processamento dos dados do usuário");
    // ...
}

Todas as mensagens dentro do bloco receberão a tag adicional UserId: 42, o que ajuda depois a localizar logs por usuário ou operação.

Exemplo: níveis de logging em ação

_logger.LogTrace("Isso é Trace — quase ninguém vai ver");
_logger.LogDebug("Isso é Debug — para desenvolvedores");
_logger.LogInformation("Isso é Information — para eventos de funcionamento normal");
_logger.LogWarning("Isso é Warning — aviso sobre possível problema");
_logger.LogError("Isso é Error — erro que exige atenção");
_logger.LogCritical("Isso é Critical — O sistema está pegando fogo, precisa de bombeiro!");

Se você configurou SetMinimumLevel(LogLevel.Information), verá apenas mensagens dos níveis Information, Warning, Error, Critical.

Truque:
Deixe logs Trace e Debug para diagnóstico detalhado durante o desenvolvimento, e em produção geralmente habilite só Information e acima, pra não inflar os logs e não perder o que é importante no meio do "ruído".

Diagrama visual: arquitetura do logging moderno

graph TD
A[Código da aplicação] --ILogger<YourClass>--> B[Microsoft.Extensions.Logging]
B --> C1[Console Provider]
B --> C2[File Provider]
B --> C3[Cloud/Database Provider]
C1 -.-> D1[Logs no console]
C2 -.-> D2[Logs em arquivo]
C3 -.-> D3[Logs no sistema de monitoramento]

subgraph Providers
    C1
    C2
    C3
end

6. Funcionalidades adicionais e extensões

Logging estruturado:
Os valores dos parâmetros podem ser armazenados não só como string, mas como chave-valor, permitindo buscas e agregações por esses parâmetros (por exemplo, via Seq, ELK/ElasticSearch ou Application Insights).

Providers de logging:
Você pode adicionar dezenas de providers diferentes: arquivo, Windows EventLog, Azure, etc.

Configurar logging via appsettings.json
No ASP.NET Core o logging pode ser configurado via arquivo de configuração, sem recompilar a aplicação.

Exemplo de configuração de nível mínimo via config (appsettings.json):

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "MyApp.Calculator": "Debug",
      "Microsoft": "Warning"
    }
  }
}

7. Erros típicos ao trabalhar com Microsoft.Extensions.Logging

Erro nº1: Escolha errada do nível de logging.
Usar LogInformation para erros em vez de LogError ou LogCritical dificulta encontrar problemas em produção.

Erro nº2: Ignorar logging estruturado.
Concatenar strings em vez de usar templates com placeholders ({Parameter}) tira proveito do logging estruturado, como buscas por parâmetros.

Erro nº3: Configurar níveis de logging incorretamente.
Se o nível mínimo estiver configurado acima do necessário (por exemplo, Warning em vez de Debug), mensagens importantes podem ser filtradas.

Erro nº4: Logging excessivo ou insuficiente.
Logs muito verbosos (por exemplo, Trace em produção) geram "ruído", e ausência de logs dificulta diagnóstico.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION