I like the concept of this, but I think to be successfull you need buy-in from the various log package authors as well as more than a few core module authors. The name Log::Any sounds as good as any (har har) but in this case, I think naming is the least of your worries.
On 9/6/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > This is a proposal for a minimal log-facilitation package that > provides modules with a standard log API while leaving the choice of > log framework and configuration to the application. > > TOO MANY WAYS TO LOG > > It seems as if every CPAN module has its own way of logging debug > information and error conditions. For example: > > * LWP - activate by use'ing LWP::Debug; outputs to STDERR > * DBI - activate by calling DBI->trace(); outputs to STDERR or a > file > * Rose::DB - activate by setting various $Debug package variables; > outputs to STDERR > * Encode::* - activate by modifying various DEBUG subroutines to > return 1; outputs using warn() > * Apache::* - activate by setting the Apache log level and > restarting; outputs to the Apache logs > > In addition, many CPAN modules do not log anything at all, possibly > because they don't want to invent another logging mechanism or become > dependent on an existing one. > > This situation is pretty much the opposite of what I want when > developing a large application. I want a single way to turn logging on > and off, and to control where logs get sent, for all of the modules > I'm using. > > This being Perl, there are many fine logging frameworks available: > Log::Log4perl, Log::Dispatch, Log::Handler, Log::Agent, Log::Trivial, > etc. So why do CPAN modules eschew the use of these and invent their > own mechanisms that are almost guaranteed to be less powerful? > > * The very existence of so many logging modules means that there is > no one standard that a CPAN author would feel comfortable binding > their users to. As usual, TMTOWTDI is a double-edged sword. > > * A logging framework can be a significant dependency for a module > to have, easily dwarfing the size of the module itself. For small > modules that want to minimize dependencies, depending on Log4perl (for > example) is a non-starter. > > A COMMON LOG API > > One thing to notice is that while the logging frameworks all differ in > their configuration and activation API, and the set of features they > support, the API to log messages is generally quite simple. At its > core it consists of > > * A set of valid log levels, e.g. debug, info, warn, error, fatal > > * Methods to log a message at a particular level, e.g. $log- > >debug() > > * Methods to determine if a particular level is activated, e.g. > $log->is_debug() > > I expect most CPAN modules would happily stick to this API, and let > the application worry about configuring what's getting logged and > where it's going. Therefore... > > PROPOSED MODULE: LOG::ANY > > I propose a small module called Log::Any that provides this API, with > no dependencies and no logging implementation of its own. Log::Any > would be designed to be linked by the main application to an existing > logging framework. > > A CPAN module would use it like this: > > package Foo; > use Log::Any; > my $log = Log::Any->get_logger(category => __PACKAGE__); > > $log->debug("a debug message") > if $log->is_debug(); > > $log->error("yikes!"); > > By default, methods like $log->debug would be no-ops, and methods like > $log->is_debug() would return false. > > As a convenient shorthand, you can use > > package Foo; > use Log::Any qw($log); > > $log->debug("a debug message") > if $log->is_debug(); > > where $log is a newly created logger object, initialized with the > package name of the caller and imported as a package-scoped variable. > > An application that wished to activate logging would call Log::Any- > >set_logger with a single argument: a subroutine that takes a log > category and returns a logger object implementing the standard logging > API above. The log category is typically the class doing the logging, > and it may be ignored. > > For example, to link with Log::Log4perl: > > use Log::Any; > use Log::Log4perl; > > Log::Log4perl->init("log.conf"); > Log::Any->set_logger(sub { Log::Log4perl->get_logger(@_) }); > > To link with Log::Dispatch, with all categories going to the screen: > > use Log::Any; > use Log::Dispatch; > > my $dispatcher = Log::Dispatch::Screen->new(...); > Log::Any->set_logger(sub { $dispatcher }); > > To link with Log::Dispatch, with different categories going to > different dispatchers: > > use Log::Any; > use Log::Dispatch; > > my $dispatcher_screen = Log::Dispatch::Screen->new(...); > my $dispatcher_file = Log::Dispatch::File->new(...); > > sub choose_dispatcher { > my $category = shift; > return $category =~ /DBI|LWP/ ? $dispatcher_file : > $dispatcher_screen; > } > Log::Any->set_logger(\&choose_dispatcher); > > set_logger will be implemented so as to take effect on all existing as > well as future loggers. Any $log objects already created inside > modules will automatically be switched when set_logger is called. > (i.e. $log will probably be a thin proxy object.) This avoids imposing > any order on module loading, and allows set_logger to be called more > than once per application. > > PROMOTING USE > > For Log::Any to be useful, a substantial number of modules - > especially major modules - would have to adopt its use. Fortunately, > with its minimal footprint and standalone nature, authors should not > find Log::Any a difficult dependency to add. Existing logging > mechanisms, such as LWP::Debug and $DBI::tfh, could easily be > converted to write *both* to their existing output streams and to > Log::Any. This would preserve backward compatibility for existing > applications, but allow new applications to benefit from more powerful > logging. I would be willing to submit such patches to major module > authors to get things going. > > MODULE NAME > > Other potential names for this module: > * Log::Service > * Log::Proxy > * Log::API > > However, since many log frameworks themselves have similar "generic" > names (e.g. Log::Dispatcher), I felt that Log::Any was the most > distinct. > > FEEDBACK? > > Feedback is most welcome. Thanks! > > Jon > >