Perlからログを出力方法
ここからは、
Perlのスクリプトから最も簡単にログを吐くには、
warn "request timeout";
これを実行すると、
request timeout at log.pl line 7.
のようにwarnを記したファイル名と行があわせて出力されます。
しかしこれだけでは前節で説明したログに必要な項目を満たしていないので、
my @time = localtime();
warn sprintf "%04d-%02d-%02dT%02d:%02d:%02d [%s] %s",
$time[5]+1900, $time[4]+1, @time[3,2,1,0], ―(1)
"WARN", ―(2)
"request timeout";
2011-08-05T16:47:12 [WARN] request timeout at log.pl
line 8.
となり、
ただしログを出力するたびにこのコードを書くのは冗長ですので、
sub logf {
my ($level,$message) = @_;
my ($pkg,$file,$line) = caller; ―(1)
my @time = localtime;
warn sprintf "%04d-%02d-%02dT%02d:%02d:%02d [%s] %s at %s line %d.\n", ―(2)
$time[5]+1900, $time[4]+1, @time[3,2,1,0],
$level, $message,
$file, $line;
}
実行方法と出力は次のようになります。
# 実行
logf("INFO","request timeout");
# 出力
2011-08-05T17:01:09 [INFO] request timeout at log.pl
line 18.
そのままlogf関数内でwarnを実行すると、
これで、
CPANに登録されているログモジュール
前節ではログを出力するための簡単な関数を作成してみましたが、
Log::Log4perl
Log::Log4perlは、
$ cpanm Log::Log4perl
基本的な使い方はリスト4のようになります。まず
use Log::Log4perl;
Log::Log4perl::init('./log4perl.conf'); ―(1)
my $logger = Log::Log4perl->get_logger('develop'); ―(2)
$logger->debug('This is a debug message'); ―(3)
$logger->warn('This is a warn message');
$logger->fatal('Fatal error has occurred');
リスト5はリスト4
log4perl.logger.develop = DEBUG, Screen
log4perl.appender.Screen = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.Screen.layout.ConversionPattern = %d [%p] %m %F at %L.%n
log4perl.
2011/08/11 17:58:39 [DEBUG] This is a debug message log4perl.pl at 9.
2011/08/11 17:58:39 [WARN] This is a warn message log4perl.pl at 10.
2011/08/11 17:58:39 [FATAL] Fatal error has occurred log4perl.pl at 11.
Log::Dispatch
Log::DispatchはDateTimeやMooseの開発者として知られているDave Rolsky氏によるログモジュールで、
リスト7がLog::Dispatchの基本的な使い方です。
use Log::Dispatch;
my $log = Log::Dispatch->new( ―(1)
outputs => [[
'Screen', ―(2)
min_level => 'debug',
stderr => 1,
newline => 1,
]],
);
$log->debug('debug message'); ―(3)
$log->info('info message');
$log->notice('notice message');
$log->emergency('emergency message');
しかしLog4perlと異なり、
debug message
info message
notice message
emergency message
というメッセージだけが表示され、
my $log = Log::Dispatch->new(
outputs => [[
'Screen',
min_level => 'debug',
stderr => 1,
newline => 1,
callbacks => sub {
my %args = @_;
my ($pkg,$file,$line);
my $caller = 0;
while ( ($pkg,$file,$line) = caller($caller) ) {
last if $pkg !~ m!^Log::Dispatch!;
$caller++;
}
my @time = localtime;
sprintf "%04d-%02d-%02dT%02d:%02d:%02d [%s] %s at %s line %d.",
$time[5]+1900, $time[4]+1, @time[3,2,1,0],
$args{level}, $args{message},
$file, $line;
}
},
]]
);
Log::Minimal
Log::Minimalは拙作のログモジュールで、
リスト9はLog::Minimalの利用例です。Log::Minimalをuseするといくつかの関数がエクスポートされるので、
use Log::Minimal;
critf("crtical message");
warnf("warning message");
infoff("infomation message");
debugff("debug message");
Log::Minimalはシンプルながらもいくつかカスタマイズできるようになっているので、
デバッグメッセージの表示
Log::Minimalでdebugfもしくはdebugffを使っても、
$ENV{LM_DEBUG} = 0;
debugf("debug message"); #表示されない
$ENV{LM_DEBUG} = 1;
debugf("debug message"); #表示される
アプリケーション開発中はLM_
ログのカラーリング
ターミナル上でログを表示した際に、
次のコードを実行すると、
$ENV{LM_DEBUG}=1;
$Log::Minimal::COLOR=1;
debugf("foo debug");
infof("bar info");
warnf("foo warn");
critf("bar critical");
![図1 ログのカラーリング 図1 ログのカラーリング](/assets/images/dev/serial/01/perl-hackers-hub/0011/thumb/TH800_001.png)
なお、
メッセージのフォーマットと自動シリアライズ
Log::Minimalのログ出力関数に2つ以上の引数を渡すと、
$name="gihyo";
id="65";
warnf("user:%s id:%d",$name,$id);
上記は、
2011-08-05T17:01:09 [INFO] user:gihyo id:65 at log.pl
line 8
また、
my $user = {
id => 65,
name => 'gihyo',
point => 1480,
};
local $Log::Minimal::AUTODUMP = 1;
infof("user:%s",$user);
上記のコードを実行すると、
2011-08-14T02:09:04 [INFO] user: {
'point' => 1480,
'name' => 'gihyo',
'id' => 65
} at /tmp/minimal.pl line 9
※実際は1行
ログ出力方法の変更
デフォルトのLog::Minimalは、
open( my $fh, ">>", "app.log");
local $Log::Minimal::PRINT = sub {
my ( $time, $type, $message, $trace) = @_;
print $fh "$time [$type] $message at $trace\n";
};
$Log::Minimal::PRINTに渡したサブルーチンリファレンスには、
ログモジュールの比較
ここまで紹介したLog::Log4perl、
モジュール名 | 時間・ | ログレベル数 | ログ出力方法のカスタマイズ | ログのカラーリング | フォーマットシリアライズ機能 | 速度 |
---|---|---|---|---|---|---|
Log::Log4perl | ○ | 6 | 拡張モジュールあり | ○ | × | △ |
Log::Dispatch | callbackで実装 | 8 | 拡張モジュールあり | 別途CPANモジュール | × | × |
Log::Minimal | ○ | 4 | 自前で用意する必要あり | ○ | ○ | ○ |
※ 速度についてはhttp://