0Pricing
Java Academy · Aula

Logging parametrizado

Formatação eficiente de mensagens.

Logging parametrizado é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

O problema da concatenação de strings

Concatenar uma mensagem de registro constrói a string completa antes da chamada, mesmo que o nível esteja desativado.

log.debug("id=" + id + " name=" + name) desperdiça CPU quando DEBUG está desativado, porque a string é construída de qualquer maneira.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String name = "Ada"; int id = 7;
        // Bad: string is built even if DEBUG is disabled
        log.debug("id=" + id + " name=" + name);
    }
}

Marcadores de posição com {}

O SLF4J usa {} como marcador de posição. Passe os valores como argumentos adicionais.

A mensagem só é montada se o nível estiver ativado, portanto os registros desativados praticamente não têm custo.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String name = "Ada"; int id = 7;
        // Good: no string built unless DEBUG is on
        log.debug("id={} name={}", id, name);
    }
}

Vários marcadores de posição

Os marcadores de posição são preenchidos na ordem. O primeiro {} recebe o primeiro argumento, o segundo recebe o segundo, e assim por diante.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("order {} for user {} totaling {} cents", "A-1", 42, 1599);
    }
}

Por que isso é eficiente

A estrutura verifica primeiro o nível. Se ele estiver desativado, retorna imediatamente sem chamar toString() em nenhum argumento.

A parte dispendiosa, a formatação, acontece de forma tardia, somente quando a mensagem realmente será emitida.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String describe(Object o) { System.out.println("toString called"); return o.toString(); }
    public static void main(String[] args) {
        // Note: passing describe(...) still evaluates eagerly; pass the raw object instead
        log.trace("value={}", new int[]{1, 2, 3});
    }
}

Passe objetos brutos, não strings pré-formatadas

Para obter o benefício da execução tardia, passe o objeto bruto, não uma chamada de método que o formate.

Se você escrever log.debug("{}", buildReport()), buildReport() ainda será executado imediatamente. Passe argumentos que o registrador possa formatar por conta própria.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        Object user = new Object();
        // Logger calls user.toString() only if DEBUG is enabled
        log.debug("current user: {}", user);
    }
}

Fornecedores tardios para trabalho pesado

Quando a formatação for realmente dispendiosa, use a API fluente do SLF4J 2.x com um Supplier, para que o trabalho seja adiado.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String heavyReport() { return "...expensive..."; }
    public static void main(String[] args) {
        log.atDebug()
           .setMessage("report: {}")
           .addArgument(() -> heavyReport())
           .log();
    }
}

Escapando uma chave literal

Se precisar de um {} literal na mensagem, escape-o com uma barra invertida: \\{}.

Isso é raro, mas útil ao registrar texto semelhante a JSON.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Logs a literal {} then the value
        log.info("empty object is \\{} and id is {}", 7);
    }
}

Exceção com marcadores de posição

Você pode combinar marcadores de posição com uma exceção ao final. O SLF4J detecta que o último argumento é um Throwable e imprime o rastreamento da pilha.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        int id = 99;
        try {
            throw new RuntimeException("db down");
        } catch (Exception e) {
            log.error("failed processing record {}", id, e);
        }
    }
}

Evite argumentos demais

Se a quantidade de marcadores de posição não corresponder à quantidade de argumentos, o SLF4J fará o possível, mas a saída poderá parecer incorreta.

Mantenha as quantidades correspondentes. Para mais de alguns valores, considere usar contexto estruturado (MDC).

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Two placeholders, two arguments: correct
        log.info("user {} did {}", "ada", "login");
    }
}

Adicionando contexto com MDC

Para valores compartilhados por muitas linhas, como um identificador de solicitação, coloque-os no MDC em vez de repeti-los em cada mensagem.

Assim, o formato do padrão poderá imprimir automaticamente o valor do MDC em todas as linhas.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        MDC.put("requestId", "req-1234");
        try {
            log.info("handling request");
            log.info("request done");
        } finally {
            MDC.clear();
        }
    }
}

Resumo das práticas recomendadas

Regras para um registro eficiente:

  • Use sempre marcadores de posição {}, nunca concatenação com +.
  • Passe objetos brutos, não strings pré-construídas.
  • Use fornecedores ou isXEnabled() para trabalhos realmente pesados.
  • Use o MDC para contexto transversal.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("processed {} items in {} ms", 1000, 42);
    }
}

Verificação rápida

Verifique seus conhecimentos sobre registro parametrizado.

Recapitulação

Você aprendeu sobre o registro parametrizado:

  • Use marcadores de posição {} com argumentos adicionais.
  • As mensagens são construídas de forma tardia, somente quando o nível está ativado.
  • Passe objetos brutos; use fornecedores para trabalhos pesados.
  • Use o MDC para valores de contexto compartilhados.

A seguir, a configuração da implementação de suporte Logback.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("Parameterized logging recap: {}", "done");
    }
}

Perguntas Frequentes

A aula “Logging parametrizado” é grátis?

Sim — o texto completo de “Logging parametrizado” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Logging parametrizado”?

Formatação eficiente de mensagens. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Logging parametrizado”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Por que usar logging estruturado
  2. Fachada SLF4J e loggers
  3. Logging parametrizado
  4. Configurando o Logback
← Voltar para Java Academy