Tags:
create new tag
, view all tags
-- JoaoCarreira - 15 Dec 2009
Descrição Geral

No xeo foi criado um sistema de logging de forma a criar um nível de abstração sobre os loggers actualmente utilizados. Nesta versão o log4j foi acualizado para a versão 1.2.15 que é utilizado internffamente pelo XEO.

Esta implementação pretende normalizar o logging no XEO assim como em aplicações desenvolvidas sobre a plataforma.

Se não for especificado qualquer configuração no boconfig.xml, o sistema utiliza a parameterização geral do log4j, ou seja o log4j.properties.

Arquitectura do Logger

O sistema de logger é constituido por dois níveis. O logger e ou Appender.

Os loggers são os elementos que definem quais os packages que devem ser logados assim como o formato de escrita no log. Por cada logger existem appenders, que podem ser os seguintes:

  • console - Este appender escreve as mensagens de log na standard output do java
  • file - Este appender cria ficheiros de log com um limite pre-definido de tamanho
  • email - Este appender envia os erros por email para os destinatários configurados. Este logger não funciona em todos os níveis, só superiores a WARNING.

Podem existir varios loggers com diferentes appenders, caso se pretenda que determinados packages sejam logados de formas distinctas.

Como usar

Obter um logger para uma class

import netgest.bo.system.Logger;
(...)
private static final Logger logger = Logger.getLogger(MyClass.class);

Escrever no log

logger.warn("Something went wrong. Message");

Performance

Quando se está a fazer logging deve-se ter alguma atenção quanto às questões de performance. Por exemplo, evitar que mensagens sejam criadas se o logger não está activo para determinado nível.

Quando se está a fazer loging deverá sempre colocar-se o código dentro de um if que interrogará o logger se este está activo para determinado nível.

Errado

logger.finest("Entrando na class " + this.getClass().getName )

Correcto

if( logger.isFinestEnabled() ) 
    logger.finest("Entrando na class " + this.getClass().getName ) 

Na segunda forma, evitamos que a string seja concatenada com o nome da class quando o nível FINEST não está activo.

Configuração do Logging no XEO (bo-config.xml)

Níveis de logging e respectivos casos de uso:

# Nivel Texto no Log Descrição
1 FINEST FINST Este nível deve ser utilizado para fazer de debug de comportamentos. Este nivel nunca deve estar activo em produção
2 FINER FINER Este nível deve dar informação relevante de trace de erros, como seja chamada a API's externas, resultados de leitura de configurações de runtime
3 FINE FINE Nível de log alargado, ou seja dá informação sobre execução de tarefas de background, resultado de chamadas a API externas como envio de emails, chamadas a webservices, etc.
4 CONFIG CONF Informação sobre configuração do Sistema, atenção, não fazer log the passwords
5 WARNING WARN Informação de avisos não criticos, ou seja erros pouco comuns, mas que o utilizador é notificado que ocorreram
6 SEVERE SEVER Erros que impedem o bom funcionamento do sistema, tais como queries mal escritas, viewers/objectos com erros de sintaxe na definição, etc...

Configuração no bo-config.xml

Configuração geral do logger:

Atributo Valores Possiveis Descrição
active true/false Se este logger está activo ou não
for String separada por virgulas Packages que esta configuração para os quais esta configuração deve ser usada
level FINEST / FINER / FINE / CONFIG / WARNING / SERVERE Nivel de log que deve ser feito por esta configuração
pattern Formato de escrita do log do tipo log4j Formato de escrita no Log

Configuração dos appender console:

Atributo Valores Possiveis Descrição
active true/false Activar ou desactivar este appender

Configuração do appender file:

Atributo Valores Possiveis Descrição
active true/false Activar ou desactivar este appender

logFile

Nome do ficheiro de log

Caminho relativo ao xeoHome ou absoluto da localização e nome do ficheiro de log

maxSize nn / nnKB / nnMB Tamanho máximo do ficheiro de log.
backupFiles n Número de ficheiros que devem ser guardados em histórico após o limite do log ser ultrapassado

