如何让Loguru在子线程中传递Correlation ID进行日志记录?
Loguru子线程继承Correlation ID的解决方法
Loguru的logger.contextualize()只在父线程生效,子线程无法自动带上Correlation ID,本质是因为Loguru的上下文存储在线程局部存储(TLS)中,子线程不会自动复制父线程的TLS数据。下面给你几种可行的解决思路:
方法一:手动传递Correlation ID到子线程,重新绑定上下文
修改线程类,让它接收Correlation ID,在子线程执行逻辑里重新调用contextualize()注入ID:
import sys import threading from loguru import logger logger.remove(0) logger.add(sys.stderr, format="{time:MMMM D, YYYY HH:mm:ss} | {level} | {message} | {extra}") class Client: def get_data(self): logger.info("get_data") class ProcessThread(threading.Thread): def __init__(self, client, correlation_id): # 新增接收ID参数 threading.Thread.__init__(self) self.client = client self.correlation_id = correlation_id def run(self): # 子线程内重新绑定上下文 with logger.contextualize(correlation_id=self.correlation_id): logger.info("inside child thread") self.client.get_data() def test(id): with logger.contextualize(correlation_id=id): process_thread = ProcessThread(Client(), id) # 传递ID给线程 logger.info("inside parent thread") process_thread.start() test('101')
方法二:使用绑定了Correlation ID的Logger实例
在父线程中用logger.bind()创建带ID的Logger实例,把这个实例传递给子线程或业务类,直接用它打日志:
import sys import threading from loguru import logger logger.remove(0) logger.add(sys.stderr, format="{time:MMMM D, YYYY HH:mm:ss} | {level} | {message} | {extra}") class Client: def __init__(self, bound_logger): self.logger = bound_logger # 接收绑定后的logger def get_data(self): self.logger.info("get_data") class ProcessThread(threading.Thread): def __init__(self, client): threading.Thread.__init__(self) self.client = client def run(self): self.client.logger.info("inside child thread") # 使用绑定好的logger self.client.get_data() def test(id): bound_logger = logger.bind(correlation_id=id) # 创建带ID的logger实例 process_thread = ProcessThread(Client(bound_logger)) bound_logger.info("inside parent thread") process_thread.start() test('101')
方法三:自定义线程类自动继承父线程上下文
如果项目中有大量线程需要处理,可以自定义线程类,启动时自动复制父线程的Loguru上下文:
import sys import threading from loguru import logger logger.remove(0) logger.add(sys.stderr, format="{time:MMMM D, YYYY HH:mm:ss} | {level} | {message} | {extra}") # 自定义继承上下文的线程类 class ContextInheritingThread(threading.Thread): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 获取父线程的Loguru上下文(注:此为内部API,未来版本可能变动) self.log_context = logger._core.context.get() def run(self): # 将父线程上下文注入子线程 with logger.contextualize(**self.log_context): super().run() class Client: def get_data(self): logger.info("get_data") class ProcessThread(ContextInheritingThread): def __init__(self, client): super().__init__() self.client = client def run(self): logger.info("inside child thread") self.client.get_data() def test(id): with logger.contextualize(correlation_id=id): process_thread = ProcessThread(Client()) logger.info("inside parent thread") process_thread.start() test('101')
内容的提问来源于stack exchange,提问作者seamonkeys
相关产品推荐
相关产品推荐

