Enterprise-level Logging
     com Log4perl


        Breno G. de Oliveira
         <garu@cpan.org>
O que pode dar errado?
Tudo.
O que pode dar errado?


     Dados externos

     Configurações

     Sistema de arquivos

     Estados inconsistentes

     Casos especiais ou extremos
Apagar incêndio é pra bombeiro.
Logging debugging tradicional


 Chamadas ao “print” espalhadas

 Chamadas “warn” espalhadas

 Dump de estruturas de dados (Data::Dumper)

 Rastreamento (“trace”) manual

 perl -d
Problemas com o debugging tradicional


      ●   Reativo

      ●   Custoso

      ●   Não escala bem
Logging tradicional


  sub debug {
        print “@_n”;
  }

  ...

  debug( “cheguei até aqui” );
Problemas com o logging tradicional


      ●   Reativo

      ●   Custoso

      ●   Não escala bem
E agora?


      ●   Fazemos o nosso...

      ●   ...não!
TIMTOWTDI
              BCINABT

●   There is More Than One Way To Do It...

●   ...But Consistency Is Not A Bad Thing
Log::Log4perl

  ●   Implementação do Log4j para Perl

  ●   Controle do número de mensagens, por
      log level e componentes

  ●   Definição dinâmica do alvo das mensagens
      (appenders)

  ●   Formatação de mensagens

  ●   Configuração externa
Log levels

                            TRACE

                        DEBUG

                     INFO


                 WARN


               ERROR

             FATAL
Modo Simples


   use Log::Log4perl qw(:easy);
   Log::Log4perl­>easy_init( $INFO );




   DEBUG “Isso nao eh exibido”;

   INFO “Mas isso eh o/”;

   ERROR “E isso tambem!”;
Modo Avançado: Inicialização

  use Log::Log4perl;
  Log::Log4perl­>init( 'log.conf' );




  Log::Log4perl­>init_once( 'log.conf' );




Log::Log4perl­>init_and_watch( 'log.conf', 10 );
Usando

 package Foo::Bar;
 use Log::Log4perl;

 my $logger = Log::Log4perl­>get_logger;

 $logger­>debug( “Going once...” );


 package Foo::Baz;
 use Log::Log4perl;

 my $logger = Log::Log4perl­>get_logger(“X”);
 $logger­>error( “D'oh!” );
Arquivos de Configuração

# nivel e alvos, por componentes
log4perl.logger = ERROR, Arq, Tela
log4perl.logger.Foo.Bar = FATAL, Arq, Tela

# log em arquivos
log4perl.appender.Arq = Log::Log4perl::Appender::File
log4perl.appender.Arq.filename=file.log
log4perl.appender.Arq.mode = append
log4perl.appender.Arq.layout=
    Log::Log4perl::Layout::SimpleLayout

# log na tela
log4perl.appender.Tela = Log::Log4perl::Appender::Screen;
log4perl.appender.Tela.layout=
    Log::Log4perl::Layout::PatternLayout
log4perl.appender.layout.ConversionPattern = [%d] %m %n
Appenders

     Log::Dispatch::ApacheLog
     Log::Dispatch::DBI
     Log::Dispatch::Email
     Log::Dispatch::Email::MailSend
     Log::Dispatch::Email::MailSendmail
     Log::Dispatch::Email::MIMELite
     Log::Dispatch::File
     Log::Dispatch::FileRotate
     Log::Dispatch::Handle
     Log::Dispatch::Screen
     Log::Dispatch::Syslog
     Log::Dispatch::Tk
     Log::Dispatch::SNMP
     ...
Conversion Patterns

%c     Categoria do evento de logging
%m     Mensagem de log
%n     Quebra de linha

%C     Nome do pacote (ou classe) totalmente qualificado
%F     Arquivo onde o evento de logging ocorreu
%d     Data atual em yyyy/MM/dd hh:mm:ss
%H     nome do host
%l     Nome do método invocante, do arquivo e número
       da linha entre parênteses.
%r     Número de milisegundos passados do início do 
       programa ao evento de log.



                     (e muito mais)
Outras Opções


 if ( $logger­>is_debug ) {
    foreach my $elemento (@lista_enorme) {
        $logger­>debug( $elemento );
 }


 open my $fh, '<', $filename
   or $logger­>logdie( “$filename: $!” );
Um arquivo de configuração diferente...
       ... ou nem tanto


log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) ­ %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %c ­ %m%n
Obrigado!
Dúvidas?

Logging e depuração enterprise-level com Log4perl