From: Niles <nil...@ex...> - 2003-09-19 19:53:24
|
I am trying to set up a system using Log4perl and multiple appenders, and I think I'm making things much more difficult than I need to. Here's what I want to accomplish: 1. Have 3 different appenders: a Log::Dispatch::Syslog-type appender, a Log::Dispatch::DBI-type appender, and a Log::Dispatch::Email-type appender. (I say "type" because these appenders will all need some modifications, which I will explain later). I'd have something like this in my init file: log4perl.logger=INFO,A1,A2,A3 where A1 is the Syslog appender, A2 is the DBI appender, and A3 is the Email appender. 2. Each of the appenders will have different minimum/maximum logging levels. The Syslog-type one will log everything from INFO and above, the DBI one will only log INFO, and the Email one will log ERROR and above. Basically, the Syslog one is to capture all information, the DBI one is to capture performance data, and the Email one is for failure notification. The init file would contain items like log4perl.appender.A2.min_level = infolog4perl.appender.A2.max_level = infolog4perl.appender.A3.min_level = error (If I can't set the min/max to the same value, I'd have the actual appender take care of that, I guess, but that's not my problem at the moment.) 3. Since the appenders have different purposes, instead of sending the same message to multiple appenders (which is easy enough), I'd like to send a hash reference to each appender, and have each appender format the output in the way that's most appropriate for the appender. The Syslog logger would create a line-oriented sendmail-type list of equates, the DBI logger would write performance information to a database table, and the Email appender would format the information in a standard, human-readable fashion. My first thought was to override the logger call so that two arguments are passed: the ordinary message (in case a future appender needs just use the plain vanilla version) and a hash reference. The three appenders I described would use the hash reference to construct their own message as is appropriate. So, I thought the easiest way would be to override some of the methods in the Log::Dispatch hierarchy, namely new() and log(), and I'd be done. Now, I'm having some difficulty because the appenders are firing when they aren't appropriate. The Email appender, in particular (actually, it's the only one I have started on now; I'm using the vanilla Log::Dispatch::Syslog one right now) fires even when the priority is "warn". I should mention here that I'm doing the following in it: use base qw (Log::Dispatch::Output);use Log::Dispatch::Email;use Mail::Sender;I started digging around in the guts of the Log::Dispatch hierarchy, looking at method calls like _should_log(), but then I start thinking that perhaps I'm going in the completely wrong direction here--I might be making things much more difficult than I have to, which wouldn't be the first time. I could probably hack and hack and make things work, but I'm worried that I'll be losing some compatibility and functionality that I'll need later. What I'm hoping to get from this email is some general direction, such as, "Use the Log4perl blah object, override this and that method, and bingo!" or "You're stuck with the Log::Dispatch stuff, and you're stuck with doing it the way you describe it, but here's what you need to do to maintain compatibility." (I noticed the callback functionality in the Log::Dispatch stuff, but I'm thinking that won't work since I want to pass different information into the appenders [the hash reference] in the first place, and I'd rather not construct some sort of formatted string and then break it up and reformat it multiple times.) I'm sorry if this turns out to be more of a Log::Dispatch question than a Log4perl question. Thank you in advance for any suggestions you might have. :-) Ig _______________________________________________ Join Excite! - http://www.excite.com The most personalized portal on the Web! |
From: Mike S. <msc...@ao...> - 2003-09-21 23:36:43
|
Niles wrote: > Each of the appenders will have different minimum/maximum logging > levels. The Syslog-type one will log everything from INFO and above, > the DBI one will only log INFO, and the Email one will log ERROR and > above. Basically, the Syslog one is to capture all information, the > DBI one is to capture performance data, and the Email one is for > failure notification. > > The init file would contain items like > > log4perl.appender.A2.min_level = info > log4perl.appender.A2.max_level = info > log4perl.appender.A3.min_level = error I think what you've done might work, although we do it differently in Log4perl. Your "only INFO and above" cases are typically solved with "appender thresholds" and the "exactly INFO" case is typically done with a levelmatch filter. Here's two FAQs dealing with these tasks: http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/FAQ.html#i_want_to_log_error_and_warn_messages_to_different_files!_how_can_i_do_that http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/FAQ.html#how_can_i_collect_all_fatal_messages_in_an_extra_log_file > 3. Since the appenders have different purposes, instead of sending the > same message to multiple appenders (which is easy enough), I'd like to > send a hash reference to each appender, and have each appender format > the output in the way that's most appropriate for the appender. The > Syslog logger would create a line-oriented sendmail-type list of > equates, the DBI logger would write performance information to a > database table, and the Email appender would format the information in > a standard, human-readable fashion. Regarding the DBI logger, you might want to look at http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/Appender/DBI.html where Kevin has provided a more powerful interface for DBI interactions. In general, if you want the appender to perform some appender-specific filtering before it actually logs the message, just pick an appender which approximately does what you need (something in the Log::Dispatch hierarchy or an appender that comes with Log::Log4perl like Log::Log4perl::Appender::File), use it as a base class for your new appender and override its log() method. Additionally, if the data you want to pass around is of global nature, take a look at the MDC mechanism at http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/FAQ.html#how_can_i_include_global_(threadspecific)_data_in_my_log_messages Hope that helps, let us know if you have any more questions ... -- -- Mike Mike Schilli m...@pe... |