How many times have you used a print instruction instead of logger.debug or logger.info? Well I used to do it frequently. The thing is, setting up a logger in an application that has many of its own, is problematic. There is a tool however that may help you identify the right place for your logger (or identify the logger you want to use).
~ $ pip install logging_tree
So what does this package do? In practice this is a logging introspection tool that recreates a tree structure of your current loggers (along with handlers and filters). This is very useful since you may immediately identify which logger you should use, or at least confirm that adding a new logger will be mandatory.
For example: if You type the following in a python terminal:
>>> import logging_tree
>>> logging_tree.printout()
<--""
Level WARNING
Well this is quite obvious, no modules are loaded, thus no custom logger was registered. On the other hand let's look at a logging tree of a young django app:
In [1]: import logging_tree
In [2]: logging_tree.printout()
<--""
Level WARNING
|
o<--"core"
| Level INFO
| Handler File '/tmp/wt.log'
|
o<--"django"
| Handler Stream <open file '<stderr>', mode 'w' at 0x7f21e9890270>
| Filter <django.utils.log.RequireDebugTrue object at 0x1676350>
| |
| o<--[django.db]
| | |
| | o<--"django.db.backends"
| |
| o<--"django.request"
| Level ERROR
| Handler <django.utils.log.AdminEmailHandler object at 0x1676790>
|
o<--"nose"
| |
| o<--"nose.case"
| |
| o<--"nose.config"
| |
| o<--"nose.core"
| |
| o<--"nose.failure"
| |
| o<--"nose.importer"
| |
| o<--"nose.inspector"
| |
| o<--"nose.loader"
| |
| o<--"nose.plugins"
| | |
| | o<--"nose.plugins.attrib"
| | |
| | o<--"nose.plugins.capture"
| | |
| | o<--"nose.plugins.collect"
| | |
| | o<--"nose.plugins.cover"
| | |
| | o<--"nose.plugins.doctests"
| | |
| | o<--"nose.plugins.isolation"
| | |
| | o<--"nose.plugins.logcapture"
| | |
| | o<--"nose.plugins.manager"
| | |
| | o<--"nose.plugins.multiprocess"
| | |
| | o<--"nose.plugins.testid"
| |
| o<--"nose.proxy"
| |
| o<--"nose.result"
| |
| o<--"nose.selector"
| |
| o<--"nose.suite"
|
o<--[py]
| |
| o<--"py.warnings"
| Handler Stream <open file '<stderr>', mode 'w' at 0x7f21e9890270>
| Filter <django.utils.log.RequireDebugTrue object at 0x1676350>
|
o<--"south"
Handler <south.logger.NullHandler object at 0x20c9350>
It's much easier to read this tree output than getting familiar with your applications logging configuration along with the documentation of other packages that are using the logging module.
Hope this saves You a lot of time.
Cheers!
KR
Thursday, February 21, 2013
Thursday, February 14, 2013
A non-production function decorator
As most developers know, not every piece of code is meant to be run on a production server. Instead of using a lot of "ifs" here and there I suggest implementing a framework specific "non_production" decorator. A simple django-specific implementation could look like this:
Now all you have to do is to apply it to your dev/test only functions:
Cheers!
KR
def non_production(func): def is_production(): #django specific from django.conf import settings return getattr(settings, "PRODUCTION", False) def wrapped(*args, **kwargs): if is_production(): raise Exception("%s is not meant to be run on a production server" % \ func.__name__) else: return func(*args, **kwargs) return wrapped
Now all you have to do is to apply it to your dev/test only functions:
@non_production def test_something(a, b): pass
Cheers!
KR
Subscribe to:
Posts (Atom)