From: Alex M. <ale...@cl...> - 2003-10-21 10:15:17
|
On Mon, Oct 20, 2003 at 01:28:04PM -0700, Kevin Goess wrote: > >I wonder if there is a way, using Log::Log4perl::Appender::DBI, to set a > >value for a logger, which will be inserted at all subsequent log > >statements. > > See 'Mapped Diagnostic Context' in the perldoc > http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl.html#mapped_diagnostic_context_(mdc) > > > >my $logger = Log::Log4perl::get_logger(); > > > >my $customer = get_cust_id(); > > #stash the value in a global location for the logger to find > Log::Log4perl::MDC->put('customer', $customer); > > >do_something_dangerous() || $logger->error("Big problem !"); > ># ... > >do_something_uncredibly_dangerous() || $logger->error("Aaargh !"); > > And set up your appender to look like something this: > > log4j.appender.DBAppndr.sql = \ > insert into logtable \ > (custid, message) \ > values (?,?) > log4j.appender.DBAppndr.params.1 = %X{customer} > > Does that answer your question? That's great ! Well, I have a couple of more questions :) 1) I'd like to have optional parameters to logging statements. The documentation says that if it lacks a parameter, it will just be replaced by the undef value. But I got a different behaviour. 2) I would like to do some preprocessing before the value are inserted in the database. I can manage to do that on %x's values by overriding the log() method (and I think I could use this trick to solve the problem #1). But I don't know how to do it on the values in %X. I'd like to do that because when a value from %X is not initialized, the string '[undef]' is inserted, but when the corresponding database column is of type INTEGER, obviously the SQL statements fails. I'd like to have a way to put a zero or a NULL value instead of the string '[undef]'. Here are pieces of code in order to explain my problems : ################################################################################ package MyAppender; use base 'Log::Log4perl::Appender::DBI'; sub log { # Here I'm subclassing to modify value from the %x's parameters my $self = shift; my %p = @_; # Categories are shown as Perl packages $p{log4p_category} =~ s/\./::/g; Log::Log4perl::Appender::DBI::log($self, %p); } 1; ################################################################################ package My::Cute::Package; my $log_conf = <<END; log4perl.appender.dbLog=MyAppender log4perl.appender.dbLog.datasource=dbi:Pg:dbname=test log4perl.appender.dbLog.username= log4perl.appender.dbLog.password= log4perl.appender.dbLog.sql=INSERT INTO log (category, level, customer, message, details) VALUES (?, ?, ?, ?, ?) log4perl.appender.dbLog.params.1 = %c log4perl.appender.dbLog.params.2 = %p log4perl.appender.dbLog.params.3 = %X{customer} log4perl.appender.dbLog.usePreparedStmt = 1 log4perl.appender.dbLog.layout = Log::Log4perl::Layout::NoopLayout log4perl.appender.dbLog.warp_message = 0 log4perl.logger=DEBUG, dbLog END use Log::Log4perl; Log::Log4perl->init(\$log_conf); my $logger = Log::Log4perl::get_logger(); # This one fails with the following message because the database wants an # integer (or a NULL value). # # DBD::Pg::st execute failed: ERROR: pg_atoi: error in "[undef]": can't parse # "[undef]" at /usr/local/lib/perl5/site_perl/5.8.0/Log/Log4perl/Appender/DBI.pm $logger->error( "Something wrong.", "A problem has happened because of this and that." ); # %X{customer} is initialized Log::Log4perl::MDC->put('customer', 1234); # This one works $logger->error( "Something wrong.", "A problem has happened because of this and that." ); # This one fails with the message : # # execute called with 4 bind variables, 5 needed at # /usr/local/lib/perl5/site_perl/5.8.0/Log/Log4perl/Appender/DBI.pm line 96. $logger->error( "Some other thing wrong." ); ################################################################################ -- Alex Marandon CLARISYS Informatique http://clarisys.fr |