Pular para o conteúdo
.NETAbstraindo o logging com uma interface
Módulo 03Construindo a Web API

Abstraindo o logging com uma interface

iniciante 25 min de leitura·Atualizado · .NET 9
Resumo

Em vez de espalhar chamadas de log acopladas a um provedor específico, definimos uma interface ILoggerManager bem pequena. Assim a aplicação depende de uma abstração, e trocar o provedor (do ILogger nativo para NLog, Serilog etc.) não impacta o resto do código.

1. Objetivos de Aprendizagem#

  • Justificar por que abstrair o logging por trás de uma interface.
  • Definir uma interface de logging enxuta e coesa.
  • Entender a relação entre a abstração própria e o ILogger<T> do framework.

2. Pré-requisitos#

  • Solução Catalog com o projeto Catalog.Api (Módulo 16).

3. Conceito#

O ASP.NET Core já traz Microsoft.Extensions.Logging com ILogger<T>. Para a maioria dos casos, injetar ILogger<T> diretamente já é o suficiente e é a recomendação oficial.

Ainda assim, uma interface própria (ILoggerManager) é útil como exercício didático de inversão de dependência: as camadas de domínio/serviço passam a depender de uma abstração que você controla, e não diretamente do namespace do framework. O porquê: em arquiteturas em camadas (Módulo 17), a camada de domínio não deve referenciar detalhes de infraestrutura.

Nota

o log estruturado nativo (_logger.LogInformation("Produto {Id} criado", id)) é preferível a concatenar strings, pois preserva os campos para consulta em ferramentas de observabilidade.

4. Mão na Massa#

4.1. Setup#

Crie um projeto de biblioteca para contratos e outro para a implementação (alinhado ao Onion do Módulo 17):

Shell
dotnet new classlib -n Catalog.LoggerService -f net9.0
dotnet new classlib -n Catalog.Contracts -f net9.0
dotnet sln add Catalog.LoggerService Catalog.Contracts
dotnet add Catalog.Api reference Catalog.LoggerService Catalog.Contracts
dotnet add Catalog.LoggerService reference Catalog.Contracts

4.2. Implementação Passo a Passo#

  1. Defina a interface em Catalog.Contracts:
C#
namespace Catalog.Contracts;

public interface ILoggerManager
{
    void LogInfo(string message);
    void LogWarn(string message);
    void LogDebug(string message);
    void LogError(string message);
}
  1. Mantenha-a pequena e estável: quatro níveis cobrem a necessidade da aplicação sem vazar a API do provedor.

4.3. Executando#

Ainda não há implementação; o build deve compilar as bibliotecas:

Shell
dotnet build

5. Exemplo Completo#

C#
// Catalog.Contracts/ILoggerManager.cs
namespace Catalog.Contracts;

public interface ILoggerManager
{
    void LogInfo(string message);
    void LogWarn(string message);
    void LogDebug(string message);
    void LogError(string message);
}

6. Boas Práticas e Armadilhas#

FaçaEvite
Manter a interface mínima e estávelExpor tipos do provedor (ex.: NLog.LogEventInfo) na interface
Colocar o contrato numa camada sem dependências de infraReferenciar o pacote do provedor na camada de domínio
Preferir ILogger nativo quando não precisar da abstraçãoReinventar todo o subsistema de logging sem necessidade
Atenção

ao criar uma abstração própria, você perde o log estruturado nativo se a interface só aceitar string. Considere assinaturas com params object[] se precisar de campos estruturados.

7. Segurança e Produção#

  • Nunca logue dados sensíveis: senhas, tokens, CPF, e-mail, número de cartão. Isso viola LGPD e cria vazamento persistente em arquivos de log.
  • Trate a interface como um ponto único onde você pode aplicar mascaramento/scrubbing de PII.

8. Exercícios#

  • Fácil: adicione um método LogTrace.
  • Médio: discuta os prós e contras de trocar string message por (string template, params object[] args).
  • Desafio: proponha como aplicar mascaramento automático de e-mails na implementação, sem alterar quem chama a interface.

9. Resumo#

Criamos ILoggerManager em uma camada de contratos, desacoplando a aplicação do provedor concreto. Reforçamos que ILogger<T> nativo já atende a maioria dos casos e que log sensível é proibido por compliance.

10. Próximos Passos#

No próximo tópico implementamos essa interface, configuramos o provedor e testamos via injeção de dependência.

11. Referências#

16-05 — Abstraindo o logging com uma interface | Curso ASP.NET Core