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:

# NivelSorted descending Texto no Log Descrição
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...
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

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:

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