Python 日志格式化程序记录当前正在执行的函数
在python日志中,我想记录当前正在执行/运行的函数。比如,Python 日志格式化程序记录当前正在执行的函数,python,logging,Python,Logging,在python日志中,我想记录当前正在执行/运行的函数。比如, class Foo: def bar(self): logging.info("I'm alive") # Writes to log: '[INFO]: Foo::bar(), I'm alive' 是否可以将我的记录器配置为执行此操作?也就是说,创建一个格式化程序来发现这一点 logging.config.dictConfig({ 'version': 1, 'disable_existi
class Foo:
def bar(self):
logging.info("I'm alive") # Writes to log: '[INFO]: Foo::bar(), I'm alive'
是否可以将我的记录器配置为执行此操作?也就是说,创建一个格式化程序来发现这一点
logging.config.dictConfig({
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '[%(levelname)s] %(FUNCTION_NAME)s: %(message)s'
},
},
...
})
您可以通过将信息上下文添加到记录器的
记录中来实现这一点。为此,您需要定义自己的ContextFilter
类,并将其实例添加到记录器中。注意,为了获得类名,我们依赖于调用类的实例的约定,而不是将其用作其他函数的参数(基于这个问题)。还请注意,此变通方法无法确定internalFunc
的类,因为它没有self
参数。请参阅下面的代码
import inspect
import logging
def get_class_from_frame(fr):
args, _, _, value_dict = inspect.getargvalues(fr)
if len(args) and args[0] == 'self':
instance = value_dict.get('self', None)
if instance:
return getattr(instance, '__class__', None)
return 'NOCLASS'
class ContextFilter(logging.Filter):
"""
This is a filter which injects contextual information into the log.
"""
def filter(self, record):
#we are adding the function field to the logger record
mystack = inspect.stack()[5]
record.function = '%s::%s'%(get_class_from_frame(mystack[0]), mystack[3])
return True
def buildLogger():
logger = logging.getLogger("root")
#now we use the function field in the format
myFormat = '[%(levelname)s] %(function)s: "%(message)s"'
formatter = logging.Formatter(myFormat)
# add an instance of ContextFilter to the logger
myFilter = ContextFilter()
logger.addFilter(myFilter)
ch = logging.StreamHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.propagate = False
return logger
# Some testing
def myStandaloneFunction():
logger.warning('this is logged from myStandaloneFunction')
class A():
def afunc(self):
def internalFunc():
logger.warning('this is logged from inside internalFunc call')
logger.warning('this is logged from inside a afunc call')
internalFunc()
logger = buildLogger()
logger.warning('this is logged from module level')
myStandaloneFunction()
a = A()
a.afunc()
您可以通过将信息上下文添加到记录器的记录中来实现这一点。为此,您需要定义自己的ContextFilter
类,并将其实例添加到记录器中。注意,为了获得类名,我们依赖于调用类的实例的约定,而不是将其用作其他函数的参数(基于这个问题)。还请注意,此变通方法无法确定internalFunc
的类,因为它没有self
参数。请参阅下面的代码
import inspect
import logging
def get_class_from_frame(fr):
args, _, _, value_dict = inspect.getargvalues(fr)
if len(args) and args[0] == 'self':
instance = value_dict.get('self', None)
if instance:
return getattr(instance, '__class__', None)
return 'NOCLASS'
class ContextFilter(logging.Filter):
"""
This is a filter which injects contextual information into the log.
"""
def filter(self, record):
#we are adding the function field to the logger record
mystack = inspect.stack()[5]
record.function = '%s::%s'%(get_class_from_frame(mystack[0]), mystack[3])
return True
def buildLogger():
logger = logging.getLogger("root")
#now we use the function field in the format
myFormat = '[%(levelname)s] %(function)s: "%(message)s"'
formatter = logging.Formatter(myFormat)
# add an instance of ContextFilter to the logger
myFilter = ContextFilter()
logger.addFilter(myFilter)
ch = logging.StreamHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.propagate = False
return logger
# Some testing
def myStandaloneFunction():
logger.warning('this is logged from myStandaloneFunction')
class A():
def afunc(self):
def internalFunc():
logger.warning('this is logged from inside internalFunc call')
logger.warning('this is logged from inside a afunc call')
internalFunc()
logger = buildLogger()
logger.warning('this is logged from module level')
myStandaloneFunction()
a = A()
a.afunc()