Separate logger name for each application instance
My python application consists of main program and several modules. Each modul开发者_高级运维e contains
import logging
log = logging.getLogger('myapp.mymodule')
on global level. Handlers and other stuff initialized in main program, and typically all messages forwarded to syslog.
Now I want to launch multiple instances of application (configuration file with instance name can be specified as command line parameter). The question is: how to pass instance name to each imported module? I want logger name to look like 'myappinstance.mymodule' or 'myapp.instance.module'. And I do not want to mess with configuration file parsing in each module, because this will require hardcoded config path.
Here is a solution I can think of:
In the main program, set the formatter of logger named myapp
import logging
logger = logging.getLogger("myapp")
formatter = logging.Formatter("%(asctime)s - instance_name - %(levelname)s - %(message)s")
ch = logging.SysLogHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
Then all imported module using logger myapp.*
will contain instance_name in the logging message.
Well, describing the problem really helps in solving it :) Just had an idea of using environment variables to pass parameters across all modules:
main.py:
import os
os.environ['instance'] = 'blah'
import a
a.py:
import os
import b
print 'a:', os.environ['instance']
b.py:
import os
print 'b:', os.environ['instance']
$ python main.py
b: blah
a: blah
Any other ideas or critics for this one?
Simply write your own logging wrapper which will give you the correct name (tweak as needed to get the instance name that you want):
def get_logger(obj=None):
if isinstance(obj, str):
return logging.getLogger(obj)
elif obj is not None:
logger_name ="%s.%s" % (obj.__class__.__module__, obj.__class__.__name__)
return logging.getLogger(logger_name)
else:
return logging.getLogger()
class Foo(object):
def __init__(self):
self._log = get_logger(self)
Or, if the process id is good enough for you, simply use that in your formatter:
http://www.python.org/doc/2.5.4/lib/node421.html
formatter = logging.Formatter("%(process)d - %(asctime)s - %(levelname)s - %(message)s")
Obviously, that will uniquely identify each process, but won't give you anything related to the instance.
精彩评论