Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 日志格式化程序记录当前正在执行的函数_Python_Logging - Fatal编程技术网

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

在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_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()