Reputation: 447
My python application consists of main program and several modules. Each module 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.
Upvotes: 1
Views: 1182
Reputation: 7418
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.
Upvotes: 0
Reputation: 447
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?
Upvotes: 0
Reputation: 10106
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.
Upvotes: 2