python logging - 根据日志消息将日志重定向到不同的文件

时间:2013-07-16 13:27:52

标签: python logging python-2.7

应用程序使用python日志记录。它有不同的模块,每个模块都有一个记录器,根层位于顶层。有三个模块与第三方API通信。跟踪来自第三方API的请求/响应日志非常耗时。因此,基于日志消息,需要将日志重定向到不同的日志文件。这将简化API请求/响应日志跟踪。基于日志级别的日志重定向很常见,但我无法提出有效的设计,根据日志消息内容将API特定日志重定向到不同的日志文件。下面是一个可以用来达到要求的方法。

class APILevelLogHandler(logging.Handler):
    def __init__(self):
        logging.Handler.__init__(self)
    def emit(self, record):
        import re, os, socket
        logFileList = []
        matchObj = re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', str(record.msg))
    logPath = "/tmp/"
    try:
        if matchObj and socket.inet_aton(matchObj.group()):
            if not matchObj.group() in logFileList:
                logFileList.append(matchObj.group())
                if not os.path.isdir(logPath):
                    try:
                        os.makedirs(logPath)
                    except OSError:
                        print "Exception", ex, callstack.ExcepCallStack()
            if "dataReceived" in record.msg or "send" in record.msg:
                with open(str(os.path.join(logPath, matchObj.group()+".log")), 'a') as f:
                    f.write(record.msg + '\n')
    except Exception, ex:
        print "Exception", ex, callstack.ExcepCallStack()

在应用程序的python日志记录设置期间,处理程序将作为

添加到根记录器中
logger = logging.getLogger('')
logger.addHandler(APILevelLogHandler())

Output.log
API test1 1.1.1.1 data send
API test2 2.2.2.2 data send
API test1 1.1.1.1 data received
API test1 1.1.1.1 data send
API test2 2.2.2.2 data received
API test1 1.1.1.1 data received

Expected output
1.1.1.1.log
API test1 1.1.1.1 data send
API test1 1.1.1.1 data received
API test1 1.1.1.1 data send
API test1 1.1.1.1 data received

2.2.2.2.log
API test2 2.2.2.2 data send
API test2 2.2.2.2 data received

请建议我更好的设计来达到上述要求。

谢谢, Ranjan

另一个可能的解决方案:

以上接近将为现有进程增加额外开销,如果我想使用处理程序RotatingFileHandler提供的相同功能,那么我必须重写功能。因此,如果从一个模块完成日志记录,我还有一个建议可以正常工作,但在我的情况下,日志记录是从多个模块完成的。所以我需要从常见的日志记录设置重定向日志。如果有多个模块的其他可能方式,请告诉我。

    logFileName = "logFileName_extracted_from_message"
    self.apilevelLogger = logging.getLogger(logFileName)
    if any(isinstance(item, logging.handlers.RotatingFileHandler) for item in logging.getLogger('').handlers):
        handler = logging.handlers.RotatingFileHandler(logFileName, maxBytes=10e6, backupCount=3)
        self.apilevelLogger.addHandler(handler)
        self.apilevelLogger.setLevel(logging.INFO)

    self.apilevelLogger.info("API test1 1.1.1.1 send data")

在第二次接近时,没有。创建的logger等于no。创建的日志文件。我希望有进一步改进的余地,而不是将相同的代码添加到所有模块中。请帮助提高效率和设计。

谢谢, 兰詹

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情(简化的脚本结构):

def writelog(text, file):
    # simplified version
    filehandle = open(file, 'a') # 'a' for 'append'
    filehandle.write(text)
    filehandle.close()

# (...) will be the group(1) of the match and the filename
matchObj = re.search('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', str(record.msg))
filename = matchObj.group(1)

# perform further tests to see if you want to write the message to the log
if ... :
    writelog(record.msg, filename)

这有帮助吗?