1

该应用程序使用 python 日志记录。它有不同的模块,每个模块都有一个记录器,根位于顶层。有三个模块与第 3 方 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

请建议我一个更好的设计来实现上述要求。

谢谢, 兰詹

另一种可能的解决方案:

上述方法会给现有进程增加额外的开销,如果我想使用处理程序 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")

在第二次走近时,没有。创建的记录器的数量等于否。创建的日志文件。与其将相同的代码添加到所有模块中,我希望还有进一步改进的空间。请帮助提高效率和设计。

谢谢, 兰詹

4

1 回答 1

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)

这有帮助吗?

于 2013-07-16T14:06:02.127 回答