Building simplicidade.org: notes, projects, and occasional rants

Log::Log4perl tip

I use Log::Log4perl for all my logging needs. Ok, I lie. I use a wrapper that deals with some stuff that I just don't like with Log::Log4perl, but that is a story for another day.

One thing that we inherited from log4j was the notion that a message can match multiple loggers in your logging hierarchy.

The logic is simple and explained in detail on a Log::Log4perl FAQ entry. If you write something like this in your logger configuration file:

log4perl.logger.Cat        = ERROR, Screen
log4perl.logger.Cat.Subcat = WARN, Screen

which define two loggers. Cat and Cat.Subcat, the second a subcategory of the first, and then use:

my $logger = get_logger("Cat.Subcat");
$logger->warn("Warning!");

you'll get a duplicate message in your log file because it matches both loggers.

I knew that and I always added a line saying:

log4perl.additivity.Cat.Subcat = 0

that prevented this behavior, but this required a line like that per logger. Pain. Not lazy, at all.

But for some reason (stupidity comes to mind) I didn't read the FAQ completely, because at the end, there is a solution. Just put this in your logger configuration file:

log4perl.oneMessagePerAppender = 1

Bliss, pure bliss.

Mind you that oneMessagePerAppender is not compatible with log4j, something that Log::Log4perl tries very hard to be, and therefore this feature is not documented at all except on this FAQ entry.