环境变量作为上下文传播载体

状态Alpha

概述

环境变量提供了一种机制,可以在不适用网络协议时,在进程边界之间传播上下文和 baggage 信息。本规范扩展了 API Propagators,定义了如何将 TextMapPropagator 与环境变量一起使用。

使用环境变量进行上下文传播很有用的常见系统包括:

  • 批处理系统
  • CI/CD 环境
  • 命令行工具

Propagator Mechanisms

通过环境变量传播上下文涉及读取和写入环境变量。应使用 TextMapPropagator 及其正常的 GetSetExtractInject 功能,如 API Propagators 规范中所述。

环境变量名称

建议使用 W3C Trace ContextW3C Baggage 规范映射到环境变量名称,以实现一致的上下文传播。

当使用 W3C Trace Context 和 Baggage propagators 与环境变量一起使用时,应使用以下翻译的标准环境变量名称:

上下文信息环境变量W3C Header 等效值
Trace ContextTRACEPARENTtraceparent
Trace StateTRACESTATEtracestate
BaggageBAGGAGEbaggage

实现可以支持其他传播格式,并应提供配置选项来覆盖默认环境变量。

格式限制

名称限制

用于上下文传播的环境变量名称

  • 为实现跨平台兼容性,应使用大写字母、数字和下划线。
  • 不得包含平台特定限制中禁止的字符。
  • 应遵循与所实现的传播格式规范一致的命名约定(例如,W3C trace context 的 TRACEPARENT)。

值限制

用于上下文传播的环境变量值

  • 必须仅使用 RFC 9110 中 HTTP 头字段允许的字符。
  • 必须遵循特定传播协议的格式要求(例如,W3C Trace Context 规范中的 TRACEPARENT 值)。
  • 不应包含敏感信息。

大小限制

实现应遵循平台特定的环境变量大小限制。

  • Windows:根据 Microsoft 文档,name=value 对的最大长度为 32,767 个字符。
  • UNIX:存在系统依赖的限制,通常低于 Windows。

当由于大小限制需要截断时,实现必须截断整个条目。截断应从条目列表的末尾开始。实现者必须记录如何进行优雅截断,并应提供指向相应规范的链接(例如,W3C tracestate 截断指南)。

操作指南

环境变量的不可变性

一旦为进程设置,环境变量在进程内应被视为不可变的。

  • 应用程序应在初始化期间读取与上下文相关的环境变量。
  • 应用程序不应修改父进程所在环境的与上下文相关的环境变量。

进程生成

生成子进程时:

  • 父进程应在生成子进程时复制当前环境变量(如果适用)、修改并注入上下文。
  • 子进程应在启动时从环境变量中提取上下文。
  • 当生成具有不同上下文或 baggage 的多个子进程时,每个子进程都应接收其自身的环境变量副本以及相应的信息。
  • 接收 SDK 设置的上下文并将其传递给应用程序自己的进程生成机制的责任在于应用程序所有者。语言实现不得处理生成进程。

安全

环境变量通常可供进程内运行的所有代码访问,并且在具有适当权限的情况下,可以从其他进程访问。

  • 实现不应在环境变量中存储敏感信息。
  • 在多租户环境中运行的应用程序应注意,环境变量可能对具有适当权限的其他进程或用户可见。

大小写敏感性

环境变量名称在 UNIX 上是区分大小写的,在 Windows 上是不区分大小写的。

  • 为了最大程度的兼容性,实现必须:
    • 始终使用大写名称(例如 TRACEPARENT 而不是 TraceParent)。
    • 设置环境变量时使用规范的大小写。

补充指南

重要提示

本节仅提供非规范性的实现指南,不增加规范的要求。

OpenTelemetry 的语言实现可以在如何实现环境变量上下文传播方面享有灵活性。已确定两种主要方法是可行的。

方法 1:提供专用的 EnvironmentContextPropagator

SDK 可以为环境变量创建专用的 propagator。例如,OTel Swift 实现了一个自定义的 EnvironmentContextPropagator,它在内部处理特定于环境的逻辑,本质上是对 TextMapPropagator 的装饰。

方法 2:通过 SettersGetters 直接使用载体

语言实现可以直接将现有的 TextMapPropagator 接口与特定于环境的载体一起使用。Go 和 Python SDK 遵循此模式,提供了:

  • EnvironmentGetter - 创建当前环境变量的内存副本,并从此副本中读取上下文。
  • EnvironmentSetter - 将上下文写入字典/映射,并提供该字典/映射给应用程序所有者,以便他们在生成进程时使用。

示例

通用行为

这两种方法都实现了相同的结果,同时提供了不同的开发者体验。语言实现可以根据其语言的习惯用法和生态系统约定选择任一方法。这两种方法中的行为是相同的,因为它们:

  1. 提取上下文:从环境变量读取,并委托给配置的 TextMapPropagator(例如 W3C、B3)进行解析。
  2. 注入上下文:返回一个环境变量的字典/映射,应用程序所有者可以将其传递给他们的进程生成库。