我正在使用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')
答案 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
的包内的模块package
,logger.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")