segunda-feira, 26 de abril de 2010

Logs: Um dia você vai precisar deles

Logs são pequenas mensagens que você deixa em seu código para poder analisar a execução do programa e facilitar a tarefa de correção de erros. Neste artigo explicarei como utilizar o Log4j para registrar logs no seu código.

Cenário
Um diz você fez um sistema muito legal, que faz um monte de cálculos complicados, através de uma séria de rotinas ou processos internos e de uma forma mágica, faz aquilo que o cliente pediu. Você instalou em produção e funcionou de primeira. Uma beleza.

Seria perfeito, a não ser pela ligação do cliente no mês seguinte afirmando que o sistema está fazendo o cálculo errado. Você é inteligente e sabe que fez o cálculo certo, não estamos discutindo isso, mas você precisa convencer o seu cliente de que você está certo. Então você tem que ir até o cliente, sentar do lado dele, puxar a forma de cálculo lá do baú de sua memória, fazer todo o cálculo junto com o usuário, explicar passo a passo, até que ele entende que o sistema está certo.

Pronto, problema resolvido, mas bem que isso poderia ter sido evitado. Como? Logs........ E eu não estou falando de System.out.println(), isso é coisa de amador.....

O que é isso?
Logs são pequenos registros que você adiciona dentro do seu código, informando alguns passos importantes de um grande processo ou cálculo, para que posteriormente você possa consultar e verificar o que seu programa está fazendo.

Legal!!!!! Não entendi! Dá para mostrar na prática?
Dá sim, vamos lá. Em primeiro lugar, você precisará de uma API para te ajudar a fazer isso. Você pode usar a API nativa do Java, ou então uma API da Apache, o Log4j (meu favorito :-).

Eu prefiro o Log4j pelos seguintes motivos:
  • Fácil de configurar
  • Flexível, com milhares de opções
  • Muita documentação disponível
  • Amplamente utilizado pela comunidade de Desenvolvedores Java
  • Funciona que é uma beleza :-D
Bom, em primeiro lugar você terá que baixar a API do site e configurar ela no Eclipse, depois disso, você precisará criar um arquivo de configuração, onde você poderá informar o formato do log, o nível de log (explico melhor depois) e aonde você quer gravar o log.

Um arquivo de configuração básico poderia ser o seguinte (nesse exemplo os logs são mostrados na console e também gravados em um arquivo):
# Aqui configuramos o nível de log e aonde queremos que os logs sejam gravados. A primeira palavra "debug", significa que queremos que apenas os logs do tipo debug em diante sejam gravados.
log4j.rootLogger=debug, stdout, R

# Aqui estanos definindo um appender que irá mostrar as mensagens de log na console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Aqui configuramos o formato do log
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

# Aqui configuramos outro appender, agora para um arquivo
log4j.appender.R=org.apache.log4j.RollingFileAppender

# Aqui definimos o nome do arquivo
log4j.appender.R.File=example.log

# Aqui definimos o tamanho máximo do arquivo
log4j.appender.R.MaxFileSize=100KB

# E aqui definimos o número máximo de arquivos de log que queresmos que sejam gerados.
log4j.appender.R.MaxBackupIndex=1

# Definição do formato do log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
Depois disso, você pode gravar seus logs fazendo o seguinte:
package src;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class Main {

/**
 * Instância do logger. Você pode colocar uma linha como essa em todas as
 * suas classes que precisam gravar log. Tome cuidado para trocar o nome da
 * classe.
 */
 private static Logger logger = Logger.getLogger(Main.class);

 public static void main(String[] args) {

   // Configuração do log4j através do arquivo
   PropertyConfigurator.configure("src/src/log4j.config");

   // Depois disso você já pode usar o atributo logger para gravar todos os
   // logs que quiser.

   // Você pode gravar como debug as partes de um grande cálculo ou grande
   // processamento.
   logger.debug("Resultado parcial de um cálculo bem complicado: 42");

   // Pode-se usar o info para registrar informações importantes, como por
   // exemplo, sempre que o sistema enviar um email.
   logger.info("Enviado email para o destinatário foo@bar.com");

   // Quando algo não previsto acontecer, você pode usar um aviso (warning)
   logger.warn("Ops... Essa linha não deveria ter executado.");

   // E quando ocorrer algum erro, você pode gravar a execeção toda,
   // para depois poder analisar
   try {
     int i = 2 / 0;
   } catch (Exception exception) {
     logger.error(":-S Algo deu errado no cálculo....", exception);
   }
 }
}
Ao executar esse programa, o resultado do log será o seguinte:
DEBUG main src.Main - Resultado parcial de um cálculo bem complicado: 42
INFO main src.Main - Enviado email para o destinatário foo@bar.com
WARN main src.Main - Ops... Essa linha não deveria ter executado.
ERROR main src.Main - :-S Algo deu errado no cálculo....
java.lang.ArithmeticException: / by zero
at src.Main.main(Main.java:37)
Os níveis de logs que o Log4j oferece são os seguintes (em ordem de gravidade da mensagem que será gravada):
trace > debug > info > warn > error > fatal
No seu arquivo de configuração, se você informar que o nível de log que deseja é INFO, então apenas as mensagens do tipo, INFO, WARN, ERROR e FATAL serão gravadas no log. E funciona da mesma forma com os outros níveis.

Boas práticas: Onde colocar logs?!
  • Procure colocar logs do tipo INFO ou DEBUG em partes de grandes cálculos ou processamentos longos, colocando os valores parciais ou o andamento do processamento.
  • SEMPRE, eu disse SEMPRE, coloque logs do "catch" de exceções. Assim você sempre terá informações para saber onde o erro está acontecendo.
  • Em ambiente de desenvolvimento, mantenha o nível de log em DEBUG, quando for para produção, podes colocar como INFO ou WARN.
  • Quando for necessário mais detalhes sobre o log, apenas mude o arquivo de configuração e reinicie a aplicação. Não é necessário recompilar.
  • Não se preocupe em ter os logs espalhados em seu código, use-os o quanto quiser. Na hora que precisar, você terá a informação necessária. Melhor do que se arrepender de não ter colocado :-p
Para mais informações sobre o Log4j, visite: logging.apache.org/log4j/1.2/manual.html

Por hoje é só, não esqueçam de comentar.

Nenhum comentário:

Postar um comentário