unicode Archives

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.

What are your environment settings for Unicode?

How have you set up your environment to work with Unicode? I want to make a cheat sheet for the Perl newbies. There is some information in the googlesphere but it's disperse and unfocused.

I'm working Unicode into the next edition of Learning Perl. The most frustrating part of this for newbies (Perl, Unicode, or otherwise) is getting all the pieces to cooperate. Even if you get it right inside your Perl program, your terminal might not handle Unicode. If your terminal handles it, you might not have the right fonts. And so on and so on.

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).