Enterprise-level Logging com Log4perl
Breno G. de Oliveira<[email protected]>
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!
● There is More Than One Way To Do It...
● ...But Consistency Is Not A Bad Thing
TIMTOWTDI BCINABT
Log::Log4perl
● Implementação do Log4j para Perl
● Controle do número de mensagens, porlog level e componentes
● Definição dinâmica do alvo das mensagens(appenders)
● Formatação de mensagens
● Configuração externa
TRACE
DEBUG
INFO
WARN
ERROR
Log levels
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 componenteslog4perl.logger = ERROR, Arq, Telalog4perl.logger.Foo.Bar = FATAL, Arq, Tela
# log em arquivoslog4perl.appender.Arq = Log::Log4perl::Appender::Filelog4perl.appender.Arq.filename=file.loglog4perl.appender.Arq.mode = appendlog4perl.appender.Arq.layout=\ Log::Log4perl::Layout::SimpleLayout
# log na telalog4perl.appender.Tela = Log::Log4perl::Appender::Screen;log4perl.appender.Tela.layout=\ Log::Log4perl::Layout::PatternLayoutlog4perl.appender.layout.ConversionPattern = [%d] %m %n
Appenders
Log::Dispatch::ApacheLogLog::Dispatch::DBILog::Dispatch::EmailLog::Dispatch::Email::MailSendLog::Dispatch::Email::MailSendmailLog::Dispatch::Email::MIMELiteLog::Dispatch::FileLog::Dispatch::FileRotateLog::Dispatch::HandleLog::Dispatch::ScreenLog::Dispatch::SyslogLog::Dispatch::TkLog::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, '<', $filenameor $logger>logdie( “$filename: $!” );
Um arquivo de configuração diferente... ... ou nem tanto
log4j.rootLogger=debug, stdout, Rlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p (%F:%L) %m%nlog4j.appender.R=org.apache.log4j.RollingFileAppenderlog4j.appender.R.File=example.loglog4j.appender.R.layout=org.apache.log4j.PatternLayoutlog4j.appender.R.layout.ConversionPattern=%p %c %m%n
Obrigado!
Dúvidas?