EDIT: here is an access to the file name related to the whole package:
filepath = __file__ if __name__ == '__main__' else __name__
For the following structure, it gives:
mypack
├── __main__.py # -> mypack.__main__
└── sub
├── __init__.py
└── sub.py # -> mypack.sub.sub
Here is a snippet:
def logger(name=None, root_name=PACKAGE_NAME):
if name:
return logging.getLogger(root_name + '.' + name)
else:
return logging.getLogger(root_name)
I usually define this function in a commons.py or utils.py, imported by all the modules of my package.
Taking advantage of the sublogger system, this allows a package to use the main logging of the package:
import utils
logger = utils.logger()
logger.info('module xxx started')
Or a sublogger dedicated to a particular concept:
import utils
logger = utils.logger('vm')
logger.info('module vm.xxx started')
The file path and the logging config are now decoupled and explicitely binded.
Which can be automatize for each module:
import utils
logger = utils.logger(__file__)
logger.info('module ' + __file__ + ' started')
Because of the sublogger system, the logger 'pk.vm' will (by default) inherit for 'pk' configuration, that is to say using the same handlers, thus writing in the same logging file.
However, it can be useful to define some particular behavior or handlers for any sublogger:
logging.config.dictConfig({
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s',
},
'simple': {
'format': '%(levelname)s %(message)s',
},
},
'handlers': {
'console':{
'level':LOG_LEVEL,
'class':'logging.StreamHandler',
'formatter': 'simple',
},
'logfile': {
'level': LOG_LEVEL,
'class': 'logging.handlers.RotatingFileHandler',
'filename': DIR_LOGS + LOGGER_NAME + '.log',
'mode': 'w',
'maxBytes': LOGFILE_MAX_SIZE,
'formatter': 'verbose',
},
'logfile' + SUBLOGGER_SEPARATOR + SUBLOGGER_VM: {
'level': LOG_LEVEL,
'class': 'logging.handlers.RotatingFileHandler',
'filename': DIR_LOGS + LOGGER_NAME + '.' + SUBLOGGER_VM + '.log',
'mode': 'w',
'maxBytes': LOGFILE_MAX_SIZE,
'formatter': 'verbose',
},
},
'loggers': {
PACKAGE_NAME: {
'handlers':['console', 'logfile'],
'propagate': True,
'level':LOG_LEVEL,
},
PACKAGE_NAME + SUBLOGGER_SEPARATOR + SUBLOGGER_VM: {
'handlers':['logfile' + SUBLOGGER_SEPARATOR + SUBLOGGER_VM],
'level':LOG_LEVEL,
},
}
})