You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 11:50:23