[Python-ideas] Logging2 with default NullHandler

anatoly techtonik techtonik at gmail.com
Fri Mar 16 09:33:34 CET 2012


On Fri, Mar 16, 2012 at 5:10 AM, Cameron Simpson <cs at zip.com.au> wrote:
> On 16Mar2012 00:39, anatoly techtonik <techtonik at gmail.com> wrote:
> | > | What do I want from library logging as a Python application developer?
> | > | Nothing until I explicitly setup default behaviour.
> | >
> | > Fair point.
> | >
> | > Conversely, almost every app I write commences thus:
> | >  from cs.logutils import setup_logging
> | >  def main(argv):
> | >    setup_logging()
> | >    ... main code ...
> | >
> | > That sends to stderr with frills. Finer grained setup can come later.
> |
> | But that makes all such libraries dependent on cs.logutils, which is
> | not an option.
>
> No, it doesn't. setup_logging just sets up the root logger somewhat.
> Your apps need some kind of convenience routine like it, is all.
> It can be very small.
>
> All the libraries have unchanged vanilla logging calls.
> For example, I use SQLalchemy et al under this scheme. The libraries
> don't know about cs.logutils at all.
>
> | In my case these libraries are self-contained PySide
> | widgets that can be used standalone or from an IDE. Adding dependency
> | on cs.logutils makes them too tied to application.
>
> The libraries don't use my convenience module. My module just makes a whole
> bunch of setup I happen to like reduce to just two lines of code in my app,
> import and setup call.

So, your scenario is clear. You have an application where you
configure logging and none of your libraries are used without this
configuration. This is a doable scenario for logging module.

But logging2 is needed for the opposite user story - when you have a
bunch of independent libraries that are used from scripts, from
application or standalone, and you need to make them silent by
default. Doing this requires inserting a logging configuration into
the header of every library. Things are dim, because 3rd party
libraries don't come with these headers. Moreover - it is unclear if
this configuration won't break the logging when you finally have to
turn it on for this particular lib from an application.

> | > I _think_ I prefer logging's current behaviour:
> | >  - I do want a big fat warning if I forget to configure logging at all
> |
> | Unless your application uses alternative logging means and doesn't use
> | logging at all (unlike 3rd party libraries it uses).
>
> If the 3rd party libraries use the logging module and you don't want
> logging happening, just configure logging to throw stuff away.

The problem that I don't know and probably don't want to think about
logging schemes used by those libs. When the time comes to
troubleshoot these libs then sure - the logging will be the first
thing I'll look into.

> | >  - I don't want lobraries doing sufficient work at import time to
> | >    warrant logging anything
> |
> | I do not want libraries doing any logging setup work at import either.
> | They should just need to contain 'extension points' for plugging log
> | handlers in case I need to debug these modules.
>
> Well, they do. Via logging. Supply an adapter handler to hook their
> calls to logging to your alternative logging means. Logging doesn't have
> to log to files/syslog/smtp etc - you can sent it anywhere. I'm sure you
> know that, so I think I'm missing some subtlety in your use case.

Yes, the argument in not about API for 'extension points' (logging
does that). The argument that logging does implicit extra work, and it
requires even more extra work to cancel the produced effects. More
over, the effects of this default implicit work are non-deterministic
- that means they depend on execution flow in you program. The effects
will be different if you toss these events in random order:

- root config is set by application
- logging.log() or friends called
- getLogger('some.dotted.name').warn() called

Basically, proper logging setup also requires to care about import
order of you application. It's not a problem if you have a single
entry point, but becomes a PITA with multiple entrypoints or in
exploratory programming (IPython?) sessions.

"Don't let me think" is the greatest usability principle of all times,
and logging module, unfortunately fails to comply. Backward
compatibility won't let it to be fixed. And that's why a predictable
logging2 module is needed.
-- 
anatoly t.



More information about the Python-ideas mailing list