in reply to Inversion of control: logging and configuration

I just did almost this exact same thing for a large set of scripts I wrote.

With regards to Log::Log4perl (which I really like btw) you only need to configure the module it once. Your 'Main' calls Log::Log4perl->init once and then any other package called just needs you to use the module and set up the logging variable. If your doing an OO module, you can even write a base class that sets up your logging variable automatically (I prefer class type instead of __PACKAGE__ for inheritance in OO logging).

sub new { my $self = shift; my $class = ref($self) || $self; my $self->{logger} = get_logger($class); ... } #following allows $object->debug("debug statement"); #may need log4perl up-stack-call(?) for traceback sub debug { my ($self,$message) = @_; $self->{logger}->debug($message); return $self; }

If you forget to set up your logger in a script using the module log4perl is should print out a warning that you didn't init it. Log4perl even has an 'easy' mode where it will do the init for you (but I haven't found the defaults to my liking for a production script).

Another thought is to have your program initialization done in a BEGIN block. Then have your modules check in an INIT block that the logger/config variables they require exist. I don't like using a BEGIN for this type of a solution but it may fit your needs.

A last option is to define a generic 'startup module' with a 'initialization' routine that is called once. Each module that needs logging/configuration would use the package and call this function in a BEGIN or INIT block. I like this idea except that I generally like per-program config files and changing config/logging information via Getopts::Long which this idea makes hard to do.

The large problem I struggled with and couldn't solve was that I wanted configuration parameters to control the logging but then I wanted to log the loading of configuration parameters (chicken and egg)...which is something I still haven't solved.

Fendaria