编辑:这里是对与整个包相关的文件名的访问:
filepath = __file__ if __name__ == '__main__' else __name__
对于以下结构,它给出:
mypack
├── __main__.py # -> mypack.__main__
└── sub
├── __init__.py
└── sub.py # -> mypack.sub.sub
这是一个sn-p:
def logger(name=None, root_name=PACKAGE_NAME):
if name:
return logging.getLogger(root_name + '.' + name)
else:
return logging.getLogger(root_name)
我通常在commons.py 或utils.py 中定义这个函数,由我的包的所有模块导入。
利用 sublogger 系统,这允许包使用包的主日志记录:
import utils
logger = utils.logger()
logger.info('module xxx started')
或专门用于特定概念的子记录器:
import utils
logger = utils.logger('vm')
logger.info('module vm.xxx started')
文件路径和日志配置现在已解耦并显式绑定。
每个模块都可以自动化:
import utils
logger = utils.logger(__file__)
logger.info('module ' + __file__ + ' started')
由于 sublogger 系统,logger 'pk.vm' 将(默认情况下)继承 'pk' 配置,即使用相同的处理程序,从而写入相同的日志文件。
但是,为任何 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,
},
}
})