in reply to Safe::Logs - Feedback appreciated

I have to admit that I'm too busy right now to review your code, but you asked that I reply here to a couple of points from your other thread.

I had to do something like what you describe for a log module I wrote, (although kind of the opposite as you will see). The objective was to retrofit a bunch of existing poorly looged scripts. My idea was to write a module that would allow a simple added use line to cause all activity on STDERR and STDOUT to get redirected to a log file. My approach was to tie STDOUT and STDERR, as well as add traps to $SIG{__WARN__} and $SIG{__DIE__}. (In hindsight overriding CORE::GLOBAL::die() and CORE::GLOBAL::warn() might have been better, but this catches errors from Perl itself, which can be useful.)

This way virtually all output activity is intercepted, regardless if a module is the one that used the logger or not. In fact it probably is simpler than your approach as things like warnings::warn() actually use Carp which in turn use CORE::warn, which is in turn intercepted by the $SIG{__WARN__} handler, likewise for die().

Generally speaking it works well, problems however occur when programs use sneaky ways to get access to the standard filehandles, and when other code installs $SIG{__FOO__} handlers and doesnt behave nicely. The latter is rare, but difficult to deal with as there isnt really a stated "nice" behaviour. For me its been rare enough that it hasnt been an issue. I still wonder when itll bite me though. :-)

Anyway, I still think that arguably the best thing to do in your situation, is write a logfile reader, or a sanitizer of some sort. This is the only real way to address the fact that it will be almost impossible to intercept all writes to the log files in question wheras it is probably feasable to ensure that the files are not read without a tool. But thats not for me to decide is it? :-)

---
demerphq


Replies are listed 'Best First'.
Re: Re: Safe::Logs - Feedback appreciated
by fokat (Deacon) on Mar 04, 2003 at 01:36 UTC
    Anyway, I still think that arguably the best thing to do in your situation, is write a logfile reader, or a sanitizer of some sort. This is the only real way to address the fact that it will be almost impossible to intercept all writes to the log files in question wheras it is probably feasable to ensure that the files are not read without a tool. But thats not for me to decide is it? :-)

    Well, actually I tried to send email to the maintainer of Logfile::Rotate to see if he would be interested in adding this features to the package. Unfortunately the email bounced...

    I agree with your point. However, teaching old-dogs new-tricks is not easy. Many people use tail -f or similar, so building and deploying a log-reader will take some time. I thought this would be a quick solution for, say, 70% of the problem in our case.

    Again, thanks a lot for your comments.

    Best regards

    -lem, but some call me fokat

      Well, actually I tried to send email to the maintainer of Logfile::Rotate to see if he would be interested in adding this features to the package. Unfortunately the email bounced...

      Did you try his CPAN address? That's different from the one in the module.

      Hugo

      This actually raises what is to me an interesting question. What to do when your work uses an open source module whose author is either not able or willing to make the modifications you would like, or disappears completely so cannot make any patches at all?

      Here we have branched a couple of modules where the authors were unresponsive or dismissive of our changes. So now we use a custom version of MIME::Lite and Config::Inifile the former because Eryq doesnt answer mails and hasn't updated the module (despite posted bugfixes) in two years, and the latter because despite providing patches the authors decided they didn't want the functionality we needed. This means that for these modules we use our own distributions, which is annoying but better than doing a complete rewrite to utilize a supported module.

      After conversations with a number of Open Source types lately Ive been seriously thinking about hijacking MIME::Lite until the author returns to Perldom. In fact we were contemplating a "CPAN Orphanage", perhaps a sourceforge project for all the CPAN modules whose authors have abandonded them.

      So I guess the relevent point to you is that if you want a patched Logfile::Rotate and you cant get the author to integrate the change, then fork it and use your local copy anyway. If the author isn't maintaining the module anyway I dont see any reason not to.

      ---
      demerphq


        Another approach is to subclass the module, or intercept calls. For a work project, I wasn't happy with the Pod::Html output, so I hacked in some changes that vary depending on the version:

        sub per_version { if ($Pod::Html::VERSION eq '1.01') { # perl5.005_03 *Pod::Html::process_text2 = \&Pod::Html::process_text1; undef *Pod::Html::process_text1; *Pod::Html::process_text1 = \&my_process; @options = qw/ --recurse --header /; } elsif ($Pod::Html::VERSION =~ /^1\.0[34]$/) { # perl-5.6.0, 5.6.1, 5.8.0 *Pod::Html::process_L2 = \&Pod::Html::process_L; undef *Pod::Html::process_L; *Pod::Html::process_L = \&my_oldprocess; @options = qw/ --recurse /; } else { die "Don't know how to hack Pod::Html v$Pod::Html::VERSION\n"; } sub my_process ($$;$$) { my($lev, $rstr, $func, $closing) = @_; my $closer = '>' x (($closing||0) + 1); if ($func && $func eq 'L') { # suppress 'the ... manpage' markup $$rstr =~ s{^ ^ ( \w+ (?: ::\w+ )* ) (?: -(?!$closer)> (\w+) )? (.*?) (\s* $closer) }{ defined($2) ? qq{$1-E<gt>$2$3|$1/"item_$2$4} : "$1$3|$1$4" }xe; } Pod::Html::process_text2($lev, $rstr, $func, $closing); } sub my_oldprocess { my($str) = @_; $str =~ s,^(\w+(::\w+)*)$,$1|$1/,; Pod::Html::process_L2($str); }

        This approach isn't always the right one, but it's a useful tool to have.

        Hugo
        This actually raises what is to me an interesting question. What to do when your work uses an open source module whose author is either not able or willing to make the modifications you would like, or disappears completely so cannot make any patches at all?

        Well, in my case it happened with Radius::Packet and Radius::Dictionary. I added support for vendor-specific attributes but was unable to make the author update the code. Finally, I decided to steal the module while maintaining full credits to the original author. My revised distribution now lives in Net::Radius. I hope my work is doing justice to the excellent work of the original author...

        For other things, we just keep a collection of patches around. I always try to let the author know about the patches and in almost all cases, I've had luck. Sometimes the problem lies in contacting the author, for which the CPAN addresses are very useful. In fact I just got a nice hint a couple of posts above.

        Best regards

        -lem, but some call me fokat