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
>
>

Reply via email to