Logging with multiple loggers/handlers

Discussion in 'Python' started by Jeff Shannon, Jul 6, 2004.

  1. Jeff Shannon

    Jeff Shannon Guest

    I'm having some difficulty getting my logging configuration set
    correctly. I'm using a config file (copied at end of post), with the
    intent of setting several loggers which write to a combination of a
    file, stderr (for debugging), and the NT Eventlog, but I don't seem to
    be getting the right combination of handlers called.

    The desired combinations are as follows:

    root - Eventlog, stderr
    log02 - file, stderr
    log02.log03 - file, stderr
    log02.log04 - Eventlog, file, stderr

    Currently, logging to stderr is working for all four loggers, but only
    log02 is being written to the logfile. Also, log03 is writing to the
    Eventlog even though it shouldn't be reaching that handler at all.

    Any suggestions as to how I could change my logconfig.ini to get the
    desired effect? (I'm considering creating an 'init' logger off of the
    root, which would handle the Eventlog records, thus allowing me to
    propagate all the stderr records to root, but this doesn't seem like
    it'd directly affect the parts I'm having problems with...)

    For reference, I'm using Python 2.2.1 and v0.4.9.2 of the logging
    package. (Upgrading to a newer version of Python is not preferred,
    though it could be done if it'll resolve the problem, but I've gathered
    that the logging package *should* work fine with Py2.2.)

    Jeff Shannon
    Technician/Programmer
    Credit International

    ----- logconf.ini -------------------------
    [loggers]
    keys=root,log02,log03,log04

    [handlers]
    keys=hand01,hand02,hand03

    [formatters]
    keys=form01

    [logger_root]
    level=NOTSET
    propagate=1
    channel=
    parent=
    qualname=(root)
    handlers=hand01,hand03

    [logger_log02]
    level=DEBUG
    propagate=0
    channel=log02
    parent=(root)
    qualname=log02
    handlers=hand02,hand03

    [logger_log03]
    level=DEBUG
    propagate=1
    channel=log03
    parent=log02
    qualname=log02.log03
    handlers=

    [logger_log04]
    level=DEBUG
    propagate=1
    channel=log04
    parent=log02
    qualname=log02.log04
    handlers=hand01

    [handler_hand01]
    class=handlers.NTEventLogHandler
    level=DEBUG
    formatter=form01
    appname=LogTest
    dllname=
    logtype=Application
    args=('LogTest', '', 'Application')

    [handler_hand02]
    class=FileHandler
    level=DEBUG
    formatter=form01
    filename=Logs\python.log
    mode=a
    args=('Logs\python.log', 'a')

    [handler_hand03]
    class=StreamHandler
    level=DEBUG
    formatter=form01
    stream=sys.stderr
    args=(sys.stderr,)

    [formatter_form01]
    format=%(asctime)s %(name)s %(levelname)s %(message)s
    datefmt=
     
    Jeff Shannon, Jul 6, 2004
    #1
    1. Advertising

  2. Jeff Shannon

    Jeff Shannon Guest

    To follow up to my own post -- I've found my problem, and it appears to
    have been between my ears. ;P

    I somehow managed to misinterpret the spec for logging.getLogger().
    From the current docs:

    getLogger([name]):
    Return a logger with the specified name or, if no name is specified,
    return
    a logger which is the root logger of the hierarchy.

    All calls to this function with a given name return the same logger
    instance.
    This means that logger instances never need to be passed between
    different
    parts of an application.

    Combined with this bit from PEP 282:


    Loggers are never instantiated directly. Instead, a module-level
    function is used:

    def getLogger(name=None): ...

    If no name is specified, the root logger is returned. Otherwise,
    if a logger with that name exists, it is returned. If not, a new
    logger is initialized and returned. Here, "name" is synonymous
    with "channel name".

    And the descriptions of the config file
    (http://www.red-dove.com/python_logging.html#config):

    #The channel value indicates the lowest portion of the channel name
    of the
    #logger. For a logger called "a.b.c", this value would be "c".

    All of this combined to give me the impression that the name that's
    passed to getLogger() should be the "lowest portion" channel name,
    rather than the fully qualified name -- i.e., that I should be using
    "log03" instead of "log02.log03". As it turns out, my impression was
    wrong -- it's the fully qualified name that should be used. My attempts
    to use the unqualified name were creating new, unconfigured loggers
    (with no handlers attached) that could only propagate records up to the
    root logger. I realized this only after inspecting the log manager's
    loggerDict and seeing the unconfigured "extra" loggers.

    While it's fairly likely that my interpretation of the docs is not
    something that many people will come up with, I think it might be
    worthwhile to expand the example sections to actually show how to use
    multiple heirarchical loggers. Had there been an example to follow, I
    certainly wouldn't have made this mistake.

    Jeff Shannon
    Technician/Programmer
    Credit International
     
    Jeff Shannon, Jul 8, 2004
    #2
    1. Advertising

  3. Jeff Shannon

    Vinay Sajip Guest

    > Loggers are never instantiated directly. Instead, a module-level
    > function is used:
    >
    > def getLogger(name=None): ...
    >
    > If no name is specified, the root logger is returned. Otherwise,
    > if a logger with that name exists, it is returned. If not, a new
    > logger is initialized and returned. Here, "name" is synonymous
    > with "channel name".
    >
    > And the descriptions of the config file
    > (http://www.red-dove.com/python_logging.html#config):
    >
    > #The channel value indicates the lowest portion of the channel name
    > of the
    > #logger. For a logger called "a.b.c", this value would be "c".
    >
    > All of this combined to give me the impression that the name that's
    > passed to getLogger() should be the "lowest portion" channel name,
    > rather than the fully qualified name -- i.e., that I should be using
    > "log03" instead of "log02.log03". As it turns out, my impression was
    > wrong -- it's the fully qualified name that should be used.


    > While it's fairly likely that my interpretation of the docs is not
    > something that many people will come up with, I think it might be
    > worthwhile to expand the example sections to actually show how to use
    > multiple heirarchical loggers. Had there been an example to follow, I
    > certainly wouldn't have made this mistake.


    The example in http://www.red-dove.com/python_logging.html#config does
    show in bold the items used by the configuration API, and says that
    the others are just used by the GUI configurator. Perhaps "channel"
    was the wrong name to use for a private element in the configurator,
    but it's done now.
     
    Vinay Sajip, Aug 6, 2004
    #3
  4. Jeff Shannon

    Jeff Shannon Guest

    Vinay Sajip wrote:

    >>While it's fairly likely that my interpretation of the docs is not
    >>something that many people will come up with, I think it might be
    >>worthwhile to expand the example sections to actually show how to use
    >>multiple heirarchical loggers. Had there been an example to follow, I
    >>certainly wouldn't have made this mistake.
    >>
    >>

    >
    >The example in http://www.red-dove.com/python_logging.html#config does
    >show in bold the items used by the configuration API, and says that
    >the others are just used by the GUI configurator. Perhaps "channel"
    >was the wrong name to use for a private element in the configurator,
    >but it's done now.
    >
    >


    May I suggest changing the wording of the getLogger() docs? I think
    that simply adding a few words to a single sentence will clarify things
    considerably.

    - Here, "name" is synonymous with "channel name".
    + Here, "name" is synonymous with "fully qualified channel name".

    Jeff Shannon
    Technician/Programmer
    Credit International
     
    Jeff Shannon, Aug 7, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert
    Replies:
    0
    Views:
    458
    Robert
    Aug 30, 2007
  2. nico
    Replies:
    3
    Views:
    468
    Arne Vajhøj
    Jan 19, 2008
  3. temp00
    Replies:
    0
    Views:
    447
    temp00
    Jun 25, 2008
  4. Rhino
    Replies:
    8
    Views:
    546
    markspace
    Apr 30, 2010
  5. Gábor Farkas
    Replies:
    0
    Views:
    188
    Gábor Farkas
    Nov 7, 2011
Loading...

Share This Page