Dominando Logging em Java: Fundamentos e Boas Práticas
Fundamentos de Logging em Java
Neste tutorial, aprenderemos sobre Java Logging e seus vários componentes com a ajuda de exemplos.
Java nos permite criar e capturar mensagens de log e arquivos através do processo de logging.
Em Java, logging requer frameworks e APIs. Java tem framework de logging built-in no pacote java.util.logging.
Também podemos usar frameworks third-party como Log4j, Logback e muitos mais para propósitos de logging.
Componentes do Java Logging
A figura abaixo representa os componentes centrais e o fluxo de controle da API de Java Logging (java.util.logging).

1. Logger
A classe Logger fornece métodos para logging. Podemos instanciar objetos da classe Logger e chamar seus métodos para propósitos de logging.
Vamos ver um exemplo.
Logger logger = Logger.getLogger("novoNomeLogger");
O método getLogger() da classe Logger é usado para encontrar ou criar novo Logger. O argumento string define o nome do logger.
Aqui, isso cria novo objeto Logger ou retorna Logger existente com mesmo nome.
É convenção definir Logger após a classe atual usando classe.getName().
Logger logger = Logger.getLogger(MinhaClasse.class.getName());
Nota: Este método lançará NullPointerException se nome passado for null.
Cada Logger tem nível que determina importância da mensagem de log. Existem 7 níveis básicos de log:
| Nível de Log (ordem decrescente) | Uso |
|---|---|
| SEVERE | falha séria |
| WARNING | mensagem de aviso, problema potencial |
| INFO | informação geral de runtime |
| CONFIG | informação de configuração |
| FINE | informação geral de desenvolvedor (mensagens de rastreamento) |
| FINER | informação detalhada de desenvolvedor (mensagens de rastreamento) |
| FINEST | informação altamente detalhada de desenvolvedor (mensagens de rastreamento) |
| OFF | desliga logging para todos níveis (não captura nada) |
| ALL | liga logging para todos níveis (captura tudo) |
Cada nível de log tem valor inteiro que determina sua severidade exceto dois níveis especiais OFF e ALL.
Registrando a Mensagem
Por padrão, os três níveis de log superiores são sempre logados. Para definir nível diferente, podemos usar o seguinte código:
logger.setLevel(Level.NivelLog); // exemplo logger.setLevel(Level.FINE);
Neste exemplo, apenas nível FINE e níveis acima são definidos para serem logados. Todas outras mensagens de log são descartadas.
Agora para logar mensagem, usamos o método log().
logger.log(Level.NivelLog, "mensagem de log"); // exemplo logger.log(Level.INFO, "Esta é mensagem de nível INFO");
Existem métodos abreviados para logar em níveis desejados.
logger.info("Esta é mensagem de nível INFO"); logger.warning("Esta é mensagem de nível WARNING");
Todas as requisições de log que passaram o nível de log definido são então encaminhadas ao LogRecord.
Nota: Se nível de logger for null, seu nível é herdado do pai e assim por diante na árvore.
2. Filtros (Filters)
Um filtro (se presente) determina se o LogRecord deve ser encaminhado ou não. Como o nome sugere, filtra mensagens de log de acordo com critérios específicos.
Um LogRecord só é passado do logger para o log handler e do log handler para sistemas externos se passar os critérios especificados.
// definir filtro logger.setFilter(filtro); // obter filtro Filter filtro = logger.getFilter();
3. Handlers (Appenders)
O log handler ou appenders recebem o LogRecord e o exportam para vários alvos.
Java SE fornece 5 handlers built-in:
| Handlers | Uso |
|---|---|
StreamHandler | escreve para OutputStream |
ConsoleHandler | escreve para console |
FileHandler | escreve para arquivo |
SocketHandler | escreve para portas TCP remotas |
MemoryHandler | escreve para memória |
Um handler pode passar o LogRecord para um filtro para novamente determinar se pode ser encaminhado a sistemas externos ou não.
Para adicionar novo handler, usamos o seguinte código:
logger.addHandler(handler); // exemplo Handler handler = new ConsoleHandler(); logger.addHandler(handler);
Para remover handler, usamos:
logger.removeHandler(handler); // exemplo Handler handler = new ConsoleHandler(); logger.addHandler(handler); logger.removeHandler(handler);
Um logger pode ter múltiplos handlers. Para obter todos handlers, usamos:
Handler[] handlers = logger.getHandlers();
4. Formatadores (Formatters)
Um handler também pode usar Formatter para formatar o objeto LogRecord em string antes de exportar para sistemas externos.
Java SE tem dois Formatters built-in:
| Formatters | Uso |
|---|---|
SimpleFormatter | formata LogRecord para string |
XMLFormatter | formata LogRecord para forma XML |
Podemos usar o seguinte código para formatar handler:
// formata para forma string handler.setFormatter(new SimpleFormatter()); // formata para forma XML handler.setFormatter(new XMLFormatter());
LogManager
O objeto LogManager mantém controle da informação global de logging. Ele lê e mantém configuração de logging e instâncias de logger.
O log manager é singleton, o que significa que apenas uma instância dele é instanciada.
Para obter instância do log manager, usamos:
LogManager manager = LogManager.getLogManager();
Vantagens do Logging
Aqui estão algumas vantagens do logging em Java.
- ajuda no monitoramento do fluxo do programa
- ajuda na captura de erros que podem ocorrer
- fornece suporte para diagnóstico de problemas e debugging
Java
- Dominando Operadores Java: Tipos, Sintaxe e Exemplos Práticos
- Comentários em Java: Tipos, Uso e Boas Práticas
- Dominando o Loop for Aprimorado em Java: Sintaxe, Exemplos e Boas Práticas
- Dominando Strings em Java: Criação, Métodos e Boas Práticas
- Dominando Interfaces em Java: Conceitos, Implementação e Boas Práticas
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Dominando Try-With-Resources em Java: Gerenciamento Automático de Recursos Explicado
- Anotações em Java Explicadas: Tipos, Posicionamento e Exemplos Práticos
- Asserções em Java: Guia Prático para Detectar Bugs e Garantir Confiabilidade do Código
- Entendendo o Java Vector: Uso, Recursos e Comparação com ArrayList