Re: logging module example



Chris Smith schrieb:
Hola, pythonisas:
 The documentation for the logging module is good, but a bit obscure.
 In particular, there seems to be a lot of action at a distance.
 The fact that getLogger() can actually be a call to Logger.__init__(),
which is mentioned in para 6.29.1, also bears stressing on 6.29.  I
grasp _why_ you'd implement it that way, but I may not be the only
coder who feels queasy with the word 'get' being used both to fetch
an instance and to trigger instantiation.

The reason for this "distance" is simply that you should be able to get a grip on a logger from wherever you are, explicitly _without_ first having to instantiate it and possibly pass it around. Think of this little example:


class Mixin(object):
    def foo(self):
        logger = logging.getLogger("MixinLogger")
        logger.debug("I'm foo!")

    def bar(self):
        logger = logging.getLogger("MixinLogger")
        logger.debug("I'm bar!")

class User(Mixin):

    def some_random_method(self):
        if relative_moon_humidity() > .8:
            self.foo()
        else:
            self.bar()


So the decoupling makes lots of sense in logging IMHO.

Anyway, after poring over the documentation, unit test, and source code,
I'd like to show a sample script that will eventually be used in my vanity project, with four loggers of increasing granularity.
I realize there are probably more ways to do this (logging seemingly
sporting perl-esque flexibility ;) so please weigh in with thoughts.
Perhaps now I can go back and get this to work with the
logging.config interface. :)

forest = ["root","trunk","branch","leaf"]
#relate our logger names to levels
lumber_jack = {forest[0] : logging.DEBUG
              ,forest[1] : logging.INFO
              ,forest[2] : logging.WARNING
              ,forest[3] : logging.ERROR  }
#Used to build up the log names into a hierarchy
log_name = []

for log in forest:
    mounty  = logging.FileHandler("%s%s.txt" % ("/home/smitty/mddl/",log))
    log_name.append(log)
    print "Instantiating %s"  % ".".join(log_name)
    timber  = logging.getLogger(".".join(log_name))
    timber.setLevel(lumber_jack[log])
    timber.addHandler(mounty)
    if   lumber_jack[log] == logging.DEBUG:
        timber.debug(  "%s's a lumberjack, and he's OK." % log)
    elif lumber_jack[log] == logging.INFO:
        timber.info(   "%s's a lumberjack, and he's OK." % log)
    elif lumber_jack[log] == logging.WARNING:
        timber.warning("%s's a lumberjack, and he's OK." % log)
    elif lumber_jack[log] == logging.ERROR:

That looks as an misunderstanding or somewhat strange usage of the logging-api. It is _very_ uncommon to have loggers level depending on _data_. Instead you just invoke


logger.debug(some_data)

and set the level elsewhere. That is a somewhat static rleationship - all forests are supposed to share _one_ logging instance, with it's current log-level. And you don't check for the level being DEBUG or whatever. You just log, and if the level is above (or below, whatever stance you take) the currently set level for that logger, the message gets displayed.

All in all it seems that you have some difficulties with the loggers being a sort of global objects. Keep that in mind when developing using them.

Regards,

Diez
.



Relevant Pages

  • Re: General question about logging concept
    ... or class to Debug to get more log messages (assuming you have more ... Also, by default the log messages include the logger info, so it's a ... Once you configure logging it's configured for the entire appdomain, ... I'm just now configuring some logging module in my web app (I'm using ...
    (microsoft.public.dotnet.framework.aspnet)
  • logging via SocketHandler and TCPserver
    ... I find that I REALLY need to be able to monitor LOTS of running programs/processes and thought it would be nice to have them use SocketHandler logging and then I would write TCPServer to accept the log messages for real-time monitoring. ... I Googled for several hours and came up with some code that I've turned in to something that works, but I can't figure out how to disconnect the server once it is connected The goal is to be able to start TCPServer, monitor the log messages sent via SocketHandler logger, disconnect, and move to the next application. ... def unPickle: ...
    (comp.lang.python)
  • Passing contextual information when logging
    ... difficulty of passing additional contextual information when logging. ... Logger instances. ...
    (comp.lang.python)
  • Re: Problem with logging module
    ... >call it within a program using the unittest module, ... logging uses internal data ... you create an instance of your logger class, ... you can also set a formatter on the handler which will ...
    (comp.lang.python)
  • Re: Logging: how to suppress default output when adding handlers?
    ... dozen files and a bunch more libraries and if they're doing a logging.debugor whatnot they're creating this. ... SQLAlchemy) would log to the root logger. ... It's by logging to an ...
    (comp.lang.python)