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

Reply via email to