Se você ainda utiliza o comando “System.out.println” para depurar partes do seu código, você está fazendo isso errado. Fazendo uma analogia com outra realidade, usar o “System.out.println” para debug é como comprar um carro de passeio para transportar chumbo.

Primeiro que você não tem controle algum sobre depuração com este comando, imagine que você tem 200 destes espalhados pelo código e agora quer tirá-los para por seu sistema em produção.

Possivelmente você esquecerá-se de alguns e acabará deixando-os em produção.

Outro método de depuração é a própria depuração da IDE, aquele em que você segue passo a passo do código. Este por sua vez é muito bom, mas depende para o que você precisa, pois se você precisa saber o valor de 1 variável em tempo de execução (run-time) e tem que passar por laços e loops complexos apenas para saber este valor, não vale nenhum pouco a pena utilizar este tipo de depuração.

Então, como solução surgiu o Logging que é uma forma de depuração “parecida” com o “System.out.println” (usado de forma errada obviamente). A vantagem de usar o Logging é que este oferece muitas funcionalidades a mais como: definir níveis de mensagem, desabilitar determinados níveis de mensagem sem precisar ficar procurando onde elas estão.

Log4j como alternativa para o Logging

Como alternativa para o Logging oferecido nativamente pelo Java, surgiu o Log4j que realiza em suma as mesmas função do Common Logging porém algumas funcionalidades extras.

Na seção de links deste artigo você encontrará o download do Log4j que deve ser adicionado no CLASSPATH do seu projeto.

O Log4j divide os logs em 5 níveis hierárquicos, sendo desde o nível mais baixo até o nível mais “severo”. São eles: DEBUG, INFO, WARN, ERROR, FATAL. A vantagem de utilizar esses níveis é que você pode dizer qual nível a aplicação deve implementar.

Os níveis de log estão de forma crescente por nível de severidade (DEBUG, INFO, WARN, ERROR e FATAL), sendo que se você ativar o nível INFO, automaticamente todos os níveis acima de INFO e claro o próprio INFO. Se você ativar o ERROR apenas ele e o FATAL será ativado.

Após entendermos os níveis do Log4j e termos configurado este em nosso projeto (no CLASSPATH) vamos criar um arquivo de properties onde ficarão as configurações globais do Log4j. Você também pode realizar as mesmas configurações de forma programática.

Listagem 1: Arquivo de Properties do Log4j


#### Usando 2 appenders, 1 para logar no console, outro para um #arquivo, 
#### ou seja, mostrará o log no console e salvará em um arquivo

log4j.rootCategory=WARN,stdout,fileOut

# Imprime somente mensagens com 'priority' WARN ou mais alto para o #logger
#lembrando a ordem: DEBUG - INFO - WARN - ERROR - FATAL
log4j.category.br.com.pacote1=INFO

#### O primeiro appender escreve no console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
### Pattern que mostra o nome do arquivo e numero da linha, porem #sem data e hora
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

#### O segundo appender escreve em um arquivo e faz um bkp ao #atingir o max 
log4j.appender.fileOut =org.apache.log4j.RollingFileAppender
log4j.appender.fileOut.File=meulog.log
### Controla o tamanho maximo do arquivo
log4j.appender.fileOut.MaxFileSize=100KB
### Faz backup dos arquivos de log (apenas 1)
log4j.appender.fileOut.MaxBackupIndex=1
log4j.appender.fileOut.layout=org.apache.log4j.PatternLayout
#####este formato esta em ingles: 2011-04-24 e imprime o nro da #linha L
log4j.appender.fileOut.layout.ConversionPattern=%d [%t] %5p %c:%L - %m%n
####imprime no formato dia/mes/ano 
#log4j.appender.fileOut.layout.ConversionPattern=%-2d{dd/MM/yy HH:mm} [%t] %5p %c:%L - %m%n

Vamos agora definir um método de inicialização para utilização do Log4j. Fique atento na linha “log4j.category.br.com.pacote1=INFO”. Aqui definimos que tudo que estiver dentro do pacote1 estará definido com o nível INFO. Na listagem 2 mostramos um método Main que está dentro do pacote1, e automaticamente só as mensagens de INFO para cima serão mostradas, ou seja, DEBUG não serão mostrados.

Listagem 2: Inicializando Log4j


public static void main(String[] args) {
  Logger logger = Logger.getLogger("br.com.MinhaClasse");
  logger.info("Iniciando procedimentos");
   Venda venda = new Venda();
  logger.debug("Criando novo objeto venda");
   venda.setNumeroOcorrencia("1234");
   venda.setObs("MINHA VENDA XX");
   VendaDao vendaDao = new VendaDao();
   vendaDao.save(venda);
  logger.info("venda salvo no banco com sucesso");

No código acima só as mensagens do INFO são mostradas, pois definimos esse nível na nossa aplicação. Geralmente quando trabalhamos em produção deixamos assim, e quando trabalhamos com o desenvolvimento e testes deixamos o nível DEBUG habilitado.

A nomeação do Logger é muito importante, pois se você dar qualquer nome como por exemplo: “meulogger” quando o resultado aparecer no console ele será como o resultado abaixo:

Listagem 3: Definindo nome “meulogger”


INFO [main] (meulogger:3) - Iniciando procedimentos

Mas o “meulogger:3” não nos diz nada, onde fica essa linha ? Em qual local do meu código com 3 mil classes ? Por isso devemos sempre definir o path completo da classe na definição de um Logger, como no exemplo abaixo.

Listagem 4: Definindo nome do Logger com o Path completo


Logger logger = Logger.getLogger("br.com.pacote1.MinhaClassePrincipal");

O resultado disso você confere na listagem 5.

Listagem 5: Resultado do Logger com Path definido na sua nomeação


INFO [main] (br.com.pacote1.MinhaClassePrinicipal:3) - Iniciando procedimentos

Agora sim, sabemos que essa INFO está vindo exatamente da classe MinhaClassePrincipal do pacote1, que está dentro do pacote “com” que está dentro do pacote “br”.

CONCLUSÃO

O Log4j é uma ferramenta muito poderosa para depuração da sua aplicação. Grandes projetos não deixar isso passar em branco, pois este é essencial para saber o que de fato sua aplicação está fazendo sem precisar ficar depurando com a própria IDE.

Links