使用现有的 OpenTelemetry 设置

了解如何在 Sentry 中使用现有的自定义 OpenTelemetry 设置。

使用本指南时,当您已经有一个完全自定义的 OpenTelemetry 设置,或者打算在 Sentry SDK 旁边添加一个自定义的 OpenTelemetry 设置。

如果您只是想向 Sentry 设置中添加单独的 OpenTelemetry 仪器化,请阅读 添加额外的 OpenTelemetry 仪器化

要使用现有的 OpenTelemetry 设置,在 init({}) 配置中设置 skipOpenTelemetrySetup: true,然后自行设置 Sentry 所需的所有组件。最后,安装 @sentry/opentelemetry 并添加以下内容:

Copied
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const Sentry = require("@sentry/node");
const {
  SentrySpanProcessor,
  SentryPropagator,
  SentrySampler,
} = require("@sentry/opentelemetry");

const sentryClient = Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  skipOpenTelemetrySetup: true,

  // The SentrySampler will use this to determine which traces to sample
  tracesSampleRate: 1.0,
});

// Note: This could be BasicTracerProvider or any other provider depending on
// how you are using the OpenTelemetry SDK
const provider = new NodeTracerProvider({
  // Ensure the correct subset of traces is sent to Sentry
  // This also ensures trace propagation works as expected
  sampler: sentryClient ? new SentrySampler(sentryClient) : undefined,
});

// Ensure spans are correctly linked & sent to Sentry
provider.addSpanProcessor(new SentrySpanProcessor());

provider.register({
  // Ensure trace propagation works
  // This relies on the SentrySampler for correct propagation
  propagator: new SentryPropagator(),
  // Ensure context & request isolation are correctly managed
  contextManager: new Sentry.SentryContextManager(),
});

// Validate that the setup is correct
Sentry.validateOpenTelemetrySetup();

确保所有 必需的 OpenTelemetry 仪器化 正确设置。否则,Sentry SDK 可能无法按预期工作。

如果您有一个自定义的 OpenTelemetry 设置,并且只想使用 Sentry 进行错误监控,可以跳过添加 SentrySpanProcessor。即使您不想将任何跟踪数据发送到 Sentry,您仍然需要添加 SentryContextManagerSentryPropagatorSentrySampler 到您的设置中。继续阅读以了解为什么需要这些组件。

为了让 Sentry SDK 按预期工作并与 OpenTelemetry 同步,我们需要一些组件。

Sentry 正常工作所需的组件:

  • SentryContextManager: 确保 OpenTelemetry 上下文与 Sentry 同步,例如正确隔离同时请求之间的数据。
  • SentrySampler: 确保尊重 Sentry 的 tracesSampleRate。即使您不使用 Sentry 进行跟踪,您仍然需要这个组件以确保跟踪传播按预期工作。如果要使用自定义采样器,请阅读 使用自定义采样器
  • SentryPropagator: 确保跟踪传播按预期工作。
  • 必需的仪器化: 确保跟踪传播按预期工作。

如果还使用 Sentry 进行跟踪所需的额外组件:

  • SentrySpanProcessor: 确保 span 正确发送到 Sentry。

跟踪传播对于 Sentry 自动连接服务是必需的 (例如,如果您想连接前端和后端,或不同的后端服务)。这使得您能够跨服务查看相关的错误。

了解有关跟踪传播的更多信息。

以下代码片段展示了如何仅使用 Sentry 进行错误监控:

Copied
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const Sentry = require("@sentry/node");
const {
  SentryPropagator,
  SentrySampler,
} = require("@sentry/opentelemetry");
const {
  registerInstrumentations,
} = require("@opentelemetry/instrumentation");

const sentryClient = Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  skipOpenTelemetrySetup: true,

  // Important: We do not define a tracesSampleRate here at all!
  // This leads to tracing being disabled

  // Disable emitting of spans in the httpIntegration
  integrations: [Sentry.httpIntegration({ spans: false })],
});

// Create and configure e.g. NodeTracerProvider
const provider = new NodeTracerProvider({
  // This ensures trace propagation works as expected
  sampler: sentryClient ? new SentrySampler(sentryClient) : undefined,
});

