要旨
use utf8プラグマの影響下でLog::Dispatch(あるいはLog::Dispatch::Config)を使おうとすると"Wide character in print ~"なwarningが出る件について調査しました。
結論
configファイルに数行書き加えるだけでしたが、fileとscreenで指定方法が違います。
実装
sample.psgi
use strict;
use warnings;
use Encode;
use Log::Dispatch::Config;
Log::Dispatch::Config->configure('./log.conf');
my $dispatcher = Log::Dispatch::Config->instance();
$dispatcher->info( decode_utf8 "再起動" );
# ↑全ての出力をencodeするため、use utf8されていないスコープではdecode_utf8が必須
use Plack::Request;
sub {
use utf8;
my $req = Plack::Request->new(shift);
unless( $req->path eq '/') {
$dispatcher->warning("ルート以外へのアクセス");
return [404, [], ['Not Found']];
}
# 必要な処理を書く
$dispatcher->info("正常な処理の完了");
return [200, [], ["OK"]];
};
log.conf
dispatchers = file screen
file.class = Log::Dispatch::File
file.min_level = notice
file.filename = ./log/error_log
file.mode = append
file.format = [%d] [%p] %m at %F line %L %n
file.binmode = :utf8
screen.class = Log::Dispatch::Screen
screen.min_level = debug
screen.stderr = 1
screen.format = [%p] %m %n
screen.utf8 = 1
fileのプロパティの定義にfile.binmode = :utf8
、screenのプロパティの定義にscreen.utf8 = 1
と書き加えることでLog::Dispatchが全ての出力をencode_utf8してくれるようです。
ちなみにこれがわかるまでは、
sample2.psgi
sub {
use utf8;
my $req = Plack::Request->new(shift);
unless( $req->path eq '/') {
$dispatcher->warning( encode_utf8("ルート以外へのアクセス") );
return [404, [], ['Not Found']];
}
# 必要な処理を書く
$dispatcher->info( encode_utf8("正常な処理の完了") );
return [200, [], ["OK"]];
};
のように逐一encodeを挿入してて辛かったです。