@ogcio/o11y-sdk-node
Version:
Opentelemetry standard instrumentation SDK for NodeJS based project
73 lines (72 loc) • 3.14 kB
JavaScript
/**
* Enhances a NodeSDKConfig with Sentry for Node integration.
*
* Includes sentry own processors and context management.
*/
export async function withSentry(config, options = {}) {
const { sentryOptions = {}, useSentrySampling = true } = options;
const components = await buildSentryComponents(sentryOptions, useSentrySampling);
return {
...config,
prependSpanProcessors: [
components.spanProcessor,
...(config.prependSpanProcessors ?? []),
],
// Wrap sampler with SentrySampler, using o11y's sampler as fallback
samplerWrapper: (defaultSampler) => {
// Chain with any existing wrapper
const baseSampler = config.samplerWrapper
? config.samplerWrapper(defaultSampler)
: defaultSampler;
return components.sampler(baseSampler);
},
additionalPropagators: [
components.propagator,
...(config.additionalPropagators ?? []),
],
// Sentry own async context tracking
contextManager: config.contextManager ?? components.contextManager,
onSdkStarted: components.validate,
};
}
/**
* Builds Sentry OTEL components by dynamically importing @sentry packages.
* This keeps @sentry/* as optional peer dependencies.
*/
async function buildSentryComponents(sentryOptions, useSentrySampling = false) {
// Dynamic imports to keep @sentry/* as optional peer dependencies
const Sentry = await import("@sentry/node");
const SentryOtel = await import("@sentry/opentelemetry");
// Destructure common options to be defaulted, pass rest to Sentry.init
const { dsn, environment, tracesSampleRate, tracesSampler, integrations, sendDefaultPii, enableLogs, ...restOptions } = sentryOptions;
// Initialize Sentry with skipOpenTelemetrySetup
Sentry.init({
dsn: dsn ?? process.env.SENTRY_DSN,
environment: environment ?? process.env.SENTRY_ENV ?? process.env.NODE_ENV,
skipOpenTelemetrySetup: true,
integrations: integrations ?? [
Sentry.redisIntegration(),
Sentry.extraErrorDataIntegration(),
Sentry.postgresIntegration(),
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
],
tracesSampleRate: useSentrySampling ? (tracesSampleRate ?? 1) : 1,
tracesSampler: useSentrySampling ? tracesSampler : undefined,
sendDefaultPii: sendDefaultPii ?? false,
enableLogs: enableLogs ?? true,
...restOptions,
});
const sentryClient = Sentry.getClient();
if (!sentryClient) {
console.warn("Unable to initialize Sentry client. Telemetry may not work as expected.");
}
return {
spanProcessor: new SentryOtel.SentrySpanProcessor(),
sampler: (fallbackSampler) => sentryClient
? new SentryOtel.SentrySampler(sentryClient)
: fallbackSampler,
propagator: new SentryOtel.SentryPropagator(),
contextManager: new Sentry.SentryContextManager(),
validate: Sentry.validateOpenTelemetrySetup,
};
}