使用现有的 OpenTelemetry 设置
了解如何在 Sentry 中使用现有的自定义 OpenTelemetry 设置。
使用本指南时,当您已经有一个完全自定义的 OpenTelemetry 设置,或者打算在 Sentry SDK 旁边添加一个自定义的 OpenTelemetry 设置。
如果您只是想向 Sentry 设置中添加单独的 OpenTelemetry 仪器化,请阅读 添加额外的 OpenTelemetry 仪器化。
要使用现有的 OpenTelemetry 设置,在 init({})
配置中设置 skipOpenTelemetrySetup: true
,然后自行设置 Sentry 所需的所有组件。最后,安装 @sentry/opentelemetry
并添加以下内容:
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,您仍然需要添加 SentryContextManager
、SentryPropagator
和 SentrySampler
到您的设置中。继续阅读以了解为什么需要这些组件。
为了让 Sentry SDK 按预期工作并与 OpenTelemetry 同步,我们需要一些组件。
Sentry 正常工作所需的组件:
- SentryContextManager: 确保 OpenTelemetry 上下文与 Sentry 同步,例如正确隔离同时请求之间的数据。
- SentrySampler: 确保尊重 Sentry 的
tracesSampleRate
。即使您不使用 Sentry 进行跟踪,您仍然需要这个组件以确保跟踪传播按预期工作。如果要使用自定义采样器,请阅读 使用自定义采样器。 - SentryPropagator: 确保跟踪传播按预期工作。
- 必需的仪器化: 确保跟踪传播按预期工作。
如果还使用 Sentry 进行跟踪所需的额外组件:
- SentrySpanProcessor: 确保 span 正确发送到 Sentry。
跟踪传播对于 Sentry 自动连接服务是必需的 (例如,如果您想连接前端和后端,或不同的后端服务)。这使得您能够跨服务查看相关的错误。
了解有关跟踪传播的更多信息。
以下代码片段展示了如何仅使用 Sentry 进行错误监控:
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 仪器化,用于处理请求隔离和跟踪传播。这可以与 @opentelemetry/instrumentation-http 并行工作,如果您注册了它。
- nativeNodeFetchIntegration 注册 opentelemetry-instrumentation-fetch-node,这对于跟踪传播是必需的。
如果未启用跟踪,性能仪器化将不会被注册,但它们仍然会被包含在打包文件中。如果您想减少打包文件大小或使用的依赖项,可以参考
无性能集成的 Sentry 设置
这些仪器化确保跟踪传播按预期工作。
如果您想添加自己的 HTTP/node-fetch 仪器化,必须按照以下步骤进行:
自 SDK 版本 8.35.0 起可用
您可以在您的 OpenTelemetry 设置中添加自己的 @opentelemetry/instrumentation-http
实例。但是,在这种情况下,您需要禁用 Sentry 的 httpIntegration
中的 span 创建:
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
,如下例所示:
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 加载器钩子 来实现:
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
skipOpenTelemetrySetup: true,
registerEsmLoaderHooks: false,
});
为什么建议自己注册加载器钩子?
当您有一个完整的自定义 OpenTelemetry 设置时,建议自己注册 ESM 加载器钩子,首先是因为从架构上来说这样做是最合理的。 您可能已经花费了精力来单独设置 OpenTelemetry,现在希望在不干扰 OpenTelemetry 设置的情况下将 Sentry 添加到应用程序中。
此外,通过自己注册钩子可以避免一些常见问题:
- 多次注册加载器钩子可能会导致重复的 span 被创建。更多详情。
- ESM 中的 OpenTelemetry 仪器化非常敏感,取决于仪器化添加的时间相对于加载器钩子注册的时间。 对此的控制应由 OpenTelemetry 设置的所有者掌握,而不是 Sentry SDK。
了解有关 ESM 安装方法的更多信息。