provider.addSpanProcessor(
  new BatchSpanProcessor(
    new OTLPTraceExporter({
      url: "http://OTLP-ENDPOINT.com/api",
    }),
  ),
);

// Initialize the provider
provider.register({
  propagator: new SentryPropagator(),
  contextManager: new Sentry.SentryContextManager(),
});

registerInstrumentations({
  instrumentations: [
    // Add OTEL instrumentation here
  ],
});

默认情况下,Sentry 会注册 OpenTelemetry 仪器化,以自动捕获跨越传入和传出 HTTP 请求、数据库查询等的 span。

如果未启用跟踪(SDK 配置中未定义 tracesSampleRate),则只会注册少量的 OpenTelemetry 仪器化。这包括以下内容:

如果未启用跟踪,性能仪器化将不会被注册,但它们仍然会被包含在打包文件中。如果您想减少打包文件大小或使用的依赖项,可以参考

无性能集成的 Sentry 设置

这些仪器化确保跟踪传播按预期工作。

如果您想添加自己的 HTTP/node-fetch 仪器化,必须按照以下步骤进行:

自 SDK 版本 8.35.0 起可用

您可以在您的 OpenTelemetry 设置中添加自己的 @opentelemetry/instrumentation-http 实例。但是,在这种情况下,您需要禁用 Sentry 的 httpIntegration 中的 span 创建:

Copied
const sentryClient = Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  skipOpenTelemetrySetup: true,
  integrations: [Sentry.httpIntegration({ spans: false })],
});

确保 httpIntegration 仍然以这种方式注册,以确保 Sentry SDK 能够正确隔离请求,例如在捕获错误时。

如果禁用了跟踪,Node Fetch 仪器化将不会发出任何 span。在这种情况下,它只会注入特定于 Sentry 的跟踪传播头。您可以自由地在此基础上添加自己的 Node Fetch 仪器化,可以根据需要发出 span。

虽然您可以使用自己的采样器,但我们建议使用 SentrySampler。这将确保根据您的 tracesSampleRate 发送到 Sentry 的正确子集的跟踪。它还将确保所有其他 Sentry 功能(如跟踪传播)按预期工作。如果您确实需要使用自己的采样器,请确保使用我们的 wrapSamplingDecision 方法包装您的 SamplingResult,如下例所示:

Copied
const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node");
const Sentry = require("@sentry/node");
const {
  SentrySpanProcessor,
  SentryPropagator,
  SentrySampler,
  wrapSamplingDecision,
} = require("@sentry/opentelemetry");

// implements Sampler from "@opentelemetry/sdk-trace-node"
class CustomSampler {
  shouldSample(
    context,
    _traceId,
    _spanName,
    _spanKind,
    attributes,
    _links,
  ) {
    const decision = yourDecisionLogic();

    // wrap the result
    return wrapSamplingDecision({
      decision,
      context,
      spanAttributes: attributes,
    });
  }

  toString() {
    return CustomSampler.name;
  }
}

const sentryClient = Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  skipOpenTelemetrySetup: true,

  // By defining any sample rate,
  // tracing intergations will be added by default
  // omit this if you do not want any performance integrations to be added
  tracesSampleRate: 0,
});

const provider = new NodeTracerProvider({
  sampler: new CustomSampler(),
});

// ...rest of your setup

// Validate that the setup is correct
Sentry.validateOpenTelemetrySetup();

如果您的应用程序在 ESM(import/export 语法)中运行,OpenTelemetry 需要您设置 ESM 加载器钩子

Sentry SDK 默认会自动注册 ESM 加载器钩子。 然而,如果您有自己的 OpenTelemetry 设置,建议配置 Sentry SDK 不要注册这些钩子,而是由您自己注册。 您可以通过将 registerEsmLoaderHooks 设置为 false设置 ESM 加载器钩子 来实现:

Copied
Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  skipOpenTelemetrySetup: true,
  registerEsmLoaderHooks: false,
});

了解有关 ESM 安装方法的更多信息。