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.

3 Comments

Wow. Nice. I know I will need this someday. Bookmarking it now.

Great suggestions!

I wonder if there could be a better way to organize these module specific suggestions?

Adding the text to the POD of the modules?

Adding links to the POD of the modules to link to these articles?

Have MetaCPAN be able to store the links and associate with the modules?

A mashup between MetaCPAN and Delicious?

Thanks, it works well.

Leave a comment

About brian d foy

user-pic I'm the author of Mastering Perl, and the co-author of Learning Perl (6th Edition), Intermediate Perl, Programming Perl (4th Edition) and Effective Perl Programming (2nd Edition).