"Abstract" has two meanings, so I think that could be confusing. I think Log::Any is better.
On 9/7/07, Jonathan Swartz <[EMAIL PROTECTED]> wrote: > That is very true. That is why I'd volunteer to patch the major > modules in a backwards-compatible way. > > Incidentally, this is also being commented on here: > > http://use.perl.org/~jonswar/journal/34366 > > and the name Log::Abstract was suggested, which I like a lot more, so > I'm leaning towards that now. > > Thanks for your feedback, > Jon > > On Sep 7, 2007, at 10:27 AM, Bill Ward wrote: > > > 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 > >> > >> > >