Logging wide characters with Log4perl
I gave my "Surviving Perl Unicode" tutorial at the Mad Mongers this weekend. After I mentioned Test::Builder's Unicode issue, JT Smith asked how I would silence wide character warnings from Log::Log4perl. I'd never really thought about it.
For instance, here's an easy program that wants to output U+2020 (ᴅᴀɢɢᴇʀ):
use utf8; use strict; use warnings; use Log::Log4perl qw(:easy); Log::Log4perl->easy_init( level => $DEBUG ); DEBUG( 'Is this a † I see before me?' ); # warning
I get this warning:
Wide character in print at /usr/local/perls/perl-5.14.1/lib/site_perl/5.14.1/Log/Log4perl/Appender/Screen.pm line 39. 2011/09/01 02:24:19 Is this a † I see before me?
It's simple to fix this because the Log::Log4perl gives an example. I can give a few more parameters to easy_init
:
use utf8; use strict; use warnings; use open OUT => ':encoding(UTF-8)'; # does not work use Log::Log4perl qw(:easy); Log::Log4perl->easy_init( { level => $DEBUG, utf8 => 1, } ); DEBUG( 'Is this a † I see before me?' ); # no warning
It's not as clear what to do when you want to do it the hard way:
use utf8; use strict; use warnings; use Log::Log4perl; use Log::Log4perl::Appender::Screen; my $config = { 'log4perl.rootLogger' => 'DEBUG, Screen', 'log4perl.appender.Screen' => 'Log::Log4perl::Appender::Screen', 'log4perl.appender.Screen.layout' => 'SimpleLayout', }; Log::Log4perl->init( $config ); my $logger = Log::Log4perl->get_logger; $logger->debug( 'Is that a † I see before me?' ); # warning
The Log::Log4perl::Appender::Screen docs mention a utf8
parameter, but as an argument to the constructor for the appender. Most people aren't going to create those objects themselves. You can set it as an option for the appender:
use utf8; use strict; use warnings; use Log::Log4perl; use Log::Log4perl::Appender::Screen; my $config = { 'log4perl.rootLogger' => 'DEBUG, Screen', 'log4perl.appender.Screen' => 'Log::Log4perl::Appender::Screen', 'log4perl.appender.Screen.layout' => 'SimpleLayout', 'log4perl.appender.Screen.utf8' => 1, }; Log::Log4perl->init( $config ); my $logger = Log::Log4perl->get_logger; $logger->debug( 'Is that a † I see before me?' ); # no warning
It works for some other appenders too, such as Log::Log4perl::Appender::File:
use utf8; use strict; use warnings; use Log::Log4perl; use Log::Log4perl::Appender::Screen; my $appender_class = 'Log::Log4perl::Appender::File'; my $config = { 'log4perl.rootLogger' => 'DEBUG, File', 'log4perl.appender.File' => $appender_class, 'log4perl.appender.File.layout' => 'SimpleLayout', 'log4perl.appender.File.filename' => 'dagger.log', 'log4perl.appender.File.utf8' => 1, }; Log::Log4perl->init( $config ); my $logger = Log::Log4perl->get_logger; $logger->debug( 'Is that a † I see before me?' ); # no warning
It looks like the Log::Log4perl::Appender::DBI appender doesn't have any setting for that. I can, however, pass it my own DBI object. Depending on the DBD, I can set various things as long as my database server agrees with my choices.
There are some other ways that you can affect appenders, as documented in Log::Log4perl::Appender.