如何在Python中记录包名?

时间:2012-04-18 09:05:18

标签: python logging

我正在使用Pythons logging模块。我想记录消息的完整路径,例如
“msg packagename.modulename.functionName lineNumber”,但是如何获取邮件的包名?

日志记录配置为:

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')

6 个答案:

答案 0 :(得分:2)

我建议使用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')

对于位于名为module.py的包内的模块packagelogger.info()调用应向STDERR生成以下消息:

package.module - message

在同一个软件包中的其他模块内部,您可以按照以下方式设置您的记录器,以获得类似的功能:

import logging

logger = logging.getLogger(__name__)

logger.info('another message')

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

package.another - another message

答案 1 :(得分:1)

我看到了问题的两种解决方案。

一,传递每次调用log。[debug,info,error,...]的文件名,由__file__魔术变量获得。这不会为您提供包名称,但它与查找日志消息的位置一样好。缺点是您需要修改应用程序中的每个日志记录调用。

两,创建一个logging.Logger的子类,它覆盖Logger.log实例方法。在新的log方法中,使用inspect.stack()inspect.getframeinfo()方法查找导致代码中log调用的堆栈帧,并提取文件名和行号。然后,您可以修改相应传递的日志消息。最后,通过调用logging告诉logging.setLoggerClass()模块使用您的子类。

答案 2 :(得分:1)

以下是我实现此方法的示例: https://github.com/JensTimmerman/vsc-base/blob/master/lib/vsc/utils/fancylogger.py

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

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

但请查看fancylogger.py以获取完整的实例。

答案 3 :(得分:1)

我不知道如何获得"包裹名称"就像Java默认情况下那样,但要添加文件名(这样可以提供相同的上下文),请在格式字符串中使用%(pathname)s

'format': '[%(levelname)s] %(message)s [%(pathname)s %(funcName)s %(lineno)d]'

请参阅此处的文档:https://docs.python.org/2/library/logging.html#logrecord-attributes

答案 4 :(得分:0)

只需将{'3}}所说明的样式'{'与{module}一起使用

示例:

'formatters': {
    'standard': {
        'format': '{asctime}: [{levelname}] [{name}] [{module}.{funcName} linenr: {lineno}]: {message}',
        'style': '{',
    },
    'report': {
        'format': '{asctime}: [{name}.{module}.{funcName} linenr: {lineno}]: {message}',
        'style': '{',
    },
    'simple': {
        'format': '{levelname} {message}',
        'style': '{',
    },
},

答案 5 :(得分:0)

我在一个名为common的软件包中有一个utils.py文件,它具有以下内容。

utils.py

import logging
log = logging
log.basicConfig(level=log.INFO, format='%(asctime)s:%(filename)s:%(funcName)s'
                                       ':%(levelname)s :%(message)s')

在我需要使用日志的任何其他文件中,我使用以下内容。

from pkg.common.utils import log
log.info("some msg")