Folks,
nice module - easy to use and powerful / flexible.
The only problem Ive encountered is trying to get something like this to
work -
log4j.appender.LOGFILE.filename=$ENV{APP_ROOT}/logs/rootlog
The code is installed into different places on several machines, and its
a bit of a hassle to
fix the config file accordingly as I propagate code off my development box.
I tried this - hoping the layoutpattern tricks would work here, but no joy -
log4j.appender.LOGFILE.filename= sub {return
"$ENV{APP_ROOT}/logs/rootlog"}
Also, for what its worth, Ive disregarded your warnings (sort of):
However, be careful, don't go overboard: if you're devel
oping a system in object-oriented style, using the class
hierarchy is usually your best choice. Think about the
people taking over your code one day: The class hierarchy
is probably what they know right up front, so it's easy
for them to tune the logging to their needs.
Ive written a wrapper (myLogger) which uses AUTOLOAD to delegate calls like
myLogger->debug(@args) to Log::Log4perl.
AUTOLOAD constructs a category dynamically, then tests it before logging it,
# use FQ name as category
my ($pkg,$file,$ln,$sub) = caller(my $i=1); # once had stackwalk,
to get past '(eval)'
my $cat = "$sub_$meth_$ln";
my $log = Log::Log4perl->get_logger($cat);
my $predicate = "is_$cat";
# is it runnable ?
eval { $runnable = $log->$predicate() };
if ($@) {
carp("logger: cant $meth on $cat: $@");
return;
} else { $seenCat{$cat}++ }
if ($runnable) {
# Dump arrays or refs
eval {
@p = shift @_ while @_ and not ref $_[0];
pop @_ while @_ and not $_[$#_];
$log->$meth(Data::Dumper->Dump([\@_],["@p"])) if @_;
$log->$meth(@p) if ! @_;
};
if ($@) { carp("logger dump problem on $sub.$ln") }
}
return;
This gives me extraordinary control over the logging - I can turn
logging on/off
at any level - even down to line-number; something like:
log4j.category.GwApi=DEBUG
log4j.category.GwApi._precond=INFO
# these both warn of interface violation
log4j.category.GwApi._required.notice=ERROR
log4j.category.GwApi._precond.notice=ERROR
# but..
# above suppresses a notice-level message by raising
# the logging threshold above it
# precondition check. Ive seen enough of them..
#log4j.category.GwApi._precond.info.181=WARN
Also, AUTOLOAD uuses Data::Dumper to print data-structures when @_ are refs
its a cheap (programmer-time) way to get a lot of context in the logs.
<441688> GwApi.AUTOLOAD.info: $screen yielded: = [
bless( {
'Buf' => [],
'Cmd' => undef,
'Id' => 10,
'Vals' => {},
'response' => bless( do{\(my $o = ' 0')}, 'TnResponse' ),
'session' => bless( {
'1024' => '1024',
'host' => 'localhost',
'resp' => bless( do{\(my $o = 'U U U C(localhost) I 2 24 80 0 0
0x2e00028 1')}, 'TnResponse' ),
'win' => bless( \*Symbol::GEN6, 'Expect' )
}, 'TnSession' )
}, 'TirksScreen' )
];
Finally -
given that line-numbers are a clumsy way of controlling output (better
done by super-category)
I thought it would be good to catalog all invoations encountered in a
given run of the sw,
which should be written out to a file written at process end. This
would be useful for assessing
the coverage of a test case/suite. Its not working yet (probly should
be in an END block),
but you can see the direction.
sub DESTROY {
print "# observed logging categories:\n", Dumper \%seenCat;
}
|