CnOps 智能运维与可观测社区
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题
导航菜单
首页开源项目实践文章视频课程常见问答开发者工具STAROps 专题

CnOps 智能运维与可观测社区

愿景

CnOps 智能运维与可观测社区是一个以"智能运维与可观测"为核心的开放、包容、分享的技术社区,旨在聚集运维专家、开发者和爱好者,共同探讨、学习和分享可观测最佳实践与最新技术,与众多技术社区合作互动,共同探讨交叉领域的技术挑战,推动可观测领域的创新与进步。

内容社区

  • 实践文章
  • 视频课程
  • 开源项目
  • 常见问答
  • 开发者工具

友情链接

  • Prometheus
  • Grafana Lab
  • OpenTelemetry
  • LoongCollector

关注我们

阿里云云原生公众号阿里云云原生
阿里云可观测公众号阿里云可观测

Copyright © 2026 CnOps 社区. All rights reserved.

首页/开源项目/OpenTelemetry/上下文
文档目录
文档开始手动插桩使用插桩库导出器资源采样什么是 OpenTelemetry?
API 参考文档示例
采样插桩使用插桩库导出器上下文传播资源Serverless基准测试API 参考文档示例资源目录
支持库列表

OpenTelemetry

上下文

要使 OpenTelemetry 正常工作,它必须对关键遥测数据进行存储与传递。 例如,当系统接收到请求并启动一个追踪 Span 时,该 Span 必须能够被后续创建其子 Span 的组件所访问。 为解决该问题,OpenTelemetry 会将追踪 Span 存储在上下文中。 本文档介绍了适用于 JavaScript 的 OpenTelemetry 上下文 API,以及具体使用方法。 上下文...

要使 OpenTelemetry 正常工作,它必须对关键遥测数据进行存储与传递。
例如,当系统接收到请求并启动一个追踪 Span 时,该 Span 必须能够被后续创建其子 Span 的组件所访问。
为解决该问题,OpenTelemetry 会将追踪 Span 存储在上下文中。
本文档介绍了适用于 JavaScript 的 OpenTelemetry 上下文 API,以及具体使用方法。

