Esse artigo faz parte da revista Java Magazine edição 05. Clique aqui para ler todos os artigos desta edição

Clique aqui para ler esse artigo em PDF.imagem_pdf.jpg

Logging no J2SE 1.4

Um introdução à API java.util.logging

Como utilizar as novas classes do J2SE 1.4 para melhorar o processo de logging em aplicações Java

Neste artigo trataremos de um aspecto muito importante no desenvolvimento de software, que muitas vezes não é tratado com a devida importância: o uso de mensagens de log – ou logging. O processo de logging é muito importante, pois propicia um canal de comunicação entre a aplicação e o usuário, que pode ser usado pelos desenvolvedores na depuração de aplicações (principalmente em circunstâncias onde não é possível o uso de um software depurador). Para aplicações em  produção, o logging pode ser usado tanto para passar informações úteis ao usuário final quanto para diagnosticar o funcionamento interno da aplicação aos técnicos de suporte.

Embora existam várias soluções de logging para Java no mercado, como o excelente log4j do projeto Apache Jakarta e o Logging Toolkit for Java da IBM, somente na versão 1.4 do J2SE foi introduzida uma API para logging, que analisaremos aqui.

O que é logging?

Traduzindo ao pé da letra, “log” seria o equivalente a anotações ou registro de acontecimentos. Assim, “logging” poderia ser traduzido como o processo de registrar mensagens a partir de uma aplicação. Embora esse conceito possa parecer algo novo, ele é utilizado em muitas aplicações, muitas vezes sem nos darmos conta disso.

Na Listagem 1, por exemplo, está uma pequena aplicação que recebe como parâmetro um número inteiro e cria um servidor na porta definida pelo número passado. Note que estamos usando os objetos System.out e System.err para relatar as ações e exceções da aplicação.

Podemos dizer que o uso de System.out (e System.err) é uma forma primitiva de logging. Essa solução, no entanto, tem muitas desvantagens:

·         Falta de flexibilidade; se desejarmos mudar o comportamento do processo de logging, é necessário mudar cada chamada aos métodos de System.out/System .err;

·         As mensagens vão sempre para o mesmo destino (o console) e muitas vezes a informação é perdida (a não ser que haja um redirecionamento da saída do console para um arquivo);

·         Não há controle se o logging está habilitado ou não; as mensagens serão sempre publicadas;

·         As mensagens não recebem formatação especial (poderiam ser formatadas em XML, por exemplo) nem informações adicionais (como a hora em que foram geradas e a classe geradora).

Alternativas

Uma solução intermediária é a criação de uma classe especial para logging. Na Listagem 2 é  usada a classe MyLogger (definida na Listagem 3). Como estamos usando uma classe à parte, as chamadas de logging são mais simples e a flexibilidade muito maior. Se depois decidirmos gravar as mensagens em um arquivo ou desabilitar o logging, basta mudarmos apenas o código na classe de logging (e não em cada chamada a System.out, por exemplo).

Pois bem, a nova API do J2SE 1.4  – e os outros produtos já citados – segue exatamente essa linha de raciocínio. Ela é composta pelo pacote java.util.logging (a Figura 1 mostra o diagrama de classes do pacote).

Conceitos

Antes de continuarmos com uma descrição mais detalhada de cada classe, é importante apresentarmos alguns conceitos utilizados pela API:

Hierarquia – todo objeto Logger (responsável pela criação de mensagens) tem um nome e está associado a outros Loggers através de uma hierarquia de nomes – se um objeto tem o nome a, é o pai do objeto a.b na hierarquia. O significado da hierarquia fica a cargo do desenvolvedor, mas o ideal é seguir a estrutura de pacotes da aplicação (por exemplo: jm5.artigos, jm5.artigos.logging, artigos.logging.rede, artigos.logging.exemplos); outra opção é organizar os objetos segundo suas funcionalidades (por exemplo: myApp.network, myCompany.framework.ejb). Além disso, cada objeto herda algumas características de seus ancestrais (como o nível de log), mas essas características podem ser redefinidas.

Nível de log – toda mensagem de log (LogRecord) tem um nível associado a ela, que determina se a mensagem será publicada ou descartada (veja mais adiante).

Classes em detalhe

Vamos analisar as principais classes do pacote de logging do J2SE 1.4:

LogRecord

Um objeto LogRecord representa a mensagem de log. Além da mensagem em si (um String) e do seu nível (um objeto Level), contém outras informações úteis, como um identificador para a thread que gerou a mensagem e a hora em que foi gerada, o nome da classe e do método gerador (quando for possível para a JVM deduzir tais informações) e um número de seqüência.

Level

O objeto Level define o nível de uma mensagem; isso determina se a mensagem será descartada ou não pelos objetos Logger e Handler. Quando um objeto Logger recebe uma mensagem de log, ele checa o nível da mensagem com o seu nível atual – ou dos seus ancestrais na hierarquia de objetos; caso o Logger não possua uma referência a um objeto Level. Se o nível da mensagem for menor que o nível do Logger, a mensagem é descartada.

Os níveis em si são representados por uma variável do tipo inteiro; os seguintes estão disponíveis (são constantes estáticas na classe Level), listados em ordem decrescente de severidade ou importância:

·         SEVERE (maior valor) – erros críticos;

·         WARNING – erros não-críticos;

·         INFO – mensagens informativas;

·         CONFIG – usada em código de configuração;

·         FINE, FINER e FINEST (menor valor) – níveis usados pelos desenvolvedores para fornecer detalhes do funcionamento da aplicação (o equivalente ao nível “traceusado em outros produtos);

Além dos níveis progressivos, existem dois especiais:

...

Quer ler esse conteúdo completo? Tenha acesso completo