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

I'm trying to envision the best way of sharing a log file across multiple packages (which happen, also, to be classes). I'm using Log::Common to handle the log file.

My classes are, say, Foo::Foo, Foo::Bar, and Foo::Baz. There's no "master class" and the Foo::* classes don't inherit from one another.

I can think of a few ways of doing this: I can create a package--say, Foo--which exports a package global $LOG that contains the Log::Common object. The Foo::* classes would need only "use Foo" to gain access to $LOG.

Or, I could create a wrapper class for Log::Common, then instantiate and export a single Foo::Log object to each Foo::* class... though, under the circumstances, it seems redundant.

Is there anything I'm missing? Glossing over? How would you share a single log file across multiple classes?

Thanks!

baphomet.

Replies are listed 'Best First'.
Re: Sharing a log file across classes...
by dragonchild (Archbishop) on Feb 27, 2002 at 19:57 UTC
    Use a singleton factory. Create a class that instantiates a a logger once. Then, every call to this factory will return the same instance. Something along the lines of
    package Factory::Singleton::Log; my $LOGGER = Log::Common->new(SOME PARAMETERS HERE); sub new { my $class = shift; return undef if ref $class; return $LOGGER; } 1; __END__

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      I'm not sure it needs to even be that complex. If you are using all three classes in the same script, why not simply pass the log object in the constructor?
      my $log = Log::Common->new; my $foo = Foo::Foo->new('log' => $log); my $bar = Foo::Bar->new('log' => $log); my $baz = Foo::Baz->new('log' => $log);
      I have used a similar method for sharing database handles amongst several different classes.
        That is definitely a perfectly good way of doing things. However, I like to encapsulate things. The client of that class hierarchy doesn't need to know what logger is being used, so allow for some default behavior. If the client wishes to override that behavior, then allow for a logger to be set, both in the constructor and by some 'setter'.

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: Sharing a log file across classes...
by Matts (Deacon) on Feb 27, 2002 at 21:28 UTC
    use Log::Dispatch::Config; # log4j for perl

    It's definitely the best logging option out there, supports very flexible logging to all sorts of different destinations, and is very well supported by the author. It provides logging via a singleton, as shown above, so it's very easy to ensure you're logging to the same place(s) from everywhere in your application.

Re: Sharing a log file across classes...
by rbc (Curate) on Feb 27, 2002 at 23:07 UTC
    This may be too simplestic a solution but you could write
    any output that needs to be logged to STDOUT or STDERR and
    start your script like so ...

    myScript.pl >& log