From: <log...@pe...> - 2003-01-24 09:47:57
|
Welcome to the Log::Log4perl recipe of the week. Today: ============================================================ Log::Log4perl Recipe of the Week (#13): How can I write my own appender? ============================================================ First off, there's a lot of Log4perl-compatible appenders already available on CPAN: Just run a search for "Log::Dispatch" on http://search.cpan.org and chances are that what you're looking for has already been developed, debugged and been used successfully in production -- no need for you to reinvent the wheel. Also, Log::Log4perl ships with a nifty database appender named Log::Log4perl::Appender::DBI -- check it out if talking to databases is your desire. But if you're up for a truly exotic task, you might have to write an appender yourself. That's very easy -- it takes no longer than a couple of minutes for the basic framework. Say, we wanted to create an appender of the class "Log::Dispatch::ColorScreen", which logs messages to the screen in a configurable color. Just create a new class in "Log/Dispatch/ColorScreen.pm" and let it inherit from the base class "Log::Dispatch::Output": package Log::Dispatch::ColorScreen; use Log::Dispatch::Output; use base qw( Log::Dispatch::Output ); Now let's assume that your Log::Log4perl configuration file "test.conf" looks like this: log4perl.logger = INFO, ColorApp log4perl.appender.ColorApp=Log::Dispatch::ColorScreen log4perl.appender.ColorApp.color=blue log4perl.appender.ColorApp.layout = PatternLayout log4perl.appender.ColorApp.layout.ConversionPattern=%d %m %n This will cause Log::Log4perl on "init()" to look for a class Log::Dispatch::ColorScreen and call its constructor new(). Let's add new() to Log/Dispatch/ColorScreen.pm: sub new { my($class, %options) = @_; my $self = { %options }; bless $self, $class; $self->_basic_init( %options ); return $self; } To initialize this appender, Log::Log4perl will call and pass all attributes of the appender as defined in the configuration file to the constructor as name/value pairs (in this case just one): Log::Dispatch::ColorScreen->new(color => "blue"); The new() method listed above stores the contents of the %options hash in the object's instance data hash (referred to by $self) and calls "_basic_init" with all name/value pairs to initialize the appender in the Log::Dispatch world. That's all for initializing a new appender with Log::Log4perl. Second, Log::Dispatch::ColorScreen needs to expose a "log_message()" method, which will be called by Log::Log4perl every time it thinks the appender should fire. Along with the object reference (as usual in Perl's object world), log_message() will receive a list of name/value pairs, of which only the one under the key "message" shall be of interest for now since it is the message string to be logged. At this point, Log::Log4perl has already taken care of joining the message to be a single string. For our special appender Log::Dispatch::ColorScreen, we're using the Term::ANSIColor module to colorize the output: use Term::ANSIColor; sub log_message { my($self, %params) = @_; print colored($params{message}, $self->{color}); } The color (as configured in the Log::Log4perl configuration file) is available as $self->{color} in the appender object. Don't forget to return 1; at the end of ColorScreen.pm and you're done. Install the new appender somewhere where perl can find it (like Log/Dispatch/ColorScreen.pm) and try it with a test script like use Log::Log4perl qw(:easy); Log::Log4perl->init("test.conf"); ERROR("blah"); to see the new colored output. Is this cool or what? Have fun! Until next week. -- Mike ################################### # Mike Schilli # # log...@pe... # # http://perlmeister.com # # http://log4perl.sourceforge.net # ################################### |