Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Log::Any with die and carp

by learnedbyerror (Monk)
on Dec 16, 2018 at 18:43 UTC ( [id://1227324]=perlquestion: print w/replies, xml ) Need Help??

learnedbyerror has asked for the wisdom of the Perl Monks concerning the following question:

Hello Oh Wise Monks

The village idiot returns with another request for your guidance. I have long been a devotee of the most excellent Log::Log4perl. However, I am currently working on a module that I think may benefit others and will place it on CPAN. As such, I plan to change the log producer to Log::Any. For most of my logging calls, this is a trivial change. There are several cases where the change is not so trivial. They are replacing $logger->logdie (which I shouldn't be using in a module anyway ) and more importantly the Log4perl levels that handle Carp: $logger->log(carp|cluck|croak|confess).

My question is, "what are your recommended means of integrating Log::Any where die and Carp functionalities are needed?"

Some of the options are not too disruptive, replace $logger->logdie(...)with $logger->logcritical(...) && die(...)

Whereas cluck or confess would be something more like

$logger->critical(...); my $long_message = Carp::longmess; foreach my $line ( $long_message =~ m/^.+$/msg ) { $logger->critical( $line ); } confess(...)

NOTE: untested code example, intended for representative use only

While functional, it seems inelegant to have to add these boilerplate lines or add a subroutine or class method to handle this. Are their more elegant ways of handling this need with Log::Any?

Thanks in advance for your sage advice!

lbe

Replies are listed 'Best First'.
Re: Log::Any with die and carp
by 1nickt (Canon) on Dec 17, 2018 at 01:11 UTC

    Hi, as you no doubt know Log::Any's approach is very minimalistic and I don't think you can really expect it to do anything other than send messages to the logger.

    So I think your approach may be the best you can do on the producer side. But, do you really need to output with Carp functions if you are going to log the longmess at level critical? Couldn't you simply document that the log will contain the stacktrace and push responsibility onto the consumer to, well, consume it, and then just die tersely?

    Hope this helps!


    The way forward always starts with a minimal test.

      Thanks for your response. I was hoping that I missed something :(

      I think you are right regarding logging longmess and die terseley

      Thanks again!, lbe

Re: Log::Any with die and carp
by karlgoethebier (Abbot) on Dec 17, 2018 at 13:16 UTC

    Don‘t worry. Good advice was given. And please note: The real village idiot left the monastery a while ago. Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

      And I was so looking forward to his energetic response :)

      Cheers, lbe

Re: Log::Any with die and carp
by perlancar (Hermit) on Dec 19, 2018 at 11:16 UTC
    May I suggest an alternative? Log::ger::Like::Log4perl. This lets you retain most of the logging code, including the log+die/log+carp methods. Granted, the backend is not Log::Any, but Log::ger is created as an alternative to Log::Any. It has interop with Log::Any and supports various outputs as well.

      perlancar First, thank you for taking the time to reply. I am only slightly familiar with Log::ger based upon a review of loggers that I performed about a year ago when I decided to take a look around. At that time, as now, I have been using and am very comfortable with Log::Log4perl. I remember being interested in Log::ger and strongly considered it as well as Log::Dispatch at that time. At that time, I decided that there wasn't a compelling reason to pull me away from Log::Log4perl.

      My goal at this point is a bit different than my previous search. Previously I was looking at loggers for my personal use. As I am now looking at log production for a module for CPAN, I have different criteria. My primary interest in Log::Any is based upon its goal of being a standard log production API agnostic of specific log consumption backends. While TIMTOWDI rules in perl, I perceive that Log::Any has somewhat become the defacto standard for this purpose though there are more reverse dependencies on CPAN for Log::Log4perl than there are for Log::Any

      I will take another look at Log::ger. Thanks again for your response.

      lbe

        You're most welcome.

        Log::ger actually has more reverse dependencies on CPAN than Log::Any now.

        % lcpan rdeps Log::ger | wc -l
        253
        
        % lcpan rdeps Log::Any | wc -l
        196

        but all those Log::ger reverse deps are mine :-) (haven't found my first vict, er, author yet), while Log::Any is used on CPAN by a whooping 77 different authors:

        % lcpan rdeps Log::ger | td select author | sort | uniq
        PERLANCAR
        
        % lcpan rdeps Log::Any | td select author | sort | uniq | wc -l
        77

        I was a long-time Log::Any user before getting annoyed enough to write the replacement, so to tell you in short why I ditched Log::Any: it stopped being lightweight enough to use in some of my modules. Startup time increases by 5-10ms. And if you use Log::Any in your module, suddenly you will also depend on things like IO::File, FindBin, Storable, Sys::Syslog:

        % lcpan deps --phase runtime --rel requires Log::Any
        +----------------+----------+---------+---------+
        | module         | author   | version | is_core |
        +----------------+----------+---------+---------+
        | B              | SHAY     | 0       | 1       |
        | Carp           | XSAWYERX | 0       | 1       |
        | Data::Dumper   | XSAWYERX | 0       | 1       |
        | Exporter       | TODDR    | 0       | 1       |
        | Fcntl          | SHAY     | 0       | 1       |
        | File::Basename | SHAY     | 0       | 1       |
        | FindBin        | SHAY     | 0       | 1       |
        | IO::File       | TODDR    | 0       | 1       |
        | Storable       | XSAWYERX | 0       | 1       |
        | Sys::Syslog    | SAPER    | 0       | 1       |
        | Test::Builder  | EXODIST  | 0       | 1       |
        | constant       | RJBS     | 0       | 1       |
        | strict         | SHAY     | 0       | 1       |
        | warnings       | SHAY     | 0       | 1       |
        +----------------+----------+---------+---------+
        
        % lcpan deps --phase runtime --rel requires Log::ger
        +--------------+----------+---------+---------+
        | module       | author   | version | is_core |
        +--------------+----------+---------+---------+
        | Data::Dumper | XSAWYERX | 0       | 1       |
        | parent       | CORION   | 0       | 1       |
        | strict       | SHAY     | 0       | 1       |
        | vars         | SHAY     | 0       | 1       |
        | warnings     | SHAY     | 0       | 1       |
        +--------------+----------+---------+---------+
        

        Granted, all those modules are core, but this shows that Log::Any was not the tiny little module you can just sneak in to your module without much thought anymore, especially if you want your module to also be tiny.

        I have made Log::ger to be as light as strict or warnings so the impact of adding use Log::ger; to your module is really minimal. And this is really important to me because I want to be able to use logging pervasively in most (if not all) of my modules when necessary.

        Log::ger basically has all the features of Log::Any plus more, with less impact to your module users.

        As for Log::Dispatch, it has even much worse startup overhead. It will add ~100ms to your module's startup by loading a whole argument parameter framework (Specio, Params::ValidationCompiler) as well as many extras like Module::Runtime, File::Spec, Storable, Exception::Class, List::Util, so that's not acceptable for some cases. It will pull many non-core dependencies to your module.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1227324]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2024-04-24 02:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found