No handlers could be found for logger
Asked Answered
C

6

72

I am newbie to python. I was trying logging in python and I came across No handlers could be found for logger error while trying to print some warning through logger instance. Below is the code I tried

import logging
logger=logging.getLogger('logger')
logger.warning('The system may break down')

And I get this error No handlers could be found for logger "logger"

What's confusing me is when I first try to print warning using logging and then through logger , it works fine, like

>>> import logging
>>> logging.warning('This is a WARNING!!!!')
WARNING:root:This is a WARNING!!!!
>>> 
>>> logger.warning('WARNING!!!!')
WARNING:logger:WARNING!!!!

Can someone throw some light on what's happening in second scenario?

Chari answered 25/5, 2017 at 19:20 Comment(1)
FYI similar question with more upvotes #346491Inapposite
C
36

For logging some message through logger, in Python at least one handler should be added to the logger object. By default the debug, warn and other functions in logging module will call basicConfig which in turn will add a StreamHandler to the root logger.

It's always recommended to add your required Handler to your logger object you are writing for your module.

You could refer to official Python docs, which has an awesome tutorial or you can better check out the source code of logging module yourself.

Simply you can check the source in Python shell itself by,

import logging
import inspect
print(inspect.getsource(logging))

Finally, calling the basicConfig explicitly will resolve the issue.

import logging
logging.basicConfig()
logger = logging.getLogger('logger')
logger.warning('The system may break down')
Chronic answered 25/5, 2017 at 19:45 Comment(0)
N
79

Call logging.basicConfig():

>>> import logging
>>> logging.basicConfig()
>>> logger = logging.getLogger('logger')
>>> logger.warning('The system may break down')
WARNING:logger:The system may break down
Nitty answered 25/5, 2017 at 19:26 Comment(3)
Thanks for sharing that! But I was just wondering why it worked in second scenario...Chari
Because logging.warning() calls logging.basicConfig() if logging is unconfigured.Nitty
Just along with this if you want to add info logs as well you might need to set level to info logger.setLevel(logging.INFO).Papacy
C
36

For logging some message through logger, in Python at least one handler should be added to the logger object. By default the debug, warn and other functions in logging module will call basicConfig which in turn will add a StreamHandler to the root logger.

It's always recommended to add your required Handler to your logger object you are writing for your module.

You could refer to official Python docs, which has an awesome tutorial or you can better check out the source code of logging module yourself.

Simply you can check the source in Python shell itself by,

import logging
import inspect
print(inspect.getsource(logging))

Finally, calling the basicConfig explicitly will resolve the issue.

import logging
logging.basicConfig()
logger = logging.getLogger('logger')
logger.warning('The system may break down')
Chronic answered 25/5, 2017 at 19:45 Comment(0)
D
18

Additional to phd's answer, calling logging.basicConfig() is a convenient function which will get you a default StreamHandler and a Formatter. That is enough if you want to quickly have a logging functionality. You can customize it's behaviour by passing basicConfig some arguments:

Add Useful parameters: output timestamp alongside the message

logger = logging.basicConfig(level=logging.DEBUG, 
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

This should be fine for most of the one off needs. If you need more control about your config, you can add more sophisticated behaviours by defining the logger's attributes your self.

Sophisticated Example: without using the basicConfig function

import logging
logger = logging.getLogger("mylogger")
streamHandler = logging.StreamHandler()
streamHandler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)

logger.addHandler(streamHandler)

logger.info("Files copied")
logger.warning("disk quota exceeded")
>> 2017-12-06 11:11:12, 090 - mylogger - INFO Files copied
>> 2017-12-06 11:11:12, 091 - mylogger - WARNING disk quota exceeded

The next step in a bigger environment, would be deriving a new logger from the previously created one, to first keep the formatting and as well to maintain a "log hierarchy"

logger2 = logging.getLogger("mylogger.new")
logger2.info("New Logger info")
>> 2017-12-06 11:11:12, 091 - mylogger.new - New logger info

A good reference is the logging cookbook: https://docs.python.org/2/howto/logging-cookbook.html

Dancy answered 6/12, 2017 at 19:24 Comment(1)
There is a typo in the 'formatter' line - missing '('. Took me ages to understand why I am getting a cryptic error trying to run that exampleMasticate
E
1

See What happens if no configuration is provided. This error shouldn't happen in Python 3.2 and later.

Extremely answered 19/4, 2022 at 8:17 Comment(0)
A
0

If you get this error when using sentry (No handlers could be found for logger "sentry.errors"), it could be due to sentry bug for SNI support.

check https://github.com/getsentry/raven-python/issues/523 for more details. a quick workaround is to replace DSN scheme by threaded+requests+https:

RAVEN_CONFIG = {
    'dsn': 'threaded+requests+https://[email protected]/1',
}
Adkison answered 30/11, 2018 at 17:43 Comment(0)
L
0

For sake of completeness:

In order to make this work on a module level which might be used elsewhere or standalone you could do

logger = logging.getLogger(__name__)

# create own logging handler if nobody changed the root logger.
if not logging.root.handlers and not logger.handlers:
    handler = logging.StreamHandler()
    handler.formatter = logging.Formatter('%(asctime)s %(funcName)s %(levelname)s: %(message)s')
    logger.addHandler(handler)

This allows running the module standalone and avoids conflicts if it is used in a context which already configures the root logger.

Note that the error message described in the post only appears in Python 2. Python 3 prints the message to stdout if no handlers are defined in the hierarchy.

Lugansk answered 6/10, 2021 at 6:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.