Log::Dispatch - How to "die" a script after all other methods are called???
Log::Dispatch - How to "die" a script after all other methods are called???
am 07.09.2005 01:55:05 von usenet
I want to use Log::Dispatch to log activity using a number of methods
(screen, files, e-mail, etc).
If I encounter a certain error threashold (such as 'critical') I want
the script to also "die". I would like Log::Dispatch to handle this
for me anytime it dispatches a "critical" level error message.
I don't see a good way to do this. I could, prehaps, define a
"critical" method which will "die" via a callback (as shown in my
example below). But, besides being an ugly kludge, there's a functional
problem with this (which I explain after this code):
#!/usr/bin/perl
use Log::Dispatch;
use Log::Dispatch::Screen ; use Log::Dispatch::File ;
my $dispatcher = Log::Dispatch->new;
$dispatcher ->add( Log::Dispatch::Screen ->new(
name => 'fubar',
min_level => 'critical',
callbacks => ${\sub {die "DIE\n"} ),
);
$dispatcher ->add( Log::Dispatch::File ->new(
name => 'file',
min_level => 'debug',
filename => '/tmp/junk.log' )
);
However, if I now do:
$dispatcher->critical("Oh no! The foo is barred");
It always calls the 'fubar' method FIRST (and dies). It won't ever call
the lesser methods (such as 'file', 'screen', 'email', etc).
I want to call the lesser methods and THEN die (via Dispatcher). I know
I could do this, of course:
$dispatcher->critical("Oh no! The foo is barred"); die;
But I really want Dispatcher to handle the "die" for me. Does anyone
know a good way to have Dispatcher call all other applicable methods
and THEN "die" the script for me?
Thanks!
Re: Log::Dispatch - How to "die" a script after all other methodsare called???
am 09.09.2005 15:27:07 von Christian Winter
usenet@DavidFilmer.com schrieb:
> I want to use Log::Dispatch to log activity using a number of methods
> (screen, files, e-mail, etc).
>
> If I encounter a certain error threashold (such as 'critical') I want
> the script to also "die". I would like Log::Dispatch to handle this
> for me anytime it dispatches a "critical" level error message.
>
[...]
> Does anyone
> know a good way to have Dispatcher call all other applicable methods
> and THEN "die" the script for me?
You will most probably have to put a wrapper around the
Log::Dispatch package that first invokes the Log::Dispatch
methods and then dies. Using Autoloader this isn't too hard
to do. I've put together an example for that, you can fetch it from
http://www.a-za-z0-9.de/perl/Log-Dispatch-DieTreshold-0.002. tar.gz
I'll have to look it over some more and make my mind up on
the package's naming, then maybe it will make it to CPAN
someday.
HTH
-Christian
Re: Log::Dispatch - How to "die" a script after all other methods are called???
am 15.09.2005 04:00:39 von usenet
Christian Winter wrote:
> ...put a wrapper around the Log::Dispatch package...
> Using Autoloader this isn't too hard to do
AutoLoader looks cool. I haven't played around with it before... I need
to read up on this one.
> I've put together an example for that, you can fetch it from
> http://www.a-za-z0-9.de/perl/Log-Dispatch-DieTreshold-0.002. tar.gz
# #
# # # #### # #
# # # # # # #
# # # # # # #
# # # # # # ## #
# # # # # ## ##
## ## #### # #
That's amazing! You really should put it up on CPAN.
There was a tiny typo in the Makefile - it had "Autoloader" instead of
"AutoLoader". That little typo was easy to identify and fix.
However, when I try to use the module, I'm getting:
Can't locate auto/Log/Dispatch/DieTreshold/autosplit.ix in @INC
at AutoLoader.pm line 160
I don't know enough to tell if this is a problem with the way
AutoLoader works or if it's a problem with the install of DieThreshold
(which I did the regular perl Makefile/make/make install without
errors).
I'm REALLY amazed at how you whipped this up (and, again, encourage you
to put it out on CPAN), and I'd really appreciate your advice on this
little problem.
FWIW, here's my modified version of my original test script:
use Log::Dispatch::DieTreshold;
use Log::Dispatch::Screen ; use Log::Dispatch::File ;
my $dispatcher = Log::Dispatch::DieThreshold->new;
$dispatcher -> die_treshold( 'critical' );
$dispatcher -> die_message( "It's dead, Jim!\n" );
$dispatcher ->add( Log::Dispatch::Screen ->new(
name => 'fubar',
min_level => 'critical',)
);
$dispatcher ->add( Log::Dispatch::File ->new(
name => 'file',
min_level => 'debug',
filename => '/tmp/junk.log' )
);
#Diagnostic message - this should print to file and continue:
$dispatcher->debug("Oh look - the bar is bazzed! That's nice!");
#hard-stop. This should print to file and die.
$dispatcher->critical("Oh no! The foo is barred!");
Re: Log::Dispatch - How to "die" a script after all other methodsare called???
am 15.09.2005 09:01:01 von Christian Winter
usenet@DavidFilmer.com wrote:
> Christian Winter wrote:
>>...put a wrapper around the Log::Dispatch package...
>>Using Autoloader this isn't too hard to do
>
> AutoLoader looks cool. I haven't played around with it before... I need
> to read up on this one.
It's certainly one of the most conventient modules out there.
>>I've put together an example for that, you can fetch it from
>>http://www.a-za-z0-9.de/perl/Log-Dispatch-DieTreshold-0.00 2.tar.gz
>
> That's amazing! You really should put it up on CPAN.
Will do that, only I'm quite stuck with work now. Maybe over the
weekend I'll find some time.
> There was a tiny typo in the Makefile - it had "Autoloader" instead of
> "AutoLoader". That little typo was easy to identify and fix.
Not only in the Makefile, but as well in the Module itself.
Seems I should banish Windows before I get completely case insensitive
myself.
> However, when I try to use the module, I'm getting:
>
> Can't locate auto/Log/Dispatch/DieTreshold/autosplit.ix in @INC
> at AutoLoader.pm line 160
>
> I don't know enough to tell if this is a problem with the way
> AutoLoader works or if it's a problem with the install of DieThreshold
> (which I did the regular perl Makefile/make/make install without
> errors).
I think this may be because I accidentially left out the closing __END__
tag in the module code that AutoLoader uses to distinguish between
functions to be loaded when the module is loaded and those to delay
until they are actually used.
I put an update at
http://www.a-za-z0-9.de/perl/Log-Dispatch-DieTreshold-0.003. tar.gz
that hase the case typos fixed and additionally and also an __END__ tag.
-Chris
Re: Log::Dispatch - How to "die" a script after all other methods are called???
am 15.09.2005 23:12:35 von usenet
Christian Winter wrote:
> I think this may be because I accidentially left out the closing
> __END__ tag in the module code... I put an update at
> http://www.a-za-z0-9.de/perl/Log-Dispatch-DieTreshold-0.003. tar.gz
Great - that fixed the problem and allowed me to test the module
(thanks!).
But, ummm, it's not doing what I expected it to do. It acts exactly
like regular Log::Dispatch. I think the problem is in this stmt in
AUTOLOAD:
if( grep { $_ eq $sub } keys %prios && $self->{"Treshold"} >=
$prios{$sub} )
This had two problems when I used the module. The "&&" is not binding
as intended (because it's so strong) and also the sense numerical
comparison operator is reversed (it dies if the die threshold is
GREATER than the current message level).
I put parens around the grep and reversed the comparison operator like
this:
if( (grep { $_ eq $sub } keys %prios) && $self->{"Treshold"} <=
$prios{$sub} )
and it works great!
***** HOWEVER, it has a backwards-compatibility issue with Dispatch.
The module is properly invoked when using Dispatch's newer (as of 1.6)
"convenience methods" for calling (ie, $log->error('Arrgh')). However,
if I call it with the old-style dispatch syntax ($log(level=>'error',
message=>'Arrgh') then the wrapper, um, doesn't seem to be wrapping
(the call is handled by Dispatcher as usual, but DieTreshold doesn't
get involved).
OBSERVATION: As far as I can tell, the module's "log" subroutine never
gets called by anything. I put a "die" as the first command in that sub
and it made no difference, at least not while running my test program.
I don't see under what circumstances this subroutine would be called.
OBSERVATION: I did not understand why "critical" was stipulated in this
line:
$self->{"Dispatcher"}->critical(@_);
I though maybe it should be "emergency" (if the intent is to always
force all methods), but maybe it should instead be something like:
$self->{"Dispatcher"}->log(level => $self->{'Treshold'}, message =>
@_);
But maybe there's a very good reason for "critical" and I just don't
understand.
I hope this info helps in some small way (since you have helped me in a
much bigger way).
Thanks again!