[Catalyst] Trapping added errors with the correct caller

Alexander Hartmaier alexander.hartmaier at t-systems.at
Mon Oct 15 16:49:59 GMT 2012


On 2012-10-15 18:03, Robert Rothenberg wrote:
> On 15/10/12 15:21 Alexander Hartmaier wrote:
>> I recommend to use a logging module like Log::Log4perl::Catalyst and do
>> all your app logging there.
> I use Log::Dispatch. (The application is already deployed, and it's not
> feasible to change it to Log4perl now.)
If you're already using a logger but the default Catalyst one that's fine.
>
> I don't see where in your code you trap calls to $c->error() and log them.
All log messages are going to your logger object, Log::Dispatch in your
case, not just errors.
Just configure Log::Dispatch to do with them what you want it to do (log
to a separate file, mail them, etc. ).
>
>> My log package for NAC::Web:NAC looks like this:
>>
>> package NAC::Web::NAC::Log;
>> use Moose;
>> use Catalyst::Log;
>> use namespace::autoclean;
>>
>> BEGIN { extends 'Log::Log4perl::Catalyst'; }
>>
>> =head1 NAME
>>
>> NAC::Web::NAC::Log - Logger for NAC::Web::NAC
>>
>> =cut
>>
>> # import _dump method from Catalyst::Log
>> *_dump = \&Catalyst::Log::_dump;
>>
>> 1;
>>
>> My app uses it with:
>>
>> =item finalize_config
>>
>> Initializes the logger after the config file merging and loading is done.
>>
>> =cut
>>
>> sub finalize_config {
>>     my $class = shift;
>>     $class->next::method(@_);
>>     $class->log(NAC::Web::NAC::Log->new($class->config->{log}));
>> }
>>
>> # Start the application
>> __PACKAGE__->setup();
>>
>> around 'prepare' => sub {
>>     my $orig = shift;
>>     my $self = shift;
>>
>>     Log::Log4perl::MDC->remove();
>>
>>     my $c = $self->$orig(@_);
>>
>>     Log::Log4perl::MDC->put( "username", $c->user->username )
>>         if $c->user_exists;
>>
>>     return $c;
>> };
>>
>> And this is how the app's prod config file looks like:
>>
>> <log>
>>     log4perl.logger                                     "WARN, FILE, MAIL"
>>     log4perl.appender.FILE
>> "Log::Log4perl::Appender::File"
>>     log4perl.appender.FILE.filename
>> "/home/nac/log/nac-web-nac.log"
>>     log4perl.appender.FILE.utf8                         1
>>     log4perl.appender.FILE.syswrite                     1
>>     log4perl.appender.FILE.layout
>> "Log::Log4perl::Layout::PatternLayout"
>>     log4perl.appender.FILE.layout.ConversionPattern     "%d{yyyy-MM-dd
>> HH:mm:ss} %-5p %X{username} %m%n"
>>     log4perl.appender.MAIL
>> "Log::Dispatch::Email::MailSend"
>>     log4perl.appender.MAIL.Threshold                    ERROR
>>     log4perl.appender.MAIL.from                         "nac at domain.com"
>>     log4perl.appender.MAIL.to
>> "app-errors at domain.com"
>>     log4perl.appender.MAIL.subject                      "[NAC::Web::NAC]
>> errors"
>>     log4perl.appender.MAIL.buffered                     0
>>     log4perl.appender.MAIL.layout                       "PatternLayout"
>>     log4perl.appender.MAIL.layout.ConversionPattern     "%d{yyyy-MM-dd
>> HH:mm:ss} %-5p %X{username} %m%n"
>> </log>
>>
>> Best regards, Alex (abraxxa)
>>
>> On 2012-10-11 14:38, Robert Rothenberg wrote:
>>> I would like to trap every error added to $c->error() and log it, noting the
>>> caller (filename, line number) in the logs.
>>>
>>> I've not gotten Catalyst::Plugin::ErrorCatcher to work, so I wrote my own
>>> plugin that overrides $c->error with the following method:
>>>
>>>   use MRO::Compat;
>>>   use namespace::autoclean;
>>>
>>>   sub error {
>>>     my ($c, @args) = @_;
>>>
>>>     foreach my $arg (@args) {
>>>         if ($arg) {
>>>
>>>             $c->log->error($arg);
>>>         }
>>>     }
>>>
>>>     return $c->next::method(@args);
>>>  }
>>>
>>> But this only logs errors as coming from my plugin.
>>>
>>> Using Sub::Uplevel or fiddling with $Log::Dispatch::CallerDepth or
>>> $Catalyst::Plugin::Log::Dispatch::CallerDepth doesn't seem to work.
>>>
>>> I also tried writing the plugin as a Moose::Role that adds my trap before
>>> error, but then it claims to be from one of the internal Moose classes in my
>>> logs.
>>>
>>> I can manually get the caller using caller(0) and add them to the log
>>> messages, but that's a bit clumsy (and overrides log formats that don't
>>> include the information).
>>>
>>> So... what is the best practice for trapping errors in a way that preserves
>>> caller information?
>>>
>>>
>>> _______________________________________________
>>> List: Catalyst at lists.scsys.co.uk
>>> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>>> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>>> Dev site: http://dev.catalyst.perl.org/
>>
>>
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> T-Systems Austria GesmbH Rennweg 97-99, 1030 Wien
>> Handelsgericht Wien, FN 79340b
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>> Notice: This e-mail contains information that is confidential and may be privileged.
>> If you are not the intended recipient, please notify the sender and then
>> delete this e-mail immediately.
>> *"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*"*
>>
>> _______________________________________________
>> List: Catalyst at lists.scsys.co.uk
>> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>> Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>> Dev site: http://dev.catalyst.perl.org/




More information about the Catalyst mailing list