diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 69ef5b6067be..850a00a549a5 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -6,6 +6,7 @@ export { fastifyIntegration, setupFastifyErrorHandler } from './integrations/tra export { amqplibIntegration, anthropicIntegration as anthropicAIIntegration, + dataloaderIntegration, expressIntegration, firebaseIntegration, genericPoolIntegration, @@ -13,6 +14,7 @@ export { graphqlDiagnosticsIntegration as graphqlIntegration, hapiIntegration, kafkajsIntegration as kafkaIntegration, + knexIntegration, koaIntegration, langChainIntegration, langGraphIntegration, @@ -31,8 +33,6 @@ export { redisIntegration } from './integrations/tracing/redis'; export { prismaIntegration } from '@sentry/server-utils'; export { setupHapiErrorHandler } from './integrations/tracing/hapi'; export { setupKoaErrorHandler } from './integrations/tracing/koa'; -export { knexIntegration } from './integrations/tracing/knex'; -export { dataloaderIntegration } from './integrations/tracing/dataloader'; export { launchDarklyIntegration, buildLaunchDarklyFlagUsedHandler, diff --git a/packages/node/src/integrations/tracing/dataloader/index.ts b/packages/node/src/integrations/tracing/dataloader/index.ts deleted file mode 100644 index 0f20888f3207..000000000000 --- a/packages/node/src/integrations/tracing/dataloader/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { IntegrationFn } from '@sentry/core'; -import { defineIntegration } from '@sentry/core'; -import { generateInstrumentOnce } from '../../../otel/instrument'; -import { - dataloaderIntegration as dataloaderChannelIntegration, - isOrchestrionInjected, -} from '@sentry/server-utils/orchestrion'; -import { DataloaderInstrumentation } from './vendored/instrumentation'; - -const INTEGRATION_NAME = 'Dataloader' as const; - -export const instrumentDataloader = generateInstrumentOnce(INTEGRATION_NAME, () => new DataloaderInstrumentation()); - -const _dataloaderIntegration = (() => { - return { - name: INTEGRATION_NAME, - setupOnce() { - // Decide here, not in the factory: the runtime channel injection runs inside `Sentry.init()`, - // after the integrations array has already been built, so `isOrchestrionInjected()` is only - // reliable by `setupOnce`. When the diagnostics channels are injected (runtime hook or bundler - // plugin), subscribe to them; otherwise fall back to the vendored OTel instrumentation. - if (isOrchestrionInjected()) { - dataloaderChannelIntegration().setupOnce?.(); - } else { - instrumentDataloader(); - } - }, - }; -}) satisfies IntegrationFn; - -/** - * Adds Sentry tracing instrumentation for the [dataloader](https://www.npmjs.com/package/dataloader) library. - * - * For more information, see the [`dataloaderIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/dataloader/). - * - * @example - * ```javascript - * const Sentry = require('@sentry/node'); - * - * Sentry.init({ - * integrations: [Sentry.dataloaderIntegration()], - * }); - * ``` - */ -export const dataloaderIntegration = defineIntegration(_dataloaderIntegration); diff --git a/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts deleted file mode 100644 index 4fb13c0755b4..000000000000 --- a/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - * - * NOTICE from the Sentry authors: - * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-dataloader - * - Upstream version: @opentelemetry/instrumentation-dataloader@0.35.0 - * - Minor TypeScript strictness adjustments for this repository's compiler settings - */ - -import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation'; -import { CACHE_KEY, SENTRY_KIND } from '@sentry/conventions/attributes'; -import type { BatchLoadFn, DataLoader, DataLoaderConstructor } from './types'; -import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/core'; - -const MODULE_NAME = 'dataloader'; -const PACKAGE_NAME = '@sentry/instrumentation-dataloader'; -const ORIGIN = 'auto.db.otel.dataloader'; - -type LoadFn = DataLoader['load']; -type LoadManyFn = DataLoader['loadMany']; -type PrimeFn = DataLoader['prime']; -type ClearFn = DataLoader['clear']; -type ClearAllFn = DataLoader['clearAll']; - -function isModule(module: unknown): module is { [Symbol.toStringTag]: 'Module'; default: DataLoaderConstructor } { - return (module as { [Symbol.toStringTag]: string })[Symbol.toStringTag] === 'Module'; -} - -function extractModuleExports(module: unknown): DataLoaderConstructor { - return isModule(module) - ? module.default // ESM - : (module as DataLoaderConstructor); // CommonJS -} - -function getSpanName( - dataloader: DataLoader, - operation: 'load' | 'loadMany' | 'batch' | 'prime' | 'clear' | 'clearAll', -): string { - const dataloaderName = dataloader.name; - if (dataloaderName) { - return `${MODULE_NAME}.${operation} ${dataloaderName}`; - } - - return `${MODULE_NAME}.${operation}`; -} - -// `load`, `loadMany` and `batch` are all cache reads -function getSpanOp(operation: 'load' | 'loadMany' | 'batch' | 'prime' | 'clear' | 'clearAll'): string | undefined { - if (operation === 'load' || operation === 'loadMany' || operation === 'batch') { - return 'cache.get'; - } - - return undefined; -} - -// `load` receives a single key, `loadMany`/`batch` receive a key array. Normalize both to the -// `string[]` shape `cache.key` expects. -function getCacheKey(keyArg: unknown): string[] | undefined { - if (Array.isArray(keyArg)) { - return keyArg.map(key => String(key)); - } - - return keyArg == null ? undefined : [String(keyArg)]; -} - -export class DataloaderInstrumentation extends InstrumentationBase { - constructor(config = {}) { - super(PACKAGE_NAME, SDK_VERSION, config); - } - - protected init() { - return [ - new InstrumentationNodeModuleDefinition( - MODULE_NAME, - ['>=2.0.0 <3'], - module => { - const dataloader = extractModuleExports(module); - this._patchLoad(dataloader.prototype); - this._patchLoadMany(dataloader.prototype); - this._patchPrime(dataloader.prototype); - this._patchClear(dataloader.prototype); - this._patchClearAll(dataloader.prototype); - - return this._getPatchedConstructor(dataloader); - }, - module => { - const dataloader = extractModuleExports(module); - ['load', 'loadMany', 'prime', 'clear', 'clearAll'].forEach(method => { - if (isWrapped(dataloader.prototype[method])) { - this._unwrap(dataloader.prototype, method); - } - }); - }, - ), - ]; - } - - private _wrapBatchLoadFn(batchLoadFn: BatchLoadFn): BatchLoadFn { - // oxlint-disable-next-line typescript/no-this-alias - const instrumentation = this; - - return function patchedBatchLoadFn(this: DataLoader, ...args: Parameters>) { - if (!instrumentation.isEnabled()) { - return batchLoadFn.call(this, ...args); - } - - return startSpan( - { - name: getSpanName(this, 'batch'), - links: this._batch?.spanLinks, - attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('batch'), - [CACHE_KEY]: getCacheKey(args[0]), - }, - onlyIfParent: true, - }, - () => batchLoadFn.apply(this, args), - ); - }; - } - - private _getPatchedConstructor(constructor: DataLoaderConstructor): DataLoaderConstructor { - // oxlint-disable-next-line typescript/no-this-alias - const instrumentation = this; - const prototype = constructor.prototype; - - if (!instrumentation.isEnabled()) { - return constructor; - } - - // oxlint-disable-next-line typescript/no-explicit-any - function PatchedDataloader(this: DataLoader, ...args: any[]) { - // BatchLoadFn is the first constructor argument - // https://github.com/graphql/dataloader/blob/77c2cd7ca97e8795242018ebc212ce2487e729d2/src/index.js#L47 - if (typeof args[0] === 'function') { - if (isWrapped(args[0])) { - instrumentation._unwrap(args, 0); - } - - args[0] = instrumentation._wrapBatchLoadFn(args[0]); - } - - return constructor.apply(this, args); - } - - PatchedDataloader.prototype = prototype; - return PatchedDataloader as unknown as DataLoaderConstructor; - } - - private _patchLoad(proto: DataLoader) { - // oxlint-disable-next-line typescript/unbound-method - if (isWrapped(proto.load)) { - this._unwrap(proto, 'load'); - } - - this._wrap(proto, 'load', this._getPatchedLoad.bind(this)); - } - - private _getPatchedLoad(original: LoadFn): LoadFn { - return function patchedLoad(this: DataLoader, ...args: Parameters) { - return startSpan( - { - name: getSpanName(this, 'load'), - attributes: { - [SENTRY_KIND]: 'client', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('load'), - [CACHE_KEY]: getCacheKey(args[0]), - }, - onlyIfParent: true, - }, - span => { - const result = original.call(this, ...args); - - if (this._batch && span.isRecording()) { - if (!this._batch.spanLinks) { - this._batch.spanLinks = []; - } - - this._batch.spanLinks.push({ context: span.spanContext() }); - } - - return result; - }, - ); - }; - } - - private _patchLoadMany(proto: DataLoader) { - // oxlint-disable-next-line typescript/unbound-method - if (isWrapped(proto.loadMany)) { - this._unwrap(proto, 'loadMany'); - } - - this._wrap(proto, 'loadMany', this._getPatchedLoadMany.bind(this)); - } - - private _getPatchedLoadMany(original: LoadManyFn): LoadManyFn { - return function patchedLoadMany(this: DataLoader, ...args: Parameters) { - return startSpan( - { - name: getSpanName(this, 'loadMany'), - attributes: { - [SENTRY_KIND]: 'client', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('loadMany'), - [CACHE_KEY]: getCacheKey(args[0]), - }, - onlyIfParent: true, - }, - () => original.call(this, ...args), - ); - }; - } - - private _patchPrime(proto: DataLoader) { - // oxlint-disable-next-line typescript/unbound-method - if (isWrapped(proto.prime)) { - this._unwrap(proto, 'prime'); - } - - this._wrap(proto, 'prime', this._getPatchedPrime.bind(this)); - } - - private _getPatchedPrime(original: PrimeFn): PrimeFn { - return function patchedPrime(this: DataLoader, ...args: Parameters) { - return startSpan( - { - name: getSpanName(this, 'prime'), - attributes: { - [SENTRY_KIND]: 'client', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('prime'), - }, - onlyIfParent: true, - }, - () => original.call(this, ...args), - ); - }; - } - - private _patchClear(proto: DataLoader) { - // oxlint-disable-next-line typescript/unbound-method - if (isWrapped(proto.clear)) { - this._unwrap(proto, 'clear'); - } - - this._wrap(proto, 'clear', this._getPatchedClear.bind(this)); - } - - private _getPatchedClear(original: ClearFn): ClearFn { - return function patchedClear(this: DataLoader, ...args: Parameters) { - return startSpan( - { - name: getSpanName(this, 'clear'), - attributes: { - [SENTRY_KIND]: 'client', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('clear'), - }, - onlyIfParent: true, - }, - () => original.call(this, ...args), - ); - }; - } - - private _patchClearAll(proto: DataLoader) { - // oxlint-disable-next-line typescript/unbound-method - if (isWrapped(proto.clearAll)) { - this._unwrap(proto, 'clearAll'); - } - - this._wrap(proto, 'clearAll', this._getPatchedClearAll.bind(this)); - } - - private _getPatchedClearAll(original: ClearAllFn): ClearAllFn { - return function patchedClearAll(this: DataLoader, ...args: Parameters) { - return startSpan( - { - name: getSpanName(this, 'clearAll'), - attributes: { - [SENTRY_KIND]: 'client', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('clearAll'), - }, - onlyIfParent: true, - }, - () => original.call(this, ...args), - ); - }; - } -} diff --git a/packages/node/src/integrations/tracing/dataloader/vendored/types.ts b/packages/node/src/integrations/tracing/dataloader/vendored/types.ts deleted file mode 100644 index 6d4f9ccb9a15..000000000000 --- a/packages/node/src/integrations/tracing/dataloader/vendored/types.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - * - * NOTICE from the Sentry authors: - * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-dataloader - * - Upstream version: @opentelemetry/instrumentation-dataloader@0.35.0 - */ - -import type { SpanLink } from '@sentry/core'; - -/* Simplified types inlined from dataloader. */ - -export type BatchLoadFn = (keys: ReadonlyArray) => PromiseLike>; - -/** A `DataLoader` instance. */ -export interface DataLoader { - _batchLoadFn: BatchLoadFn; - _batch: { spanLinks?: SpanLink[] } | null; - load(key: K): Promise; - loadMany(keys: ArrayLike): Promise>; - prime(key: K, value: V | Error): this; - clear(key: K): this; - clearAll(): this; - name: string | undefined; - // oxlint-disable-next-line typescript/no-explicit-any - [key: string]: any; -} - -/** The `DataLoader` class/constructor. */ -export interface DataLoaderConstructor { - // oxlint-disable-next-line typescript/no-explicit-any - new (batchLoadFn: BatchLoadFn, options?: any): DataLoader; - prototype: DataLoader; -} diff --git a/packages/node/src/integrations/tracing/knex/index.ts b/packages/node/src/integrations/tracing/knex/index.ts deleted file mode 100644 index 8c32fe87168c..000000000000 --- a/packages/node/src/integrations/tracing/knex/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { KnexInstrumentation } from './vendored/instrumentation'; -import type { IntegrationFn } from '@sentry/core'; -import { defineIntegration } from '@sentry/core'; -import { generateInstrumentOnce } from '../../../otel/instrument'; -import { isOrchestrionInjected, knexIntegration as knexChannelIntegration } from '@sentry/server-utils/orchestrion'; - -const INTEGRATION_NAME = 'Knex' as const; - -export const instrumentKnex = generateInstrumentOnce(INTEGRATION_NAME, () => new KnexInstrumentation()); - -const _knexIntegration = (() => { - return { - name: INTEGRATION_NAME, - setupOnce() { - // Prefer the diagnostics-channel subscriber when orchestrion injected its channels; otherwise - // fall back to the vendored OTel instrumentation. `isOrchestrionInjected()` is only reliable by - // `setupOnce` (the runtime injection runs during `Sentry.init()`, after integrations are built). - if (isOrchestrionInjected()) { - knexChannelIntegration().setupOnce?.(); - } else { - instrumentKnex(); - } - }, - }; -}) satisfies IntegrationFn; - -/** - * Knex integration - * - * Capture tracing data for [Knex](https://knexjs.org/). - * - * @example - * ```javascript - * import * as Sentry from '@sentry/node'; - * - * Sentry.init({ - * integrations: [Sentry.knexIntegration()], - * }); - * ``` - */ -export const knexIntegration = defineIntegration(_knexIntegration); diff --git a/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts deleted file mode 100644 index e3b00ed2fcc4..000000000000 --- a/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - * - * NOTICE from the Sentry authors: - * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-knex - * - Upstream version: @opentelemetry/instrumentation-knex@0.62.0 - * - Minor TypeScript strictness adjustments for this repository's compiler settings - * - Refactored to use Sentry's span APIs instead of OpenTelemetry tracing APIs - */ - -/* oxlint-disable typescript/no-deprecated */ - -import type { InstrumentationConfig } from '@opentelemetry/instrumentation'; -import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation'; -import type { Span, SpanAttributes } from '@sentry/core'; -import { - getActiveSpan, - SDK_VERSION, - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_STATUS_ERROR, - startSpan, -} from '@sentry/core'; -import { - DB_NAME, - DB_OPERATION, - DB_STATEMENT, - DB_SYSTEM, - DB_USER, - NET_PEER_NAME, - NET_PEER_PORT, - NET_TRANSPORT, - SENTRY_KIND, -} from '@sentry/conventions/attributes'; -import { InstrumentationNodeModuleFile } from '../../InstrumentationNodeModuleFile'; -import { ATTR_DB_SQL_TABLE } from './semconv'; -import * as utils from './utils'; - -const PACKAGE_NAME = '@sentry/instrumentation-knex'; -const ORIGIN = 'auto.db.otel.knex'; - -const MODULE_NAME = 'knex'; -const SUPPORTED_VERSIONS = [ - // use "lib/execution" for runner.js, "lib" for client.js as basepath, latest tested 0.95.6 - '>=0.22.0 <4', - // use "lib" as basepath - '>=0.10.0 <0.18.0', - '>=0.19.0 <0.22.0', - // use "src" as basepath - '>=0.18.0 <0.19.0', -]; - -// Max length of the query text captured in the `db.statement` attribute; ".." is appended when truncated. -const MAX_QUERY_LENGTH = 1022; - -const parentSpanSymbol = Symbol('sentry.instrumentation-knex.parent-span'); - -export class KnexInstrumentation extends InstrumentationBase { - public constructor(config: InstrumentationConfig = {}) { - super(PACKAGE_NAME, SDK_VERSION, config); - } - - public init(): InstrumentationNodeModuleDefinition { - const module = new InstrumentationNodeModuleDefinition(MODULE_NAME, SUPPORTED_VERSIONS); - - module.files.push( - this._getClientNodeModuleFileInstrumentation('src'), - this._getClientNodeModuleFileInstrumentation('lib'), - this._getRunnerNodeModuleFileInstrumentation('src'), - this._getRunnerNodeModuleFileInstrumentation('lib'), - this._getRunnerNodeModuleFileInstrumentation('lib/execution'), - ); - - return module; - } - - private _getRunnerNodeModuleFileInstrumentation(basePath: string): InstrumentationNodeModuleFile { - return new InstrumentationNodeModuleFile( - `knex/${basePath}/runner.js`, - SUPPORTED_VERSIONS, - (Runner: any, moduleVersion?: string) => { - this._ensureWrapped(Runner.prototype, 'query', this._createQueryWrapper(moduleVersion)); - return Runner; - }, - (Runner: any) => { - this._unwrap(Runner.prototype, 'query'); - return Runner; - }, - ); - } - - private _getClientNodeModuleFileInstrumentation(basePath: string): InstrumentationNodeModuleFile { - return new InstrumentationNodeModuleFile( - `knex/${basePath}/client.js`, - SUPPORTED_VERSIONS, - (Client: any) => { - this._ensureWrapped(Client.prototype, 'queryBuilder', this._storeContext.bind(this)); - this._ensureWrapped(Client.prototype, 'schemaBuilder', this._storeContext.bind(this)); - this._ensureWrapped(Client.prototype, 'raw', this._storeContext.bind(this)); - return Client; - }, - (Client: any) => { - this._unwrap(Client.prototype, 'queryBuilder'); - this._unwrap(Client.prototype, 'schemaBuilder'); - this._unwrap(Client.prototype, 'raw'); - return Client; - }, - ); - } - - private _createQueryWrapper(moduleVersion?: string) { - return function wrapQuery(original: (...args: any[]) => any) { - return function wrapped_logging_method(this: any, query: any) { - const config = this.client.config; - - const table = utils.extractTableName(this.builder); - const operation = query?.method; - const connectionString = config?.connection?.connectionString; - const name = - config?.connection?.filename || - config?.connection?.database || - utils.extractDatabaseFromConnectionString(connectionString); - - const attributes: SpanAttributes = { - [SENTRY_KIND]: 'client', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, - 'knex.version': moduleVersion, - [DB_SYSTEM]: utils.mapSystem(this.client.driverName), - [ATTR_DB_SQL_TABLE]: table, - [DB_OPERATION]: operation, - [DB_USER]: config?.connection?.user, - [DB_NAME]: name, - [NET_PEER_NAME]: config?.connection?.host ?? utils.extractHostFromConnectionString(connectionString), - [NET_PEER_PORT]: config?.connection?.port ?? utils.extractPortFromConnectionString(connectionString), - [NET_TRANSPORT]: config?.connection?.filename === ':memory:' ? 'inproc' : undefined, - [DB_STATEMENT]: utils.limitLength(query?.sql, MAX_QUERY_LENGTH), - }; - - // The query builder captures the span active when it was created (see `_storeContext`). - // `onlyIfParent` ensures we only instrument queries that run as part of an existing trace. - const parentSpan: Span | undefined = this.builder[parentSpanSymbol] || getActiveSpan(); - - const args = arguments; - return startSpan( - { - name: utils.getName(name, operation, table), - attributes, - parentSpan, - onlyIfParent: true, - }, - span => - // `Runner.query` returns a real, already-executing Promise, so it is safe to let - // `startSpan` await it and auto-end the span. - original.apply(this, args).catch((err: any) => { - const formatter = utils.getFormatter(this); - const fullQuery = formatter(query.sql, query.bindings || []); - const message = err.message.replace(`${fullQuery} - `, ''); - span.setStatus({ code: SPAN_STATUS_ERROR, message }); - throw err; - }), - ); - }; - }; - } - - private _storeContext(original: (...args: any[]) => any) { - return function wrapped_logging_method(this: any) { - const builder = original.apply(this, arguments); - // Capture the span that is active when the query builder is created. The query often executes - // in a different async context, so we reuse this span as the parent when the query runs. - Object.defineProperty(builder, parentSpanSymbol, { - value: getActiveSpan(), - }); - return builder; - }; - } - - private _ensureWrapped(obj: any, methodName: string, wrapper: (original: any) => any): void { - if (isWrapped(obj[methodName])) { - this._unwrap(obj, methodName); - } - this._wrap(obj, methodName, wrapper); - } -} diff --git a/packages/node/src/integrations/tracing/knex/vendored/semconv.ts b/packages/node/src/integrations/tracing/knex/vendored/semconv.ts deleted file mode 100644 index 3cbb5a94d7be..000000000000 --- a/packages/node/src/integrations/tracing/knex/vendored/semconv.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - * - * NOTICE from the Sentry authors: - * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-knex - * - Upstream version: @opentelemetry/instrumentation-knex@0.62.0 - */ - -/** - * @deprecated Replaced by `db.collection.name`. - */ -export const ATTR_DB_SQL_TABLE = 'db.sql.table' as const; - -export const DB_SYSTEM_NAME_VALUE_SQLITE = 'sqlite' as const; - -export const DB_SYSTEM_NAME_VALUE_POSTGRESQL = 'postgresql' as const; diff --git a/packages/node/src/integrations/tracing/knex/vendored/utils.ts b/packages/node/src/integrations/tracing/knex/vendored/utils.ts deleted file mode 100644 index d60013963856..000000000000 --- a/packages/node/src/integrations/tracing/knex/vendored/utils.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - * - * NOTICE from the Sentry authors: - * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/15ef7506553f631ea4181391e0c5725a56f0d082/packages/instrumentation-knex - * - Upstream version: @opentelemetry/instrumentation-knex@0.62.0 - * - Refactored to use Sentry's span APIs instead of OpenTelemetry tracing APIs - */ - -import { DB_SYSTEM_NAME_VALUE_POSTGRESQL, DB_SYSTEM_NAME_VALUE_SQLITE } from './semconv'; - -export const getFormatter = (runner: any) => { - if (runner) { - if (runner.client) { - if (runner.client._formatQuery) { - return runner.client._formatQuery.bind(runner.client); - } else if (runner.client.SqlString) { - return runner.client.SqlString.format.bind(runner.client.SqlString); - } - } - if (runner.builder) { - return runner.builder.toString.bind(runner.builder); - } - } - return () => ''; -}; - -const systemMap = new Map([ - ['sqlite3', DB_SYSTEM_NAME_VALUE_SQLITE], - ['pg', DB_SYSTEM_NAME_VALUE_POSTGRESQL], -]); - -export const mapSystem = (knexSystem: string) => { - return systemMap.get(knexSystem) || knexSystem; -}; - -export const getName = (db: string, operation?: string, table?: string) => { - if (operation) { - if (table) { - return `${operation} ${db}.${table}`; - } - return `${operation} ${db}`; - } - return db; -}; - -export const limitLength = (str: string, maxLength: number) => { - if (typeof str === 'string' && typeof maxLength === 'number' && 0 < maxLength && maxLength < str.length) { - return `${str.substring(0, maxLength)}..`; - } - return str; -}; - -export const extractDatabaseFromConnectionString = (connectionString?: string): string | undefined => { - if (!connectionString) return undefined; - try { - const db = new URL(connectionString).pathname?.replace(/^\//, ''); - return db || undefined; - } catch { - return undefined; - } -}; - -export const extractHostFromConnectionString = (connectionString?: string): string | undefined => { - if (!connectionString) return undefined; - try { - return new URL(connectionString).hostname || undefined; - } catch { - return undefined; - } -}; - -export const extractPortFromConnectionString = (connectionString?: string): number | undefined => { - if (!connectionString) return undefined; - try { - const port = new URL(connectionString).port; - return port ? parseInt(port, 10) : undefined; - } catch { - return undefined; - } -}; - -export const extractTableName = (builder: any): string => { - const table = builder?._single?.table; - if (typeof table === 'object') { - return extractTableName(table); - } - return table; -};