Configuração do appender (Este appender só funciona para log's superiores a WARNING) email:

AtributoSorted descending Valores Possiveis Descrição
to email address Endereço do destinatário do email
subject String Texto do assunto do email
smtpHost hostname Servidor SMTP a usar para envio dos erros de log
from email address Endereço de email do remetente
cc email address Endereço CC do email
buffer n Número de messagens anteriores no log que devem ser enviadas no corpo do email
bcc email address Endereço BCC do email
active true/false Activar ou desactivar este appender
Exemplos de configuração

Este logger está configurado para fazer logging em todas as classes que estejam na hierarquia do package pt e netgest. O nivel de log é o FINEST por isso, o log será extenso. Como o appender email está desactivado, as mensagens de WARNING e SEVERE não serão enviadas por email.

<logConfig>
 <logger active='true' for='pt,netgest' level='FINEST' pattern='%d %5p [%t] (%F:%L) - %m%n' >
  <console active='true'  />
  <file active='true' logFile='.\log\fileName.log' backupFiles='5' maxSize='50MB' />
  <email active='false' buffer='50' smtpHost='mail.itds.pt' from='' to='jp[a]itds.pt' cc='' bcc='' subject='ola' />
 </logger>
</logConfig>

Log com exemplo de niveis diferentes e appenders por package. Esta configuração faz o log em mode FINEST para a consola, ficheiro e email de todas as classes que estejam no package pt. Para as classes que estejam no package netgest, escreve na consola apenas as mensagens de CONFIG ou superiores.

<logConfig>
 <logger active='true' for='pt' level='FINEST' pattern='%d %5p [%t] (%F:%L) - %m%n' >
  <console active='true'  />
  <file active='true' logFile='.\log\fileName.log' backupFiles='5' maxSize='50MB' />
  <email active='true' buffer='50' smtpHost='mail.itds.pt' from='' to='destemail' cc='' bcc='' subject='ola' />
 </logger>
 <logger active='true' for='netgest' level='CONFIG' pattern='%d %5p [%t] (%F:%L) - %m%n' >
  <console active='true'  />
 </logger>
</logConfig>

Exemplo de uma class a utilizar o logging

Exemplo de utilização numa class desenvolvida:

package pt.logger;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

import netgest.bo.system.Logger;
import netgest.bo.system.boApplication;

public class LoggerDemo {
   
   // Initialize the logger for the class
   private static final Logger logger = Logger.getLogger( LoggerDemo.class );
   
   public static void main( String[] args ) {
      // Call some sample methods
      loggedMethod();
      doSomeWork();
   }
   
   public static void doSomeWork() {
      FileWriter fw;
      PrintWriter pw;
      File propsFile;
      
      // Log configuration info to the logger
      logger.config("xeoHome is [%s]", 
            boApplication.getApplicationFromStaticContext("XEO")
               .getApplicationConfig().getNgtHome()
            );
      
      propsFile = new File("c:\\jvmprops.txt");
      
      if( propsFile.exists() ) {
         // Warning - the previous file was overwritten
         logger.warn("Overwritting file %s ", propsFile.getName() );
      }
      else {
         if( logger.isFineEnabled() )
            // Fine - Creating a file
            logger.fine("Creating file %s ", propsFile.getName() );
      }
      
      try {
         fw = new FileWriter( propsFile );
         pw = new PrintWriter( fw );
         
         if( logger.isFinestEnabled() ) {
            // Finest - Filling a file
            logger.finest("Dumping properties to [%s]", propsFile.getAbsolutePath() );
         }
         
         for( Object propName : System.getProperties().keySet() ) {
            pw.format( "%s : %s \n", propName, System.getProperty( propName.toString() ) );
         }
         
         pw.close();
         if( logger.isFinestEnabled() ) {
            // Finest - Closing the file
            logger.finest("Closing file [%s]", propsFile.getAbsolutePath() );
         }
         fw.close();
      } catch (IOException e) {
         // Severe - Something goes wrong writing the file
         logger.severe( "Error writing to file [%s]" , e, propsFile.getAbsolutePath() );
      }
   }
   
   public static void loggedMethod() {
      // Finest - tracing method call's
      logger.finest( "Entering in method: %s", "loggedMethod" );
      // Do Work
      // (...)

      logger.finest( "Exiting in method: %s", "loggedMethod" );
   }
   
}

Topic attachments
I Attachment Action Size Date Who Comment
Java source code filejava LoggerDemo.java manage 2.1 K 2009-12-21 - 20:49 JoaoCarreira Código fonte da class de demonstração
Edit | Attach | Print version | History: r8 | r6 < r5 < r4 < r3 | Backlinks | Raw View | Raw edit | More topic actions...
Topic revision: r4 - 2009-12-21 - JoaoCarreira
 

No permission to view TWiki.WebTopBar

This site is powered by the TWiki collaboration platform Powered by Perl

No permission to view TWiki.WebBottomBar