Criando um Logger de Debug com Marcador em C#

Em aplicações de console C#, a janela Saída do Visual Studio exibe diversas mensagens de carregamento que costumam atrapalhar a leitura das informações importantes. Para isolar o que realmente interessa, podemos criar um helper que adiciona um marcador fixo às mensagens de debug e aproveitar o filtro nativo da janela de saída.

O helper proposto não reimplementa o sistema de saída: ele encapsula os métodos Debug.Write e Debug.WriteLine, prefixando cada linha com uma tag identificável.

  1. Implementação do Helper

using System.Diagnostics;

public static class DebugFilter
{
    private static string _tag = "[DBG]";
    private static bool _needsTag = true;

    public static string Tag
    {
        get => _tag;
        set
        {
            if (!string.IsNullOrEmpty(value))
                _tag = value;
        }
    }

    [DebuggerStepThrough]
    public static void WriteLine(object value)
    {
        if (value is null)
            Debug.WriteLine($"{_tag} nulo");
        else
            Debug.WriteLine($"{_tag} " + value);

        _needsTag = true;
    }

    [DebuggerStepThrough]
    public static void WriteLine()
    {
        Debug.WriteLine(string.Empty);
        _needsTag = true;
    }

    [DebuggerStepThrough]
    public static void Write(object value)
    {
        if (_needsTag)
        {
            if (value is null)
                Debug.Write($"{_tag} nulo");
            else
                Debug.Write($"{_tag} " + value);

            _needsTag = false;
            return;
        }

        Debug.Write(value?.ToString() ?? string.Empty);
    }
}
  1. Controle do Prefixo

O campo _needsTag garante que o marcador seja inserido apenas no primeiro Write após uma nova linha. Dessa forma, vários Write consecutivos formam uma única linha prefixada uma única vez.

  1. Exemplos de Uso

4.1 Linhas completas

DebugFilter.Tag = "[APP]";
DebugFilter.WriteLine("Inicializando serviço...");
DebugFilter.WriteLine("Conexão estabelecida.");

4.2 Compondo uma linha com vários Write

DebugFilter.Write("Processando");
DebugFilter.Write(" ");
DebugFilter.Write("itens");
DebugFilter.WriteLine();

Resultado exibido:

[APP] Processando itens
  1. Aplicando o Filtro

Para mostrar apenas as mensagens de interesse, digite o marcador na caixa de pesquisa da janela Saída do Visual Studio. Linhas sem o prefixo são ocultadas da visualização.

[APP] Inicializando serviço...
[APP] Conexão estabelecida.

Mensagens internas do runtime, sem o prefixo [APP], não aparecem no resultado filtrado.

  1. Atenção à Filtragem por Linha

O filtro da janela Saída atua por linha. Se a lógica produzir uma linha que não contém o marcador, ela será ocultada. Veja o exemplo abaixo:

DebugFilter.Write("Mensagem sem nova linha.");
// A linha acima contém o prefixo, então aparece.
// Se o prefixo só estiver no primeiro Write e a linha for quebrada
// de forma inesperada, parte do texto pode sumir do filtro.

Por isso, quando cada registro precisa ser visível independentemente, prefira WriteLine.

  1. Exemplo Completo

using System.Diagnostics;

public class Program
{
    public static void Main()
    {
        DebugFilter.Tag = "[LOJA]";

        string[] produtos = { "Maçã", "Laranja", "Banana" };
        decimal[] precos = { 4.50m, 3.20m, 2.80m };

        DebugFilter.WriteLine("Relatório de preços");

        for (int i = 0; i < produtos.Length; i++)
        {
            DebugFilter.WriteLine($"Produto: {produtos[i]} - Preço: R$ {precos[i]:F2}");
        }

        DebugFilter.WriteLine("Fim do relatório");
    }
}

Resultado filtrado:

[LOJA] Relatório de preços
[LOJA] Produto: Maçã - Preço: R$ 4,50
[LOJA] Produto: Laranja - Preço: R$ 3,20
[LOJA] Produto: Banana - Preço: R$ 2,80
[LOJA] Fim do relatório

Tags: C# .NET System.Diagnostics.Debug Visual Studio Output Window

Publicado em 7-20 16:57