上下文管理器 {#context-manager}

上下文 API 依赖于上下文管理器才能工作。
本文档中的示例将假设你已经配置好了一个上下文管理器。
通常上下文管理器由你的 SDK 提供,但是也可以直接注册一个,如下所示:

import * as api from '@opentelemetry/api';
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';

const contextManager = new AsyncHooksContextManager();
contextManager.enable();
api.context.setGlobalContextManager(contextManager);

Root 上下文 {#root-context}

ROOT_CONTEXT 是一个空上下文。
如果当前没有活跃上下文,ROOT_CONTEXT 就会成为活跃上下文。
关于活跃上下文的详细信息,请参考活跃上下文。

上下文键 {#context-keys}

上下文条目是键值对。
键可以通过调用 api.createContextKey(description) 来创建。

import * as api from '@opentelemetry/api';

const key1 = api.createContextKey('My first key');
const key2 = api.createContextKey('My second key');

基本操作 {#basic-operations}

获取条目 {#get-entry}

条目可以通过 context.getValue(key) 方法来访问。

import * as api from '@opentelemetry/api';

const key = api.createContextKey('some key');
// ROOT_CONTEXT 是一个空上下文
const ctx = api.ROOT_CONTEXT;

const value = ctx.getValue(key);

设置条目 {#set-entry}

条目可以通过 context.setValue(key, value) 方法来创建。
设置上下文条目会创建一个新上下文,其中包含前一个上下文的所有条目,但包含新条目。
设置上下文条目不会修改前一个上下文。

import * as api from '@opentelemetry/api';

const key = api.createContextKey('some key');
const ctx = api.ROOT_CONTEXT;

// 添加一个新条目
const ctx2 = ctx.setValue(key, 'context 2');

// ctx2 包含新条目
console.log(ctx2.getValue(key)); // "context 2"

// ctx 未被修改
console.log(ctx.getValue(key)); // undefined

删除条目 {#delete-entry}

条目可以通过调用 context.deleteValue(key) 方法来删除。
删除上下文条目会创建一个新上下文,其中包含前一个上下文的所有条目,但不包含被标识为键的条目。
删除上下文条目不会修改前一个上下文。

import * as api from '@opentelemetry/api';

const key = api.createContextKey('some key');
const ctx = api.ROOT_CONTEXT;
const ctx2 = ctx.setValue(key, 'context 2');

// 删除条目
const ctx3 = ctx2.deleteValue(key);

// ctx3 不包含条目
console.log(ctx3.getValue(key)); // undefined

// ctx2 未被修改
console.log(ctx2.getValue(key)); // "context 2"
// ctx 未被修改
console.log(ctx.getValue(key)); // undefined

活跃上下文 {#active-context}

IMPORTANT: 此假设你已经配置了上下文管理器。如果没有配置,api.context.active() 将始终返回 ROOT_CONTEXT。

活跃上下文是指由 api.context.active() 返回的上下文。
上下文对象包含一些条目,这些条目允许追踪组件在追踪单个执行线程时相互通信,并确保追踪成功创建。
例如,当创建一个 Span 时,它可以添加到上下文中。
之后,当创建另一个 Span 时,它可以使用上下文中的 Span 作为其父 Span。
这一能力,是通过各类机制实现的,Node.js 环境下借助
async_hooks 或
AsyncLocalStorage,浏览器环境下则依托
zone.js,以此确保上下文能在单次执行链路中完成传递。
如果没有上下文处于活跃状态,则返回 ROOT_CONTEXT,它只是一个空的上下文对象。

获取活跃上下文 {#get-active-context}

活跃上下文,是指由 api.context.active() 返回的上下文。

import * as api from '@opentelemetry/api';

// 返回当前活跃上下文
// 如果没有活跃上下文,返回 ROOT_CONTEXT
const ctx = api.context.active();

设置活跃上下文 {#set-active-context}

可以使用 api.context.with(ctx, callback) 来激活一个上下文。在执行
callback 回调期间,传递给 with 的上下文将成为 context.active 的返回值。

import * as api from '@opentelemetry/api';

const key = api.createContextKey('Key to store a value');
const ctx = api.context.active();

api.context.with(ctx.setValue(key, 'context 2'), async () => {
  // "context 2" 是活跃上下文
  console.log(api.context.active().getValue(key)); // "context 2"
});

api.context.with(context, callback) 的返回值,是回调的返回值。回调总是同步调用。

import * as api from '@opentelemetry/api';

const name = await api.context.with(api.context.active(), async () => {
  const row = await db.getSomeValue();
  return row['name'];
});

console.log(name); // 数据库返回的 name

活跃上下文执行可能是嵌套的。

import * as api from '@opentelemetry/api';

const key = api.createContextKey('Key to store a value');
const ctx = api.context.active();

// 没有活跃上下文
console.log(api.context.active().getValue(key)); // undefined

api.context.with(ctx.setValue(key, 'context 2'), () => {
  // "context 2" 是活跃上下文
  console.log(api.context.active().getValue(key)); // "context 2"
  api.context.with(ctx.setValue(key, 'context 3'), () => {
    // "context 3" 是活跃上下文
    console.log(api.context.active().getValue(key)); // "context 3"
  });
  // "context 2" 是活跃上下文
  console.log(api.context.active().getValue(key)); // "context 2"
});

// 没有活跃上下文
console.log(api.context.active().getValue(key)); // undefined

示例 {#example}

这个更复杂的示例展示了上下文如何不被修改,而是创建新的上下文对象。

import * as api from '@opentelemetry/api';

const ctx = api.context.active(); // 当没有活跃上下文时返回 ROOT_CONTEXT
const ctx2 = ctx.setValue(key, 'context 2'); // 不会修改 ctx

console.log(ctx.getValue(key)); //? undefined
console.log(ctx2.getValue(key)); //? "context 2"

const ret = api.context.with(ctx2, () => {
  const ctx3 = api.context.active().setValue(key, 'context 3');

  console.log(api.context.active().getValue(key)); //? "context 2"
  console.log(ctx.getValue(key)); //? undefined
  console.log(ctx2.getValue(key)); //? "context 2"
  console.log(ctx3.getValue(key)); //? "context 3"

  api.context.with(ctx3, () => {
    console.log(api.context.active().getValue(key)); //? "context 3"
  });
  console.log(api.context.active().getValue(key)); //? "context 2"

  return 'return value';
});
// 回调返回的值会返回给调用方
console.log(ret); //? "return value"

文章大纲