Showing the right funcName when wrapping logger functionality in a custom class

前端 未结 8 1676
你的背包
你的背包 2021-02-01 16:31

This is the formatting string that I am using for logging:

\'%(asctime)s - %(levelname)-10s - %(funcName)s - %(message)s\'

But to show the logg

8条回答
  •  不思量自难忘°
    2021-02-01 16:56

    As suggested in the first answer, subclassing the Logger class and using logging.setLoggerClass should do the trick. You will need a modified findCaller function, that is handling your wrapped function call(s).

    Put the following into a module, since the findCaller class method is searching the first call from a file, which is not the current source filename.

    import inspect
    import logging
    import os
    
    if hasattr(sys, 'frozen'): #support for py2exe
        _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
    elif __file__[-4:].lower() in ['.pyc', '.pyo']:
        _srcfile = __file__[:-4] + '.py'
    else:
        _srcfile = __file__
    _srcfile = os.path.normcase(_srcfile)
    
    class WrappedLogger(logging.Logger):
        def __init__(self,name):
            logging.Logger.__init__(self, name)
    
        def findCaller(self):
            """
            Find the stack frame of the caller so that we can note the source
            file name, line number and function name.
            """
            # get all outer frames starting from the current frame
            outer = inspect.getouterframes(inspect.currentframe())
            # reverse the order, to search from out inward
            outer.reverse()
            rv = "(unknown file)", 0, "(unknown function)"    
    
            pos = 0
            # go through all frames
            for i in range(0,len(outer)):
                # stop if we find the current source filename
                if outer[i][1] == _srcfile:
                    # the caller is the previous one
                    pos=i-1
                    break
    
            # get the frame (stored in first tuple entry)
            f = outer[pos][0]
    
            co = f.f_code
            rv = (co.co_filename, f.f_lineno, co.co_name)
    
            return rv
    # Usage:
    logging.setLoggerClass(WrappedLogger)
    log = logging.getLogger("something")
    

提交回复
热议问题