Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Moose based logging question

by jandrew (Chaplain)
on Feb 09, 2014 at 13:18 UTC ( [id://1074111]=perlquestion: print w/replies, xml ) Need Help??

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

Hello all,

I am working on developing a Moose based logging Module. Yes I have reviewed the currently popular logging modules and while I used Log4perl for a while I still was looking for incremental functionality. I would like to ask the monastery for assistance in minimizing the impact of logging statements left in code.

I am a largely a solo coder. Meaning I don't have a lot of code infrastructure at $work. While I acknowledge the long term value of all the test infrastructure that is best practice I sometimes don't have the time to implement it while getting stuff done. My solution is to leave the debug statements from development in my production code so that if I break some old code with a new piece of code I can trace it through the old stuff as well as the new stuff. The obvious issue with this is that the debug stuff costs some production overhead.

I initially messed around with Smart::Comments since the production impact of these statements are near 0. However, I lost all of the goodness associated with logging namespaces and control from it. What is the best way to minimize the impact of deselected logging statements and deselected logging parameter evaluation in the following scenario?

package Logger; use Moose; sub log{ my ( $self, $string ) = @_; print $string . "<--- Logged information\n"; } package main; my $Logger = Logger->new; print "Some normal action here\n"; my $debug = "Sometimes I want this"; $Logger->log( $debug );

Points for a Moose based answer!

I already share some of my code on CPAN but I know that if I don't minimize the debug stuff that I leave in my code that most people will find it unusable. In a perfect world my logging config file would even be able to turn off parameter evaluation of some logging statements without having to wrap them in an if_error() block. Is that even possible? (Without source code filtering)

Replies are listed 'Best First'.
Re: Moose based logging question
by tobyink (Canon) on Feb 09, 2014 at 20:46 UTC

    You could do something like this:

    my $logger; use constant DEBUGGING => !!$ENV{DEBUG}; sub log_this (&) { DEBUGGING or return; $logger ||= Logger->new; $logger->log($_) for shift->(); } log_this { "Hello world" }; log_this { "Hello", "world" }; log_this { my $data = Expensive->method_call(); "DATA: $data"; };

    If the $DEBUG environment variable is false, log_this will return quickly without evaluating the contents of the code block. This still has the overhead of the sub call to log_this itself, but that overhead will be fairly small.

    As a bonus, you could use something like Keyword::Simple to alter the parsing of log_this to avoid having even the overhead of that redundant sub call when $DEBUG is false. If you write your custom parser carefully, so that it has no real effect on the syntax of the log_this keyword but just causes it to be no-opped as appropriate, then the custom parsing could be dropped in for a speed-up only on those versions of Perl that support it (5.14+), but it would still work on older Perls.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

      tobyink++,

      Thanks for the pointer to Keyword::Simple as well.

Re: Moose based logging question
by RichardK (Parson) on Feb 09, 2014 at 14:39 UTC

    I'd recommend following Test-driven_development instead. Then when you've made a change you _know_ that the code still works properly because it passes the test suite. That's far far easier then grovelling through log files trying to work out what's gone wrong and has no runtime overhead.

    Personally, I find test driven development the most productive way to write code, and Test::Simple / Test::More are very easy to work with.

      I'm not sure if you read the readmore section of my posting but I am familiar with the three links you provided and have used both of the test modules that you posted. I do write tests for code deliverables that I am working on.

      The piece of development I am referencing is the unforeseen element of code performance in as-yet unguessed circumstances. This often occurs when I combine an old package with some new package to fulfill an additional requirement that was not initially identified during the development of the old package. Another case is when an old package is fed an unforeseen corner case set of data. I know there is a whole science for creating these corner cases for test including Devel::Cover however I am generally lucky to get time to get basic tests in place before other functionality is required. When I find a bug I write a test so the bug won't come back but if I don't know about the bug in advance I move on.

Re: Moose based logging question
by Bloodnok (Vicar) on Feb 10, 2014 at 14:37 UTC
    The documentation (Log::Log4perl) perldoc shows that there is a direct, in-built means of achieving this in the section 'Resurrecting Hidden Log4perl Statements'.

    A user level that continues to overstate my experience :-))

      Bloodnok The farther I get in this project the more appreciation I have for Log::Log4perl and the work that went into it.

      Update: The :resurrect tag does appear to use a source filter which is not universally loved

Re: Moose based logging question
by jellisii2 (Hermit) on Feb 10, 2014 at 12:45 UTC
    What were the shortcomings of Log:Log4perl that caused you to look for another solution? You can set the level of each appender individually without too much trouble, so you can make the program as quiet as you wish. I don't see anything in your example that Log4perl couldn't accommodate.
      jellisii2,

      My question (and sample code) wasn't intended to be an indictment of Log4perl which is a well written and well thought out program with lots of good community support. I apologize if I did not correctly communicate that earlier. I have included a list below of why I went out on my own designing a new logger but in the end you might be able to chalk it up to a learning experience. For starters tobyink has finally motivated me to learn about and try prototypes, introduced me to the bang bang operator, and pointed me to an intriguing module which is worth the effort all on it's own.

      Ultimately, I guess I prefer perl because we embrace TIMTOWDI. As you will note if you have read my list of reasons I also listed set of behaviours from Log4perl that I tried to preserve. Additionally I am fairly certain that the behaviours I am trying to preserve have been implemented less cleanly than the mainstream loggers. For me the journey is the goal and I'm just trying to have fun on the way.

        Wanting to reinvent the wheel for personal edification is one thing. Wanting to reinvent the wheel for production code is quite another.

        Good luck on your pursuit, but beware putting it into a major production environment. Someone that's not you will have to maintain it at some point.

        BTW, I have no opinions on any of the OO frameworks for perl. I don't use any of them yet.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (6)
As of 2024-04-23 12:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found