在Python中向日志记录添加Per-request上下文



背景

对于RESTapi服务,我希望以一种不必重写整个应用程序的日志语句的方式提供更多的日志上下文。我在flask中使用python日志库,在gunicorn中使用eventlet runner类型。

用例

想象一下,在未来,通过该系统的所有请求都有一个唯一的(足够的(事务ID,作为来自某个上游源的头(可能是反向代理(。我想在每个日志语句中记录这个事务id,以便即使在峰值负载期间也可以轻松地通过我的系统跟踪给定的请求。

方法

编写一个自定义的日志上下文过滤器类,从烧瓶中提取所需的信息。我的理解是,我应该能够从线程本地上下文变量中提取这些信息(即请求对象(。在初始化全局根记录器后,我只需设置这个自定义上下文过滤器,在调试领域一切都应该很好!

我从以下食谱文档中发现了这种方法。。。https://docs.python.org/2/howto/logging-cookbook.html#using-传递上下文信息的过滤器

问题

  • 您预计这种方法会出现伸缩性问题吗
  • 有没有想过将此事务id向下游传播到我的网络中的其他请求
  • eventlet工作程序类型的使用是否会妨碍其按预期运行(即,由于并发问题而导致的混合上下文(
  • 仅仅因为你可以,并不意味着你应该。我为什么不应该这样做还有其他原因吗

听起来您可能正在考虑实现一个类似X-Trace的系统。免责声明:我工作的商业产品是这样运作的。

关于传播,随着应用程序复杂性的增长,它可能会成为一个问题。由于您在后端需要更多现成的解决方案或多语言组件,因此需要支持上下文日志记录,或者由于缺乏可见性而造成负担。如果您需要通过HTTP-RPC之外的东西(如JBoss或Thrift(传递上下文,或者某种实现复杂性的消息队列,那么其他消息传递机制也是如此。

对于异步请求,您肯定需要确保唯一的id从阻塞代码路径正确地传递到事件代码路径,或者冒着混合/重新使用id的风险。在分析呼叫传播时,这可能是微妙的危险信号的来源。

最新更新