Making logging.getLogger() simpler

Discussion in 'Python' started by Lie Ryan, Sep 18, 2010.

  1. Lie Ryan

    Lie Ryan Guest

    I was expecting this to work:

    import logging
    logger = logging.getLogger(__name__)
    logger.warn('this is a warning')

    instead it produced the error:

    No handlers could be found for logger "__main__"


    However, if instead I do:

    import logging
    logging.warn('creating logger')
    logger = logging.getLogger(__name__)
    logger.warn('this is a warning')

    then it does work.

    Is there any reason why getLogger()-created logger shouldn't
    automatically create a default handler?
     
    Lie Ryan, Sep 18, 2010
    #1
    1. Advertising

  2. Lie Ryan

    Kev Dwyer Guest

    On Sun, 19 Sep 2010 02:35:15 +1000, Lie Ryan wrote:

    > I was expecting this to work:
    >
    > import logging
    > logger = logging.getLogger(__name__)
    > logger.warn('this is a warning')
    >
    > instead it produced the error:
    >
    > No handlers could be found for logger "__main__"
    >
    >
    > However, if instead I do:
    >
    > import logging
    > logging.warn('creating logger')
    > logger = logging.getLogger(__name__)
    > logger.warn('this is a warning')
    >
    > then it does work.
    >
    > Is there any reason why getLogger()-created logger shouldn't
    > automatically create a default handler?


    Hello Lie,

    Calling logging.warn(), or logging.debug() etc. before handlers
    have been assigned to the root logger will result in
    logging.basicConfig() being called automatically. By default a
    StreamHandler will be created on the root logger and your logger
    inherits the StreamHandler. So you can avoid the "No handlers..."
    warning by calling logging.basicConfig() before your program
    does any logging.

    I don't know why getLogger() doesn't so something similar when
    it's called. Perhaps so that the logger is explicitly
    initialised with basic, file or dictConfig?

    Cheers,

    Kev
     
    Kev Dwyer, Sep 19, 2010
    #2
    1. Advertising

  3. Lie Ryan

    Vinay Sajip Guest

    On Sep 18, 5:35 pm, Lie Ryan <> wrote:
    > I was expecting this to work:
    >
    >   importlogging
    >   logger =logging.getLogger(__name__)
    >   logger.warn('this is a warning')
    >
    > instead it produced the error:
    >
    >   No handlers could be found for logger "__main__"
    >
    > However, if instead I do:
    >
    >   importlogging
    >  logging.warn('creating logger')
    >   logger =logging.getLogger(__name__)
    >   logger.warn('this is a warning')
    >
    > then it does work.
    >
    > Is there any reason why getLogger()-created logger shouldn't
    > automatically create a default handler?


    There is a good reason why a getLogger()-created logger doesn't add a
    default handler. Imagine if it did, and the code you were writing was
    a library module that was used in an application being written by
    another developer. Imagine if there were several other libraries which
    also declared loggers (and therefore several default handlers). Then
    the result of running the application would be to get a whole bunch of
    unexpected messages from those libraries, including yours. This would
    annoy the application developer no end, and rightly so.

    For simple uses of logging (where you are writing a utility script,
    for example, when you are the application developer) you can call
    logging.warning() etc. which will (for your convenience) add a handler
    to write to the console for you, if there isn't a handler already.

    If you are doing something more involved, you will need to configure
    logging to do whatever it is you want, and when you run your program
    your log will contain messages from your application as well as third-
    party libraries you use, all playing well together and with no
    unpleasant surprises.

    If you are writing a library, you will typically:

    1. Add a NullHandler to your top-level logger.
    2. If you want to force your users (application developers) to add
    handlers explicitly to their loggers, set your top-level logger's
    propagate flag to False.
    3. If you want to have a specific verbosity on your loggers, which is
    different from the default (WARNING), you need to set that level on
    your top-level logger, or on individual loggers for which you want
    that specific, non-default verbosity.

    I hope that helps,


    Vinay Sajip
     
    Vinay Sajip, Sep 19, 2010
    #3
  4. Lie Ryan

    Vinay Sajip Guest

    On Sep 19, 7:52 pm, Vinay Sajip <> wrote:
    > If you are writing a library, you will typically:
    > 2. If you want to force your users (application developers) to add
    > handlers explicitly to their loggers, set your top-level logger's
    > propagate flag to False.


    Sorry, in the above text, where it says "their loggers" it should say
    "your loggers"

    Regards,

    Vinay Sajip
     
    Vinay Sajip, Sep 19, 2010
    #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. johnny
    Replies:
    1
    Views:
    644
    Dennis Lee Bieber
    Dec 12, 2006
  2. Philip Semanchuk
    Replies:
    0
    Views:
    542
    Philip Semanchuk
    May 23, 2010
  3. genkuro
    Replies:
    8
    Views:
    1,575
    Stephen Hansen
    Jun 15, 2010
  4. Steven W. Orr

    Advise on using logging.getLogger needed.

    Steven W. Orr, Oct 2, 2011, in forum: Python
    Replies:
    1
    Views:
    152
    Vinay Sajip
    Oct 7, 2011
  5. Ram
    Replies:
    1
    Views:
    266
    Dennis Lee Bieber
    Dec 29, 2011
Loading...

Share This Page