From 338db8b5a2da28c540ca87331c967bddce8075d5 Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Fri, 22 May 2026 14:34:12 +0200 Subject: [PATCH 1/2] ref(node): Vendor `@opentelemetry/sql-common` Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/node/package.json | 1 - .../mysql2/vendored/instrumentation.ts | 2 +- .../postgres/vendored/instrumentation.ts | 2 +- .../integrations/tracing/utils/sql-common.ts | 83 +++++++++++++++++++ yarn.lock | 7 -- 5 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 packages/node/src/integrations/tracing/utils/sql-common.ts diff --git a/packages/node/package.json b/packages/node/package.json index 585d427bba8b..acd32ed24602 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -68,7 +68,6 @@ "@opentelemetry/api": "^1.9.1", "@opentelemetry/core": "^2.6.1", "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/sql-common": "^0.41.2", "@opentelemetry/sdk-trace-base": "^2.6.1", "@opentelemetry/semantic-conventions": "^1.40.0", "@sentry/core": "10.53.1", diff --git a/packages/node/src/integrations/tracing/mysql2/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/mysql2/vendored/instrumentation.ts index 00185eca1115..a6f99fd61a27 100644 --- a/packages/node/src/integrations/tracing/mysql2/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/mysql2/vendored/instrumentation.ts @@ -33,7 +33,7 @@ import { semconvStabilityFromStr, } from '@opentelemetry/instrumentation'; import { DB_SYSTEM_VALUE_MYSQL, ATTR_DB_STATEMENT, ATTR_DB_SYSTEM } from './semconv'; -import { addSqlCommenterComment } from '@opentelemetry/sql-common'; +import { addSqlCommenterComment } from '../../utils/sql-common'; import type { Connection, Query, QueryOptions, QueryError, FieldPacket, FormatFunction } from './mysql2-types'; import { MySQL2InstrumentationConfig } from './types'; import { getConnectionAttributes, getConnectionPrototypeToInstrument, getQueryText, getSpanName, once } from './utils'; diff --git a/packages/node/src/integrations/tracing/postgres/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/postgres/vendored/instrumentation.ts index 70a6ca5797f3..8fd07288368e 100644 --- a/packages/node/src/integrations/tracing/postgres/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/postgres/vendored/instrumentation.ts @@ -53,7 +53,7 @@ import { } from './internal-types'; import { PgInstrumentationConfig } from './types'; import * as utils from './utils'; -import { addSqlCommenterComment } from '@opentelemetry/sql-common'; +import { addSqlCommenterComment } from '../../utils/sql-common'; import { SDK_VERSION } from '@sentry/core'; const PACKAGE_NAME = '@sentry/instrumentation-pg'; import { SpanNames } from './enums/SpanNames'; diff --git a/packages/node/src/integrations/tracing/utils/sql-common.ts b/packages/node/src/integrations/tracing/utils/sql-common.ts new file mode 100644 index 000000000000..a230fdff9195 --- /dev/null +++ b/packages/node/src/integrations/tracing/utils/sql-common.ts @@ -0,0 +1,83 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * NOTICE from the Sentry authors: + * - Vendored from: https://github.com/open-telemetry/opentelemetry-js-contrib/tree/5a5918fd4f9f16b14c9ef4d3de08ab98c20e5b46/packages/sql-common + * - Upstream version: @opentelemetry/sql-common@0.41.2 + */ + +/* eslint-disable */ + +import { trace, Span, ROOT_CONTEXT, defaultTextMapSetter } from '@opentelemetry/api'; +import { W3CTraceContextPropagator } from '@opentelemetry/core'; + +// NOTE: This function currently is returning false-positives +// in cases where comment characters appear in string literals +// ("SELECT '-- not a comment';" would return true, although has no comment) +function hasValidSqlComment(query: string): boolean { + const indexOpeningDashDashComment = query.indexOf('--'); + if (indexOpeningDashDashComment >= 0) { + return true; + } + + const indexOpeningSlashComment = query.indexOf('/*'); + if (indexOpeningSlashComment < 0) { + return false; + } + + const indexClosingSlashComment = query.indexOf('*/'); + return indexOpeningDashDashComment < indexClosingSlashComment; +} + +// sqlcommenter specification (https://google.github.io/sqlcommenter/spec/#value-serialization) +// expects us to URL encode based on the RFC 3986 spec (https://en.wikipedia.org/wiki/Percent-encoding), +// but encodeURIComponent does not handle some characters correctly (! ' ( ) *), +// which means we need special handling for this +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent +function fixedEncodeURIComponent(str: string) { + return encodeURIComponent(str).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`); +} + +export function addSqlCommenterComment(span: Span, query: string): string { + if (typeof query !== 'string' || query.length === 0) { + return query; + } + + // As per sqlcommenter spec we shall not add a comment if there already is a comment + // in the query + if (hasValidSqlComment(query)) { + return query; + } + + const propagator = new W3CTraceContextPropagator(); + const headers: { [key: string]: string } = {}; + propagator.inject(trace.setSpan(ROOT_CONTEXT, span), headers, defaultTextMapSetter); + + // sqlcommenter spec requires keys in the comment to be sorted lexicographically + const sortedKeys = Object.keys(headers).sort(); + + if (sortedKeys.length === 0) { + return query; + } + + const commentString = sortedKeys + .map(key => { + const encodedValue = fixedEncodeURIComponent(headers[key]!); + return `${key}='${encodedValue}'`; + }) + .join(','); + + return `${query} /*${commentString}*/`; +} diff --git a/yarn.lock b/yarn.lock index 6e2a62a0c379..8ac640965c28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6114,13 +6114,6 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.40.0.tgz#10b2944ca559386590683392022a897eefd011d3" integrity sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw== -"@opentelemetry/sql-common@^0.41.2": - version "0.41.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz#7f4a14166cfd6c9ffe89096db1cc75eaf6443b19" - integrity sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ== - dependencies: - "@opentelemetry/core" "^2.0.0" - "@oxc-parser/binding-android-arm64@0.76.0": version "0.76.0" resolved "https://registry.yarnpkg.com/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.76.0.tgz#2bf8524add42f7a399ea0da9ae8e764bb9aeb61b" From 5ea2efe554fb9dd1ec2536be81c7a764a9ec446e Mon Sep 17 00:00:00 2001 From: Nicolas Hrubec Date: Fri, 22 May 2026 16:40:29 +0200 Subject: [PATCH 2/2] fix(node): Update yarn.lock after rebase on develop Co-Authored-By: Claude Opus 4.6 (1M context) --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 8ac640965c28..dabaefa72272 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6016,7 +6016,7 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.1.tgz#c1b0346de336ba55af2d5a7970882037baedec05" integrity sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q== -"@opentelemetry/core@2.6.1", "@opentelemetry/core@^2.0.0", "@opentelemetry/core@^2.6.1": +"@opentelemetry/core@2.6.1", "@opentelemetry/core@^2.6.1": version "2.6.1" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-2.6.1.tgz#a59d22a9ae3be80bb41b280bbbe1fe9fbdb6c2a5" integrity sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==