http://qs321.pair.com?node_id=295310

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

Recently I've written a Sendmail::Milter, and now it all seems to at least work I'm looking into making it production-ready.

Since a lot of the programmers here are Java-people I've tended to lean toward Log4perl as my logging and error-reporting system since it's vaguely similar to what they (and hence the sysadmins) here are most used to, and it's also more than configurable and robust enough for my uses.

The problem I'm now faced with is that Milter is a threaded module, and I'm not sure if Log4perl is able to run reliably in such an environment. Since reliability is a major goal here I'm loathe to use it for this unless someone can reassure me that it'll still work will.

Anyone capable of making reassuring noises in my direction regarding Log4perl and threads? If not, does anyone have any suggestions for a suitably robust and flexible workaround?

Replies are listed 'Best First'.
Re: Will Log4perl work threaded?
by broquaint (Abbot) on Sep 30, 2003 at 15:30 UTC
    Having a quick peek at the source for Log::Log4perl::Appender::File it would appear that it will not be thread-safe due to its lack of file locking. But if you're using the Log::Log4perl::Appender::DBI layer you should be fine as DBI is thread-safe (in theory, at least).

    As for a solution, I'd say just override the specific logging methods e.g

    sub Log::Log4perl::Appender::File::log { my($self, %params) = @_; my $fh = $self->{fh}; flock( $fh => LOCK_EX ); print $fh $params{message}; flock( $fh => LOCK_UN ); if ($self->{autoflush}) { my $oldfh = select $self->{fh}; $| = 1; select $oldfh; } }
    Or perhaps create just a wrapper function/method that does the flocking before and after the call to the logging function.

    HTH

    _________
    broquaint

Re: Will Log4perl work threaded?
by liz (Monsignor) on Sep 30, 2003 at 15:25 UTC
    Good question. I have no idea as I have never used Log4Perl. The following questions come up when I read your question:

    • Have you tried it and seen any errors?
    • Are you logging from multiple threads to the same "log"?
    • Have you tried putting a lock around the actual logging (if you see problems with logging).
    • Is there a test-suite?

    I don't see any immediate reasons why there would be any problems using log4perl with threaded programs. But I could easily be very wrong.

    Liz

      Thanks for the feedback.. in response to your questions..

      • I had tried it to some extent, and hadn't seen difficulties. The issue though is that I can imagine it being the kind of thing that'd seem perfectly happy that one time something unforeseen happened and it's under incredible load.. at which point it all goes horribly wrong, data loss and badness.
      • It would be logging from all of the concurrent threads to the logfile since, in principle at least, all of the threads constitute the one service and those responsible for administering it would probably prefer a single easy-to-read log.
      • I'd not tried putting the lock there since I'd not seen the problem yet, also if Log4perl was happy multithreaded then I'd rather not have the performance hit of another set of locking.
      • The seperate functions have unit tests as far as is practical, unfortunately given the way the module slimes under the skin of Sendmail the only full way to test it is to fire off a bunch of mails at it and check it does what's expected. There is a basic test for this too, but it doesn't touch the logging as yet.