Skip to main content
 首页 » 编程设计

Python之使用 structlog 从多个模块记录

2025年01月19日12powertoolsteam

我正在尝试使用 Structlog 来记录到一个文件,然后使用 filebeat 将日志发送到我的日志记录服务。

我已经使一切正常,但我希望能够在多个模块中使用相同的记录器,就像使用 Python 的默认记录器一样(参见 https://docs.python.org/2/howto/logging.html “从多个模块记录”部分)。

其中一个原因是我想将一个 sessionID 绑定(bind)到我的日志输出,该日志输出应该跨从该 session 调用的所有模块进行记录。

可能需要一些关于如何使用 structlogger 的基础知识,但尚未在他们的文档或其他帖子中找到答案。

请多多指教....

一个例子:

主要.py

#!/usr/bin/env python3 
# -*- coding: UTF-8 -*- 
 
import uuid 
 
from mylogger import myLogger 
import otherModule 
 
myLogger = myLogger() 
 
myLogger.log.warning('working', error='test') 
 
myLogger.log = myLogger.log.bind(sessionID=str(uuid.uuid4())) 
 
myLogger.log.warning('Event where sessionID is bound to logger', error='test') 
 
otherModule = otherModule.otherModule() 

我的记录器.py

#!/usr/bin/python3 
# -*- coding: UTF-8 -*- 
 
import datetime, logging 
from structlog import wrap_logger, get_logger 
from structlog.processors import JSONRenderer 
from structlog.stdlib import filter_by_level, add_log_level 
 
 
class myLogger(): 
    def __init__(self, loggername="root", logLevel='INFO', logFile='test2.log'): 
 
        self.log = wrap_logger( 
            logging.getLogger('root'), 
            processors=[ 
                filter_by_level, 
                add_log_level, 
                self.add_timestamp, 
                JSONRenderer(indent=1, sort_keys=True) 
            ] 
        ) 
 
        logging.basicConfig(format='%(message)s', level=logLevel, filename=logFile) 
 
    def my_get_logger(self, loggername="AnyLogger"): 
        log = get_logger(loggername) 
 
        return log 
 
    def add_timestamp(self,  _, __, event_dict): 
        event_dict['timestamp'] = datetime.datetime.utcnow().isoformat() 
        return event_dict 

其他模块.py

import structlog 
from mylogger import myLogger 
 
class otherModule(): 
    def __init__(self): 
        logger = structlog.get_logger('root') 
        ## This logger does not have the processors nor the bound sessionID 
 
        logger.warning('In other module') 
        ## This logmessage is printed to console 
 
        logger2 = myLogger(); 
        ## This logger has all the processors  but not the bund sessionID 
 
        logger2.log.warning('In other module') 
        ## This log is written to my logfile, but without the sessionID 

请您参考如下方法:

您需要使用包装字典作为上下文类,如 structlog documentation 中所述

所以你最终会得到这样的结果:

structlog.configure( 
    processors=[ 
        structlog.stdlib.filter_by_level, 
        # other processors 
    ], 
    context_class=structlog.threadlocal.wrap_dict(dict), 
)