|
From: Robert J. <yad...@sn...> - 2006-09-27 14:04:20
|
I've implemented a buffering mechanism in my wrapper's log()
call. Basically I check using {dbh}->ping() if the database is
up. If not, I buffer the message in an array and return success so
that the parent program can proceed.
When the database comes back up I dump the buffer to the DBI appender.
However, the dumped log messages have the time of the dump, not the
original log message time. Is there a way to get Log4perl to use the
original time of the message? It doesn't seem to be in the hash that
the log() method gets; but maybe I'm just not looking in the right spot?
I guess I could workaround the issue by prepending the original time
to the "message" field, but I'd like to avoid modifying the original
as much as possible. Can I do something like: 1) store the original
time internally in my buffer and 2) when dumping the buffer to the
appender, set some internal Log4perl time variable to the buffered time?
-----------------------------------------------------------
package Mylog;
use warnings;
use strict;
use Carp;
use DBI;
require Log::Log4perl::Appender::DBI;
sub new {
my ($class, %options) = @_;
my $appender = Log::Log4perl::Appender::DBI->new(
map { $_ => $options{$_} } keys %options,
);
my $self = {
appender => $appender,
name => $options{name},
};
bless $self, $class;
$self->_init(%options);
return $self;
}
sub log {
my ($self, %p) = @_;
# Check for DB connection
if (! $self->{dbh}->ping() ) {
# Buffer the message
push @{$self->{BUFFER}}, \%p;
# Notify FOT
$self->_notify(%p);
# Try to reconnect
eval {
$self->{dbh} = $self->{connect}->();
};
return 1;
} else {
$self->{connected_time} = scalar gmtime();
}
$self->check_buffer();
$Log::Log4perl::caller_depth++;
$self->{appender}->log(
%p,
);
$Log::Log4perl::caller_depth--;
return 1;
}
sub _init {
my $self = shift;
my %params = @_;
if ($params{dbh}) {
$self->{dbh} = $params{dbh};
} else {
$self->{connect} = sub {
DBI->connect(@params{qw(datasource username password)},
{PrintError => 0})
or croak "Log4perl: $DBI::errstr";
};
$self->{dbh} = $self->{connect}->();
$self->{_mine} = 1;
}
}
sub _notify {
my $self = shift;
my %params = @_;
# eventually send an email or something
# for now just print a message
print "Database is down\n";
}
sub check_buffer {
my $self = shift;
return unless ($self->{BUFFER} && ref $self->{BUFFER} eq 'ARRAY');
while ( @{$self->{BUFFER}} ) {
my $ref = shift @{$self->{BUFFER}};
$Log::Log4perl::caller_depth += 2;
$self->{appender}->log(
%$ref,
);
$Log::Log4perl::caller_depth -= 2;
}
return 1;
}
1;
-----------------------------------------------------------
--
Rob
|