Debug Python logging issues
P introspection with logging_tree
Have you ever wondered where all your logging information is coming from (or even where it's going to, or possibly why it's all duplicated)? If so, then logging_tree is your saviour.
I came across the logging_tree library recently as I was following a specific issue in the urllib3
library, regarding the proliferation of INFO statements.
I installed it (pip install logging-tree
) and ran it on our local dev instance, expecting to see the logging configuration that we had set in settings.py
, but imagine my surprise when all this came out (hipchat_logger
is used to push updates to HipChat; "yunojuno" is the root logger for our application - I have removed all the detail below that; "errordite" is an error management service, similar to Sentry - more about that in a later blog post):
>>> import logging_tree
>>> logging_tree.printout()
<--""
Level DEBUG
Handler Stream <open file '<stderr>', mode 'w' at 0xb73260d0>
|
o<--"SocialAuth"
| Level DEBUG
|
o<--"django"
| Handler <logging.NullHandler object at 0x8e0edec>
| |
| o<--[django.db]
| | |
| | o "django.db.backends"
| | Propagate OFF
| | Handler <logging.NullHandler object at 0x92c676c>
| |
| o<--"django.request"
| Level DEBUG
| Handler Stream <open file '<stderr>', mode 'w' at 0xb73260d0>
| Handler <django_errordite.handlers.DjangoErrorditeHandler object at 0x92c65cc>
|
o "hipchat_logger"
| Level INFO
| Propagate OFF
| Handler <yunojuno.apps.logger.handlers.HipChatHandler object at 0x92c666c>
|
o<--[requests]
| |
| o<--"requests.auth"
| |
| o<--[requests.packages]
| |
| o<--"requests.packages.urllib3"
| Handler <logging.NullHandler object at 0x8e65d0c>
| |
| o<--"requests.packages.urllib3.connectionpool"
| |
| o<--"requests.packages.urllib3.poolmanager"
| |
| o<--"requests.packages.urllib3.response"
|
o<--[rq]
| |
| o<--"rq.worker"
|
o<--"south"
| Handler <south.logger.NullHandler object at 0x94ce08c>
|
o<--[webassets]
| |
| o<--"webassets.debug"
| Level ERROR
| Handler Stream <open file '<stderr>', mode 'w' at 0xb73260d0>
|
o "yunojuno"
Level DEBUG
Propagate OFF
Handler Stream <open file '<stderr>', mode 'w' at 0xb73260d0>
Handler <django_errordite.handlers.DjangoErrorditeHandler object at 0x92c65cc>
|
...
>>>
If you're interested finding out more about how logging works, I strongly recommend reading the article http://rhodesmill.org/brandon/2012/logging_tree/, and in particular the details around propagation of log messages.
Making Freelance Work