Skip to content

Commit e3cc97a

Browse files
committed
ref(node): Remove remaining OTel tracing APIs from knex instrumentation
Replace api.context/api.trace parent detection with getActiveSpan + startSpan({ parentSpan, onlyIfParent }), and inline the postgresql semconv constant locally.
1 parent a32abea commit e3cc97a

3 files changed

Lines changed: 38 additions & 34 deletions

File tree

packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@
2020
* - Refactored to use Sentry's span APIs instead of OpenTelemetry tracing APIs
2121
*/
2222

23-
import * as api from '@opentelemetry/api';
23+
import { SpanKind } from '@opentelemetry/api';
2424
import type { InstrumentationConfig } from '@opentelemetry/instrumentation';
2525
import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation';
26-
import type { SpanAttributes } from '@sentry/core';
27-
import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_STATUS_ERROR, startSpan } from '@sentry/core';
26+
import type { Span, SpanAttributes } from '@sentry/core';
27+
import {
28+
getActiveSpan,
29+
SDK_VERSION,
30+
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
31+
SPAN_STATUS_ERROR,
32+
startSpan,
33+
} from '@sentry/core';
2834
import { InstrumentationNodeModuleFile } from '../../InstrumentationNodeModuleFile';
2935
import {
3036
ATTR_DB_NAME,
@@ -56,7 +62,7 @@ const SUPPORTED_VERSIONS = [
5662
// Max length of the query text captured in the `db.statement` attribute; ".." is appended when truncated.
5763
const MAX_QUERY_LENGTH = 1022;
5864

59-
const contextSymbol = Symbol('opentelemetry.instrumentation-knex.context');
65+
const parentSpanSymbol = Symbol('sentry.instrumentation-knex.parent-span');
6066

6167
export class KnexInstrumentation extends InstrumentationBase<InstrumentationConfig> {
6268
public constructor(config: InstrumentationConfig = {}) {
@@ -138,34 +144,29 @@ export class KnexInstrumentation extends InstrumentationBase<InstrumentationConf
138144
[ATTR_DB_STATEMENT]: utils.limitLength(query?.sql, MAX_QUERY_LENGTH),
139145
};
140146

141-
// The query builder captures the context active when it was created (see `_storeContext`).
142-
// We only instrument queries that run as part of an existing trace.
143-
const parentContext = this.builder[contextSymbol] || api.context.active();
144-
const parentSpan = api.trace.getSpan(parentContext);
145-
const hasActiveParent = parentSpan && api.trace.isSpanContextValid(parentSpan.spanContext());
146-
if (!hasActiveParent) {
147-
return original.bind(this)(...arguments);
148-
}
147+
// The query builder captures the span active when it was created (see `_storeContext`).
148+
// `onlyIfParent` ensures we only instrument queries that run as part of an existing trace.
149+
const parentSpan: Span | undefined = this.builder[parentSpanSymbol] || getActiveSpan();
149150

150151
const args = arguments;
151-
return api.context.with(parentContext, () =>
152-
startSpan(
153-
{
154-
name: utils.getName(name, operation, table),
155-
kind: api.SpanKind.CLIENT,
156-
attributes,
157-
},
158-
span =>
159-
// `Runner.query` returns a real, already-executing Promise, so it is safe to let
160-
// `startSpan` await it and auto-end the span.
161-
original.apply(this, args).catch((err: any) => {
162-
const formatter = utils.getFormatter(this);
163-
const fullQuery = formatter(query.sql, query.bindings || []);
164-
const message = err.message.replace(`${fullQuery} - `, '');
165-
span.setStatus({ code: SPAN_STATUS_ERROR, message });
166-
throw err;
167-
}),
168-
),
152+
return startSpan(
153+
{
154+
name: utils.getName(name, operation, table),
155+
kind: SpanKind.CLIENT,
156+
attributes,
157+
parentSpan,
158+
onlyIfParent: true,
159+
},
160+
span =>
161+
// `Runner.query` returns a real, already-executing Promise, so it is safe to let
162+
// `startSpan` await it and auto-end the span.
163+
original.apply(this, args).catch((err: any) => {
164+
const formatter = utils.getFormatter(this);
165+
const fullQuery = formatter(query.sql, query.bindings || []);
166+
const message = err.message.replace(`${fullQuery} - `, '');
167+
span.setStatus({ code: SPAN_STATUS_ERROR, message });
168+
throw err;
169+
}),
169170
);
170171
};
171172
};
@@ -174,8 +175,10 @@ export class KnexInstrumentation extends InstrumentationBase<InstrumentationConf
174175
private _storeContext(original: (...args: any[]) => any) {
175176
return function wrapped_logging_method(this: any) {
176177
const builder = original.apply(this, arguments);
177-
Object.defineProperty(builder, contextSymbol, {
178-
value: api.context.active(),
178+
// Capture the span that is active when the query builder is created. The query often executes
179+
// in a different async context, so we reuse this span as the parent when the query runs.
180+
Object.defineProperty(builder, parentSpanSymbol, {
181+
value: getActiveSpan(),
179182
});
180183
return builder;
181184
};

packages/node/src/integrations/tracing/knex/vendored/semconv.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,5 @@ export const ATTR_NET_PEER_PORT = 'net.peer.port' as const;
6464
export const ATTR_NET_TRANSPORT = 'net.transport' as const;
6565

6666
export const DB_SYSTEM_NAME_VALUE_SQLITE = 'sqlite' as const;
67+
68+
export const DB_SYSTEM_NAME_VALUE_POSTGRESQL = 'postgresql' as const;

packages/node/src/integrations/tracing/knex/vendored/utils.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
* - Refactored to use Sentry's span APIs instead of OpenTelemetry tracing APIs
2020
*/
2121

22-
import { DB_SYSTEM_NAME_VALUE_POSTGRESQL } from '@opentelemetry/semantic-conventions';
23-
import { DB_SYSTEM_NAME_VALUE_SQLITE } from './semconv';
22+
import { DB_SYSTEM_NAME_VALUE_POSTGRESQL, DB_SYSTEM_NAME_VALUE_SQLITE } from './semconv';
2423

2524
export const getFormatter = (runner: any) => {
2625
if (runner) {

0 commit comments

Comments
 (0)