use Log::Log4perl::Catalyst;
# Either make Log4perl act like the Catalyst default logger:
__PACKAGE__->log(Log::Log4perl::Catalyst->new());
# or use a Log4perl configuration file, utilizing the full
# functionality of Log4perl
__PACKAGE__->log(Log::Log4perl::Catalyst->new('l4p.conf'));

... and then sprinkly logging statements all over any code executed by Catalyst:

This module provides Log4perl functions to Catalyst applications. It was inspired by Catalyst::Log::Log4perl on CPAN, but has been completely rewritten and uses a different approach to unite Catalyst and Log4perl.

Log4perl provides loggers, usually associated with the current package, which can then be remote-controlled by a central configuration. This means that if you have a controller function like

respectively. See the Log4perl manpage on how to perform fine-grained log-level and location filtering, and how to forward messages not only to the screen or to log files, but also to databases, email appenders, and much more.

Also, you can vary the layout of each message. For example if you want to know where a particular statement was logged, turn on file names and line numbers:

If called without parameters, new() initializes Log4perl in a way so that messages are logged similiarly to Catalyst's default logging mechanism. If you provide configuration, either the name of a configuration file or a reference to scalar string containing the configuration, it will call Log4perl with these parameters.

Note the difference between Log4perl's initialization in Catalyst, which uses the Catalyst-specific Log::Log4perl::Catalyst module (top of this page), and making use of Log4perl's loggers with the standard Log::Log4perl loggers and macros. While initialization requires Log4perl to perform dark magic to conform to Catalyst's different logging strategy, obtaining Log4perl's logger objects or calling its macros are unchanged.

Instead of using Catalyst's way of referencing the "context" object $c to obtain logger references via its log() method, you can just as well use Log4perl's get_logger() or macros to access Log4perl's logger singletons. The result is the same.