如何在Python中记录包名称?

2024-04-23 20:52:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Pythonslogging模块。我想记录消息的完整路径,比如
“msg package name.modulename.functionName行号”,但如何获取消息的包名称?

日志记录配置为:

LOGGING = {    
'formatters': {
    'simple': {
    'format': '[%(levelname)s] %(message)s [%(module)s %(funcName)s %(lineno)d]'
    },  
},
'handlers': {
'console': {
        'level':'INFO',
        'class':'logging.StreamHandler',
        'formatter':'simple',
    }
},
'loggers': {
    'develop': {
        'handlers': ['console'],
        'level': 'DEBUG',
        'propagate': True,
    },
}

}

我有一个这样的记录器:

logger = logging.getLogger('develop')

Tags: 模块name路径消息packagelogginghandlers记录
3条回答

我建议使用logging.getLogger(__name__.split('.')[0])生成包的记录器,使用包含name参数的格式化程序配置它,然后使用logging.getLogger(__name__)生成模块的记录器。

例如:

import logging

formatter = logging.Formatter('%(name)s - %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
handler.setLevel(logging.INFO)

package_logger = logging.getLogger(__name__.split('.')[0])
package_logger.setLevel(logging.INFO)
package_logger.addHandler(handler)

logger = logging.getLogger(__name__)
logger.info('message')

对于位于名为package的包内的模块module.pylogger.info()调用应生成以下消息给STDERR

package.module - message

在同一个包中的其他模块中,您可以简单地按照以下步骤设置记录器,以获得在其中工作的类似功能:

import logging

logger = logging.getLogger(__name__)

logger.info('another message')

对于从同一包的module.py模块调用的包another.py内的模块package,这将生成STDERR的以下文本:

package.another - another message

我看到了两个解决问题的办法。

首先,在每次调用log.[debug,info,error,…]时传入文件名,这是由__file__魔术变量获得的。这并没有提供包的名称,但它与查找日志消息的来源一样好。缺点是需要修改应用程序中的每个日志记录调用。

第二,生成logging.Logger的子类,该子类重写Logger.log实例方法。在新的log方法中,使用inspect.stack()inspect.getframeinfo()方法查找导致在代码中调用log的堆栈帧,并提取文件名和行号。然后可以相应地修改传入的日志消息。最后,告诉logging模块通过调用logging.setLoggerClass()来使用子类。

下面是我如何实现这一点的示例: https://github.com/JensTimmerman/vsc-base/blob/master/lib/vsc/utils/fancylogger.py

正如Simon所建议的,我扩展到python记录器来添加自定义字段。 但您也可以定义一个新的getLogger函数来执行以下操作:

rootmodulename = inspect.stack()[-1][1].split('/')[-1].split('.')[0]
callingfunctionname = inspect.stack()[2][3]
logger = logging.getLogger("%s.%s" % (rootmodulename, callingfunctionname))

但看看fancylogger.py就可以得到一个完整的示例。

相关问题 更多 >