From 2172d76e86d47de6a8579eced0c9e817a885102a Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 23 Jul 2026 09:28:18 +0200 Subject: [PATCH 1/7] feat(core): Remove `kind` for spans, move to `sentry.kind` attribute --- .../aws-integration-streamed/test.ts | 8 ++-- .../aws-serverless/aws-integration/test.ts | 8 ++-- .../suites/tracing/amqplib/test.ts | 6 +-- .../suites/tracing/dataloader/test.ts | 4 +- .../fetch-strip-query/test.ts | 2 +- .../http-strip-query/test.ts | 2 +- .../suites/tracing/httpIntegration/test.ts | 4 +- .../suites/tracing/kafkajs/test.ts | 6 +-- .../suites/tracing/mongodb/test.ts | 12 +++--- .../suites/tracing/mysql/test.ts | 4 +- .../suites/tracing/postgres-streamed/test.ts | 4 +- .../suites/tracing/prisma-orm-v5/test.ts | 6 +-- .../suites/tracing/prisma-orm-v6/test.ts | 4 +- .../src/integration/aws/vendored/aws-sdk.ts | 15 +++++-- .../aws/vendored/services/ServiceExtension.ts | 3 +- .../aws/vendored/services/dynamodb.ts | 4 +- .../aws/vendored/services/kinesis.ts | 4 +- .../aws/vendored/services/lambda.ts | 3 +- .../integration/aws/vendored/services/s3.ts | 4 +- .../aws/vendored/services/secretsmanager.ts | 4 +- .../integration/aws/vendored/services/sns.ts | 9 ++--- .../integration/aws/vendored/services/sqs.ts | 10 ++--- .../aws/vendored/services/stepfunctions.ts | 4 +- .../aws-serverless/src/requestSpanOptions.ts | 6 +-- packages/core/src/client.ts | 8 +--- .../http/get-outgoing-span-data.ts | 2 +- .../integrations/http/server-subscription.ts | 9 +---- packages/core/src/shared-exports.ts | 4 +- packages/core/src/spanKind.ts | 40 ++++++------------- .../core/src/tracing/spans/captureSpan.ts | 6 +-- packages/core/src/types/span.ts | 2 + packages/core/src/types/startSpanOptions.ts | 15 ------- .../http/get-outgoing-span-data.test.ts | 4 +- .../http/server-subscription.test.ts | 2 +- packages/core/test/lib/spanKind.test.ts | 16 +++----- packages/deno/src/opentelemetry/tracer.ts | 32 +-------------- .../http/httpServerSpansIntegration.ts | 4 +- .../node-fetch/undici-instrumentation.ts | 4 +- .../tracing/amqplib/vendored/utils.ts | 7 ++-- .../dataloader/vendored/instrumentation.ts | 20 ++++------ .../firebase/otel/patches/firestore.ts | 5 ++- .../firebase/otel/patches/functions.ts | 4 +- .../tracing/kafka/vendored/utils.ts | 6 +-- .../tracing/knex/vendored/instrumentation.ts | 4 +- .../tracing/mysql/vendored/instrumentation.ts | 4 +- .../mysql2/vendored/instrumentation.ts | 12 ++---- .../postgres/vendored/instrumentation.ts | 22 +++++----- .../tracing/postgres/vendored/utils.ts | 11 ++--- .../redis/vendored/ioredis-instrumentation.ts | 9 +++-- .../redis/vendored/redis-instrumentation.ts | 8 ++-- .../tedious/vendored/instrumentation.ts | 4 +- .../opentelemetry/src/applyOtelSpanData.ts | 24 +++-------- packages/opentelemetry/src/exports.ts | 2 - packages/opentelemetry/src/sampler.ts | 8 +--- packages/opentelemetry/src/spanExporter.ts | 3 +- packages/opentelemetry/src/tracer.ts | 12 ++++-- .../src/utils/backfillStreamedSpanData.ts | 13 +----- .../opentelemetry/src/utils/getSpanKind.ts | 17 -------- .../src/utils/parseSpanDescription.ts | 24 +++++------ packages/opentelemetry/test/trace.test.ts | 9 ++--- .../opentelemetry/test/tracerProvider.test.ts | 2 +- .../test/utils/getSpanKind.test.ts | 11 ----- .../server/integrations/tracing-channel.ts | 4 +- .../remix/test/server/tracing-channel.test.ts | 2 +- .../integrations/tracing-channel/amqplib.ts | 6 +-- .../tracing-channel/aws-sdk/index.ts | 4 +- .../aws-sdk/services/dynamodb.ts | 2 - .../aws-sdk/services/kinesis.ts | 2 - .../aws-sdk/services/lambda.ts | 3 +- .../tracing-channel/aws-sdk/services/s3.ts | 2 - .../aws-sdk/services/secretsmanager.ts | 2 - .../tracing-channel/aws-sdk/services/sns.ts | 10 ++--- .../tracing-channel/aws-sdk/services/sqs.ts | 12 +++--- .../aws-sdk/services/stepfunctions.ts | 2 - .../tracing-channel/aws-sdk/types.ts | 3 -- .../tracing-channel/dataloader.ts | 11 +++-- .../tracing-channel/firebase/firestore.ts | 5 ++- .../tracing-channel/firebase/functions.ts | 5 +-- .../tracing-channel/kafkajs/spans.ts | 6 +-- .../src/integrations/tracing-channel/knex.ts | 4 +- .../src/integrations/tracing-channel/mysql.ts | 4 +- .../integrations/tracing-channel/mysql2.ts | 4 +- .../tracing-channel/postgres-js.ts | 7 ++-- .../integrations/tracing-channel/postgres.ts | 12 ++++-- .../src/integrations/tracing-channel/redis.ts | 9 ++--- .../integrations/tracing-channel/tedious.ts | 4 +- .../server-utils/src/mongodb/mongodb-span.ts | 9 +++-- .../src/mongoose/mongoose-legacy-span.ts | 5 ++- .../server-utils/src/prisma/tracing-helper.ts | 15 ++++--- packages/server-utils/src/prisma/types.ts | 4 +- 90 files changed, 265 insertions(+), 418 deletions(-) delete mode 100644 packages/opentelemetry/src/utils/getSpanKind.ts delete mode 100644 packages/opentelemetry/test/utils/getSpanKind.test.ts diff --git a/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration-streamed/test.ts b/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration-streamed/test.ts index a5e4ea13011a..0b2e1a6379aa 100644 --- a/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration-streamed/test.ts @@ -61,7 +61,7 @@ function assertAwsServiceSpans(spanCcontainer: SerializedStreamedSpanContainer): 'rpc.service': { value: 'S3', type: 'string' }, 'cloud.region': { value: 'us-east-1', type: 'string' }, 'aws.s3.bucket': { value: 'ot-demo-test', type: 'string' }, - 'otel.kind': { value: 'CLIENT', type: 'string' }, + 'sentry.kind': { value: 'client', type: 'string' }, }), }); @@ -129,7 +129,7 @@ function assertAwsServiceSpans(spanCcontainer: SerializedStreamedSpanContainer): 'messaging.destination.name': { value: 'my-queue', type: 'string' }, 'url.full': { value: 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue', type: 'string' }, 'messaging.message.id': { value: 'message-id-1', type: 'string' }, - 'otel.kind': { value: 'PRODUCER', type: 'string' }, + 'sentry.kind': { value: 'producer', type: 'string' }, }), }); @@ -141,7 +141,7 @@ function assertAwsServiceSpans(spanCcontainer: SerializedStreamedSpanContainer): 'messaging.system': { value: 'aws_sqs', type: 'string' }, 'messaging.operation.type': { value: 'receive', type: 'string' }, 'messaging.batch.message_count': { value: 1, type: 'integer' }, - 'otel.kind': { value: 'CONSUMER', type: 'string' }, + 'sentry.kind': { value: 'consumer', type: 'string' }, }), }); @@ -154,7 +154,7 @@ function assertAwsServiceSpans(spanCcontainer: SerializedStreamedSpanContainer): 'messaging.system': { value: 'aws.sns', type: 'string' }, 'messaging.destination': { value: 'my-topic', type: 'string' }, 'aws.sns.topic.arn': { value: 'arn:aws:sns:us-east-1:123456789012:my-topic', type: 'string' }, - 'otel.kind': { value: 'PRODUCER', type: 'string' }, + 'sentry.kind': { value: 'producer', type: 'string' }, }), }); diff --git a/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/test.ts b/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/test.ts index 22d84e5ffb3a..fb4f84b7372f 100644 --- a/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/test.ts +++ b/dev-packages/node-integration-tests/suites/aws-serverless/aws-integration/test.ts @@ -56,7 +56,7 @@ function assertAwsServiceSpans(transaction: TransactionEvent): void { 'rpc.service': 'S3', 'cloud.region': 'us-east-1', 'aws.s3.bucket': 'ot-demo-test', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }), }); @@ -119,7 +119,7 @@ function assertAwsServiceSpans(transaction: TransactionEvent): void { 'messaging.destination.name': 'my-queue', 'url.full': 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue', 'messaging.message.id': 'message-id-1', - 'otel.kind': 'PRODUCER', + 'sentry.kind': 'producer', }), }); @@ -133,7 +133,7 @@ function assertAwsServiceSpans(transaction: TransactionEvent): void { 'messaging.system': 'aws_sqs', 'messaging.operation.type': 'receive', 'messaging.batch.message_count': 1, - 'otel.kind': 'CONSUMER', + 'sentry.kind': 'consumer', }), }); @@ -148,7 +148,7 @@ function assertAwsServiceSpans(transaction: TransactionEvent): void { 'messaging.system': 'aws.sns', 'messaging.destination': 'my-topic', 'aws.sns.topic.arn': 'arn:aws:sns:us-east-1:123456789012:my-topic', - 'otel.kind': 'PRODUCER', + 'sentry.kind': 'producer', }), }); diff --git a/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts b/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts index de30dd3f6bd7..f614652ecb6b 100644 --- a/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/amqplib/test.ts @@ -41,7 +41,7 @@ const expectedProducerSpan = (routingKey: string) => 'url.full': 'amqp://sentry:***@localhost:5672/', } : {}), - 'otel.kind': 'PRODUCER', + 'sentry.kind': 'producer', 'sentry.op': 'message', 'sentry.origin': PUBLISHER_ORIGIN, }), @@ -66,7 +66,7 @@ const EXPECTED_MESSAGE_SPAN_CONSUMER = expect.objectContaining({ 'messaging.operation.type': 'process', } : {}), - 'otel.kind': 'CONSUMER', + 'sentry.kind': 'consumer', 'sentry.op': 'message', 'sentry.origin': CONSUMER_ORIGIN, }), @@ -163,7 +163,7 @@ describeWithDockerCompose('amqplib auto-instrumentation', { workingDirectory: [_ status: 'internal_error', data: expect.objectContaining({ 'messaging.system': 'rabbitmq', - 'otel.kind': 'CONSUMER', + 'sentry.kind': 'consumer', 'sentry.op': 'message', 'sentry.origin': CONSUMER_ORIGIN, }), diff --git a/dev-packages/node-integration-tests/suites/tracing/dataloader/test.ts b/dev-packages/node-integration-tests/suites/tracing/dataloader/test.ts index dfad54dc5516..e7e4b8f73f3a 100644 --- a/dev-packages/node-integration-tests/suites/tracing/dataloader/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/dataloader/test.ts @@ -31,7 +31,7 @@ describe('dataloader auto-instrumentation', () => { expect(loadSpan?.data?.['sentry.op']).toBe(CACHE_GET_OP); expect(loadSpan?.data?.['cache.key']).toEqual(['user-1']); // A direct operation is a client call; the deferred `batch` below gets no kind - expect(loadSpan?.data?.['otel.kind']).toBe('CLIENT'); + expect(loadSpan?.data?.['sentry.kind']).toBe('client'); const batchSpan = spans.find(span => span.description === 'dataloader.batch'); expect(batchSpan).toBeDefined(); @@ -39,7 +39,7 @@ describe('dataloader auto-instrumentation', () => { expect(batchSpan?.origin).toBe(ORIGIN); expect(batchSpan?.status).toBe('ok'); expect(batchSpan?.data?.['cache.key']).toEqual(['user-1']); - expect(batchSpan?.data?.['otel.kind']).toBeUndefined(); + expect(batchSpan?.data?.['sentry.kind']).toBeUndefined(); // The batch span links back to the load span that triggered it expect(batchSpan?.links).toEqual([ diff --git a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts index 0ab411783aa2..33a5c30bb4a6 100644 --- a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/fetch-strip-query/test.ts @@ -37,7 +37,7 @@ describe('outgoing fetch spans - strip query', () => { 'http.response.status_code': 200, 'network.peer.address': '::1', 'network.peer.port': expect.any(Number), - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'server.port': expect.any(Number), 'user_agent.original': 'node', 'sentry.op': 'http.client', diff --git a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts index 6153a01c7e7f..6a65673ca7da 100644 --- a/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/http-client-spans/http-strip-query/test.ts @@ -41,7 +41,7 @@ describe('outgoing http spans - strip query', () => { 'net.peer.name': 'localhost', 'net.peer.port': expect.any(Number), 'net.transport': 'ip_tcp', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', }, diff --git a/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts b/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts index 69740b8bdaf4..f5705ac88f81 100644 --- a/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/httpIntegration/test.ts @@ -125,7 +125,7 @@ describe('httpIntegration', () => { 'net.peer.ip': '::1', 'net.peer.port': expect.any(Number), 'net.transport': 'ip_tcp', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, @@ -169,7 +169,7 @@ describe('httpIntegration', () => { 'net.peer.ip': '::1', 'net.peer.port': expect.any(Number), 'net.transport': 'ip_tcp', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, diff --git a/dev-packages/node-integration-tests/suites/tracing/kafkajs/test.ts b/dev-packages/node-integration-tests/suites/tracing/kafkajs/test.ts index 799c73560c17..e7bf29cab17b 100644 --- a/dev-packages/node-integration-tests/suites/tracing/kafkajs/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/kafkajs/test.ts @@ -58,7 +58,7 @@ describeWithDockerCompose('kafkajs', { workingDirectory: [__dirname] }, () => { data: expect.objectContaining({ 'messaging.system': 'kafka', 'messaging.destination.name': 'test-topic', - 'otel.kind': 'PRODUCER', + 'sentry.kind': 'producer', 'sentry.op': 'message', 'sentry.origin': producerOrigin, }), @@ -72,7 +72,7 @@ describeWithDockerCompose('kafkajs', { workingDirectory: [__dirname] }, () => { data: expect.objectContaining({ 'messaging.system': 'kafka', 'messaging.destination.name': 'test-topic', - 'otel.kind': 'CONSUMER', + 'sentry.kind': 'consumer', 'sentry.op': 'message', 'sentry.origin': consumerOrigin, }), @@ -98,7 +98,7 @@ describeWithDockerCompose('kafkajs', { workingDirectory: [__dirname] }, () => { data: expect.objectContaining({ 'messaging.system': 'kafka', 'messaging.destination.name': 'invalid topic name', - 'otel.kind': 'PRODUCER', + 'sentry.kind': 'producer', 'sentry.op': 'message', 'sentry.origin': producerOrigin, 'error.type': 'KafkaJSNonRetriableError', diff --git a/dev-packages/node-integration-tests/suites/tracing/mongodb/test.ts b/dev-packages/node-integration-tests/suites/tracing/mongodb/test.ts index 5c88a8de18da..06d9f17a7b61 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mongodb/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mongodb/test.ts @@ -33,7 +33,7 @@ describe('MongoDB auto-instrumentation', () => { 'net.peer.name': expect.any(String), 'net.peer.port': expect.any(Number), 'db.statement': '{"title":"?"}', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: '{"title":"?"}', op: 'db', @@ -52,7 +52,7 @@ describe('MongoDB auto-instrumentation', () => { 'net.peer.name': expect.any(String), 'net.peer.port': expect.any(Number), 'db.statement': '{"title":"?","_id":{"_bsontype":"?","id":"?"}}', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: '{"title":"?","_id":{"_bsontype":"?","id":"?"}}', op: 'db', @@ -72,7 +72,7 @@ describe('MongoDB auto-instrumentation', () => { 'net.peer.port': expect.any(Number), 'db.statement': '{"ismaster":"?","client":{"driver":{"name":"?","version":"?"},"os":{"type":"?","name":"?","architecture":"?","version":"?"},"platform":"?"},"compression":[],"helloOk":"?"}', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: '{"ismaster":"?","client":{"driver":{"name":"?","version":"?"},"os":{"type":"?","name":"?","architecture":"?","version":"?"},"platform":"?"},"compression":[],"helloOk":"?"}', @@ -92,7 +92,7 @@ describe('MongoDB auto-instrumentation', () => { 'net.peer.name': expect.any(String), 'net.peer.port': expect.any(Number), 'db.statement': '{"title":"?"}', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: '{"title":"?"}', op: 'db', @@ -107,7 +107,7 @@ describe('MongoDB auto-instrumentation', () => { 'db.system': 'mongodb', 'db.operation': 'find', 'db.statement': '{"$thisOperatorDoesNotExist":"?"}', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }), description: '{"$thisOperatorDoesNotExist":"?"}', op: 'db', @@ -126,7 +126,7 @@ describe('MongoDB auto-instrumentation', () => { 'net.peer.name': expect.any(String), 'net.peer.port': expect.any(Number), 'db.statement': '{"endSessions":[{"id":{"_bsontype":"?","sub_type":"?","position":"?","buffer":"?"}}]}', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: '{"endSessions":[{"id":{"_bsontype":"?","sub_type":"?","position":"?","buffer":"?"}}]}', op: 'db', diff --git a/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts b/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts index 9cd0d93fca64..ddd8e0494a4d 100644 --- a/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/mysql/test.ts @@ -223,9 +223,9 @@ describe('mysql auto instrumentation', () => { type: 'integer', value: expect.any(Number), }, - 'otel.kind': { + 'sentry.kind': { type: 'string', - value: 'CLIENT', + value: 'client', }, 'sentry.environment': { type: 'string', diff --git a/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts b/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts index a0d7686e912b..0b32b7329f08 100644 --- a/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/postgres-streamed/test.ts @@ -36,9 +36,9 @@ const COMMON_DB_ATTRIBUTES = { type: 'integer', value: expect.any(Number), }, - 'otel.kind': { + 'sentry.kind': { type: 'string', - value: 'CLIENT', + value: 'client', }, 'sentry.environment': { type: 'string', diff --git a/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v5/test.ts b/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v5/test.ts index 94afb45905d4..a28ff3aa76c5 100644 --- a/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v5/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v5/test.ts @@ -76,7 +76,7 @@ function expectPrismaV5Spans(transaction: TransactionEvent): void { data: { 'db.statement': expect.stringContaining('INSERT INTO'), 'db.system': 'postgresql', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'sentry.op': 'db', 'sentry.origin': 'auto.db.otel.prisma', }, @@ -88,7 +88,7 @@ function expectPrismaV5Spans(transaction: TransactionEvent): void { data: { 'db.statement': expect.stringContaining('SELECT'), 'db.system': 'postgresql', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'sentry.op': 'db', 'sentry.origin': 'auto.db.otel.prisma', }, @@ -100,7 +100,7 @@ function expectPrismaV5Spans(transaction: TransactionEvent): void { data: { 'db.statement': expect.stringContaining('DELETE'), 'db.system': 'postgresql', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'sentry.op': 'db', 'sentry.origin': 'auto.db.otel.prisma', }, diff --git a/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v6/test.ts b/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v6/test.ts index 4516c5627508..28187d820d1a 100644 --- a/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v6/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/prisma-orm-v6/test.ts @@ -89,7 +89,7 @@ describeWithDockerCompose('Prisma ORM v6 Tests', { workingDirectory: [__dirname] 'db.query.text': 'SELECT "public"."User"."id", "public"."User"."createdAt", "public"."User"."email", "public"."User"."name" FROM "public"."User" WHERE 1=1 OFFSET $1', 'db.system': 'postgresql', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: 'SELECT "public"."User"."id", "public"."User"."createdAt", "public"."User"."email", "public"."User"."name" FROM "public"."User" WHERE 1=1 OFFSET $1', @@ -100,7 +100,7 @@ describeWithDockerCompose('Prisma ORM v6 Tests', { workingDirectory: [__dirname] 'sentry.op': 'db', 'db.query.text': 'DELETE FROM "public"."User" WHERE "public"."User"."email"::text LIKE $1', 'db.system': 'postgresql', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', }, description: 'DELETE FROM "public"."User" WHERE "public"."User"."email"::text LIKE $1', }); diff --git a/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts b/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts index b1a48514c98e..d65ebfb01233 100644 --- a/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts +++ b/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts @@ -9,7 +9,7 @@ * (https://github.com/open-telemetry/opentelemetry-js-contrib/pull/3530) */ -import { Span, SpanKind, context, trace, diag, SpanStatusCode } from '@opentelemetry/api'; +import { Span, context, trace, diag, SpanStatusCode } from '@opentelemetry/api'; import { AWS_REQUEST_EXTENDED_ID, AWS_REQUEST_ID, CLOUD_REGION } from './enums'; import { ServicesExtensions } from './services'; import { AwsSdkInstrumentationConfig, NormalizedRequest, NormalizedResponse } from './types'; @@ -35,8 +35,13 @@ import { } from './utils'; import { propwrap } from './propwrap'; import { RequestMetadata } from './services/ServiceExtension'; -import { HTTP_STATUS_CODE } from '@sentry/conventions/attributes'; -import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core'; +import { HTTP_STATUS_CODE, SENTRY_KIND } from '@sentry/conventions/attributes'; +import { + SDK_VERSION, + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + startInactiveSpan, +} from '@sentry/core'; const PACKAGE_NAME = '@sentry/instrumentation-aws-sdk'; @@ -151,9 +156,11 @@ export class AwsInstrumentation extends InstrumentationBase { /** * Register a callback to preprocess a span JSON _before_ it is passed to the `processSpan` and * `processSegmentSpan` hooks. Use this to backfill data that subsequent hooks rely on. - * The optional `hint` exposes additional context about the originating span (e.g. the OTel `spanKind`). */ - public on( - hook: 'preprocessSpan', - callback: (streamedSpanJSON: StreamedSpanJSON, hint?: { spanKind?: number }) => void, - ): () => void; + public on(hook: 'preprocessSpan', callback: (streamedSpanJSON: StreamedSpanJSON) => void): () => void; /** * Register a callback for when a span JSON is processed, to add some data to the span JSON. @@ -992,7 +988,7 @@ export abstract class Client { /** * Fire a hook event to preprocess a span JSON before the `processSpan` and `processSegmentSpan` hooks run. */ - public emit(hook: 'preprocessSpan', streamedSpanJSON: StreamedSpanJSON, hint?: { spanKind?: number }): void; + public emit(hook: 'preprocessSpan', streamedSpanJSON: StreamedSpanJSON): void; /** * Fire a hook event when a span JSON is processed, to add some data to the span JSON. diff --git a/packages/core/src/integrations/http/get-outgoing-span-data.ts b/packages/core/src/integrations/http/get-outgoing-span-data.ts index 8092bec8c5bf..a3b0705122f7 100644 --- a/packages/core/src/integrations/http/get-outgoing-span-data.ts +++ b/packages/core/src/integrations/http/get-outgoing-span-data.ts @@ -26,7 +26,7 @@ export function getOutgoingRequestSpanData(request: HttpClientRequest): StartSpa // TODO(v11): Update these to the Sentry semantic attributes for urls. // https://getsentry.github.io/sentry-conventions/attributes/ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.client', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'http.url': url, 'http.method': request.method, 'http.target': request.path || '/', diff --git a/packages/core/src/integrations/http/server-subscription.ts b/packages/core/src/integrations/http/server-subscription.ts index 7517b88509c9..95eb90ae5f92 100644 --- a/packages/core/src/integrations/http/server-subscription.ts +++ b/packages/core/src/integrations/http/server-subscription.ts @@ -38,10 +38,9 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, } from '../../semanticAttributes'; import { safeMathRandom } from '../../utils/randomSafeContext'; -import { SPAN_KIND } from '../../spanKind'; import type { SpanAttributes } from '../../types/span'; import type { SpanStatus } from '../../types/spanStatus'; -import { HTTP_URL, URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; +import { HTTP_URL, URL_FULL, URL_PATH, SENTRY_KIND } from '@sentry/conventions/attributes'; // Tree-shakable guard to remove all code related to tracing declare const __SENTRY_TRACING__: boolean; @@ -280,19 +279,15 @@ function buildServerSpanWrap( return startSpanManual( { name, - // Pass SERVER so the OTel sampler infers op='http.server' rather than - // 'http', which it does for the INTERNAL default. - kind: SPAN_KIND.SERVER, attributes: { // Sentry-specific attributes [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', + [SENTRY_KIND]: 'server', // Set http.route to the URL path as a best-effort route name. // Framework integrations (Express, etc.) update this via onSpanEnd. 'http.route': httpTargetWithoutQueryFragment, - // OTel kind (explicit attribute so it appears in span data) - 'otel.kind': 'SERVER', // Network attributes 'net.host.ip': localAddress, 'net.host.port': localPort, diff --git a/packages/core/src/shared-exports.ts b/packages/core/src/shared-exports.ts index eae0361ee6dd..4ee7ef383bd0 100644 --- a/packages/core/src/shared-exports.ts +++ b/packages/core/src/shared-exports.ts @@ -138,8 +138,8 @@ export { } from './utils/request'; export type { MaxRequestBodySize } from './utils/request'; export { DEFAULT_ENVIRONMENT, DEV_ENVIRONMENT } from './constants'; -export { SPAN_KIND, spanKindToName } from './spanKind'; -export type { SpanKindValue } from './spanKind'; +export { spanKindToName } from './spanKind'; +export type { SpanKind, SpanKindNumber } from './spanKind'; export { addBreadcrumb } from './breadcrumbs'; export { functionToStringIntegration } from './integrations/functiontostring'; // eslint-disable-next-line typescript/no-deprecated diff --git a/packages/core/src/spanKind.ts b/packages/core/src/spanKind.ts index 5a08ebadf572..10bfed2cad9b 100644 --- a/packages/core/src/spanKind.ts +++ b/packages/core/src/spanKind.ts @@ -1,36 +1,22 @@ +export type SpanKindNumber = 0 | 1 | 2 | 3 | 4; +export type SpanKind = 'server' | 'client' | 'producer' | 'consumer'; + /** - * The kind of a span, mirroring OpenTelemetry's `SpanKind` enum values. - * - * Exported as a plain const object so SDK code can set a span's kind without - * importing `@opentelemetry/api` just for the enum. The numeric values must - * stay in sync with OpenTelemetry's `SpanKind` since they are passed through to - * the underlying OTel span and sampler. + * Map of otel span kind numbers to span kind names. */ -export const SPAN_KIND = { - INTERNAL: 0, - SERVER: 1, - CLIENT: 2, - PRODUCER: 3, - CONSUMER: 4, -} as const; - -export type SpanKindValue = (typeof SPAN_KIND)[keyof typeof SPAN_KIND]; - -// Reverse of SPAN_KIND (value → name), for the `otel.kind` attribute. The numeric keys come from -// SPAN_KIND so they stay in sync; `satisfies` ensures every kind has a name. -const SPAN_KIND_NAME = { - [SPAN_KIND.INTERNAL]: 'INTERNAL', - [SPAN_KIND.SERVER]: 'SERVER', - [SPAN_KIND.CLIENT]: 'CLIENT', - [SPAN_KIND.PRODUCER]: 'PRODUCER', - [SPAN_KIND.CONSUMER]: 'CONSUMER', -} as const satisfies Record; +const SPAN_KIND_NUMBER_TO_NAME = { + [0]: undefined, + [1]: 'server', + [2]: 'client', + [3]: 'producer', + [4]: 'consumer', +} as const satisfies Record; /** * Resolve the string name of a span kind value (e.g. `1` → `'SERVER'`), mirroring the reverse * mapping of OpenTelemetry's `SpanKind` enum. Used for the `otel.kind` span attribute, so SDK * code doesn't need to import `@opentelemetry/api` just for that reverse lookup. */ -export function spanKindToName(kind: number): (typeof SPAN_KIND_NAME)[SpanKindValue] | undefined { - return SPAN_KIND_NAME[kind as SpanKindValue]; +export function spanKindToName(kind: number): SpanKind | undefined { + return SPAN_KIND_NUMBER_TO_NAME[kind as SpanKindNumber]; } diff --git a/packages/core/src/tracing/spans/captureSpan.ts b/packages/core/src/tracing/spans/captureSpan.ts index ed837cb82003..b65f85b02d46 100644 --- a/packages/core/src/tracing/spans/captureSpan.ts +++ b/packages/core/src/tracing/spans/captureSpan.ts @@ -57,13 +57,9 @@ export function captureSpan(span: Span, client: Client): SerializedStreamedSpanW applyCommonSpanAttributes(spanJSON, serializedSegmentSpan, client, finalScopeData); - // Access `kind` via duck-typing — OTel span objects have this property but it's not on Sentry's Span type. - // It is forwarded to `preprocessSpan` subscribers (e.g. the OpenTelemetry SDK backfills op/source/name from it). - const spanKind = (span as { kind?: number }).kind; - // Preprocess the span JSON before any other hooks run, so that `processSpan`/`processSegmentSpan` // subscribers (incl. integrations) and `beforeSendSpan` see fully inferred span data. - client.emit('preprocessSpan', spanJSON, { spanKind }); + client.emit('preprocessSpan', spanJSON); if (spanJSON.is_segment) { applyScopeToSegmentSpan(spanJSON, finalScopeData); diff --git a/packages/core/src/types/span.ts b/packages/core/src/types/span.ts index bcc8b4506038..02a5b175352e 100644 --- a/packages/core/src/types/span.ts +++ b/packages/core/src/types/span.ts @@ -1,4 +1,5 @@ import type { Attributes, RawAttributes } from '../attributes'; +import type { SpanKind } from '../spanKind'; import type { SpanLink, SpanLinkJSON } from './link'; import type { Measurements } from './measurement'; import type { HrTime } from './opentelemetry'; @@ -29,6 +30,7 @@ export type SpanAttributes = Partial<{ 'sentry.op': string; 'sentry.source': TransactionSource; 'sentry.sample_rate': number; + 'sentry.kind': SpanKind; }> & Record; diff --git a/packages/core/src/types/startSpanOptions.ts b/packages/core/src/types/startSpanOptions.ts index 391a4354722d..eb3aa0b53299 100644 --- a/packages/core/src/types/startSpanOptions.ts +++ b/packages/core/src/types/startSpanOptions.ts @@ -1,5 +1,4 @@ import type { Scope } from '../scope'; -import type { SpanKindValue } from '../spanKind'; import type { SpanLink } from './link'; import type { Span, SpanAttributes, SpanTimeInput } from './span'; @@ -29,20 +28,6 @@ export interface StartSpanOptions { /** An op for the span. This is a categorization for spans. */ op?: string; - /** - * The kind of the span, following OpenTelemetry's SpanKind enum. - * - 0 = INTERNAL (default) - * - 1 = SERVER - * - 2 = CLIENT - * - 3 = PRODUCER - * - 4 = CONSUMER - * - * This is used by OpenTelemetry-based SDK implementations to set the correct - * span kind on the underlying OTel span, which affects how the span is - * displayed and sampled. - */ - kind?: SpanKindValue; - /** * If provided, make the new span a child of this span. * If this is not provided, the new span will be a child of the currently active span. diff --git a/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts b/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts index fc2527ac7732..2076c9cc9d15 100644 --- a/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts +++ b/packages/core/test/lib/integrations/http/get-outgoing-span-data.test.ts @@ -54,9 +54,9 @@ describe('getOutgoingRequestSpanData', () => { expect(result.attributes!['sentry.op']).toBe('http.client'); }); - it('sets otel.kind to "CLIENT"', () => { + it('sets sentry.kind to "CLIENT"', () => { const result = getOutgoingRequestSpanData(makeMockRequest()); - expect(result.attributes!['otel.kind']).toBe('CLIENT'); + expect(result.attributes!['sentry.kind']).toBe('client'); }); it('builds the span name from method and URL', () => { diff --git a/packages/core/test/lib/integrations/http/server-subscription.test.ts b/packages/core/test/lib/integrations/http/server-subscription.test.ts index 8c1fc3594403..37e822c5fc4c 100644 --- a/packages/core/test/lib/integrations/http/server-subscription.test.ts +++ b/packages/core/test/lib/integrations/http/server-subscription.test.ts @@ -104,7 +104,7 @@ describe('getHttpServerSubscriptions', () => { 'http.response.status_code': 200, 'http.status_code': 200, 'http.target': '/users/42?foo=bar', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.server', 'sentry.source': 'url', diff --git a/packages/core/test/lib/spanKind.test.ts b/packages/core/test/lib/spanKind.test.ts index 918a31488c62..4d8505b3e559 100644 --- a/packages/core/test/lib/spanKind.test.ts +++ b/packages/core/test/lib/spanKind.test.ts @@ -1,16 +1,12 @@ import { describe, expect, it } from 'vitest'; -import { SPAN_KIND, spanKindToName } from '../../src/spanKind'; +import { spanKindToName } from '../../src/spanKind'; describe('spanKindToName', () => { it('resolves each span kind value to its name', () => { - expect(spanKindToName(SPAN_KIND.INTERNAL)).toBe('INTERNAL'); - expect(spanKindToName(SPAN_KIND.SERVER)).toBe('SERVER'); - expect(spanKindToName(SPAN_KIND.CLIENT)).toBe('CLIENT'); - expect(spanKindToName(SPAN_KIND.PRODUCER)).toBe('PRODUCER'); - expect(spanKindToName(SPAN_KIND.CONSUMER)).toBe('CONSUMER'); - }); - - it('returns undefined for an unknown kind value', () => { - expect(spanKindToName(99)).toBeUndefined(); + expect(spanKindToName(0)).toBe(undefined); + expect(spanKindToName(1)).toBe('server'); + expect(spanKindToName(2)).toBe('client'); + expect(spanKindToName(3)).toBe('producer'); + expect(spanKindToName(4)).toBe('consumer'); }); }); diff --git a/packages/deno/src/opentelemetry/tracer.ts b/packages/deno/src/opentelemetry/tracer.ts index bdd86bde6a8d..795f24eb9be4 100644 --- a/packages/deno/src/opentelemetry/tracer.ts +++ b/packages/deno/src/opentelemetry/tracer.ts @@ -1,11 +1,6 @@ import type { Context, Span, SpanOptions, Tracer, TracerProvider } from '@opentelemetry/api'; -import { SpanKind, trace } from '@opentelemetry/api'; -import { - SEMANTIC_ATTRIBUTE_SENTRY_OP, - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - startInactiveSpan, - startSpanManual, -} from '@sentry/core'; +import { trace } from '@opentelemetry/api'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan, startSpanManual } from '@sentry/core'; /** * Set up a mock OTEL tracer to allow inter-op with OpenTelemetry emitted spans. @@ -34,16 +29,12 @@ class SentryDenoTraceProvider implements TracerProvider { class SentryDenoTracer implements Tracer { public startSpan(name: string, options?: SpanOptions): Span { - // Map OpenTelemetry SpanKind to Sentry operation - const op = this._mapSpanKindToOp(options?.kind); - return startInactiveSpan({ ...options, name, attributes: { ...options?.attributes, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', - ...(op ? { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op } : {}), 'sentry.deno_tracer': true, }, }); @@ -68,16 +59,12 @@ class SentryDenoTracer implements Tracer { ): ReturnType { const opts = (typeof options === 'object' && options !== null ? options : {}) as SpanOptions; - // Map OpenTelemetry SpanKind to Sentry operation - const op = this._mapSpanKindToOp(opts.kind); - const spanOpts = { ...opts, name, attributes: { ...opts.attributes, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', - ...(op ? { [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op } : {}), 'sentry.deno_tracer': true, }, }; @@ -95,19 +82,4 @@ class SentryDenoTracer implements Tracer { // In OTEL the semantic matches `startSpanManual` because spans are not auto-ended return startSpanManual(spanOpts, callback) as ReturnType; } - - private _mapSpanKindToOp(kind?: SpanKind): string | undefined { - switch (kind) { - case SpanKind.CLIENT: - return 'http.client'; - case SpanKind.SERVER: - return 'http.server'; - case SpanKind.PRODUCER: - return 'message.produce'; - case SpanKind.CONSUMER: - return 'message.consume'; - default: - return undefined; - } - } } diff --git a/packages/node/src/integrations/http/httpServerSpansIntegration.ts b/packages/node/src/integrations/http/httpServerSpansIntegration.ts index a09a1759fd84..ce716190d78a 100644 --- a/packages/node/src/integrations/http/httpServerSpansIntegration.ts +++ b/packages/node/src/integrations/http/httpServerSpansIntegration.ts @@ -25,6 +25,7 @@ import { SENTRY_HTTP_PREFETCH, URL_FULL, URL_PATH, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import type { Event, @@ -51,7 +52,6 @@ import { bindScopeToEmitter, startInactiveSpan, withActiveSpan, - SPAN_KIND, } from '@sentry/core'; import { DEBUG_BUILD } from '../../debug-build'; import type { NodeClient } from '../../sdk/client'; @@ -168,9 +168,9 @@ const _httpServerSpansIntegration = ((options: HttpServerSpansIntegrationOptions const span = startInactiveSpan({ name: bestEffortTransactionName, - kind: SPAN_KIND.SERVER, attributes: { // Sentry specific attributes + [SENTRY_KIND]: 'server', [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.http', [SENTRY_HTTP_PREFETCH]: isKnownPrefetchRequest(request) || undefined, diff --git a/packages/node/src/integrations/node-fetch/undici-instrumentation.ts b/packages/node/src/integrations/node-fetch/undici-instrumentation.ts index 89a754b36274..5761e2d5ef8f 100644 --- a/packages/node/src/integrations/node-fetch/undici-instrumentation.ts +++ b/packages/node/src/integrations/node-fetch/undici-instrumentation.ts @@ -29,7 +29,6 @@ import { LRUMap, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, stripDataUrlContent, @@ -40,6 +39,7 @@ import { HTTP_RESPONSE_STATUS_CODE, NETWORK_PEER_ADDRESS, NETWORK_PEER_PORT, + SENTRY_KIND, SERVER_ADDRESS, SERVER_PORT, URL_FULL, @@ -218,6 +218,7 @@ function onRequestCreated(config: NodeFetchOptions, { request }: RequestMessage) const urlScheme = requestUrl.protocol.replace(':', ''); const requestMethod = getRequestMethod(request.method); const attributes: SpanAttributes = { + [SENTRY_KIND]: 'client', [HTTP_REQUEST_METHOD]: requestMethod, [ATTR_HTTP_REQUEST_METHOD_ORIGINAL]: request.method, [URL_FULL]: requestUrl.toString(), @@ -265,7 +266,6 @@ function onRequestCreated(config: NodeFetchOptions, { request }: RequestMessage) const client = getClient(); const span = startInactiveSpan({ name: requestMethod === '_OTHER' ? 'HTTP' : requestMethod, - kind: SPAN_KIND.CLIENT, attributes, onlyIfParent: !client || !hasSpanStreamingEnabled(client), }); diff --git a/packages/node/src/integrations/tracing/amqplib/vendored/utils.ts b/packages/node/src/integrations/tracing/amqplib/vendored/utils.ts index e9cc669331a3..eec57b724a8c 100644 --- a/packages/node/src/integrations/tracing/amqplib/vendored/utils.ts +++ b/packages/node/src/integrations/tracing/amqplib/vendored/utils.ts @@ -12,10 +12,9 @@ * - Replaced the OTel context-key confirm-channel marker with a synchronous flag on the channel instance */ -import { SpanKind } from '@opentelemetry/api'; import type { Span, SpanAttributes } from '@sentry/core'; import { getTraceData, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core'; -import { MESSAGING_SYSTEM, NET_PEER_NAME, NET_PEER_PORT } from '@sentry/conventions/attributes'; +import { MESSAGING_SYSTEM, NET_PEER_NAME, NET_PEER_PORT, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { Channel, ConfirmChannel, Connection, Options } from './amqplib-types'; import { ATTR_MESSAGING_CONVERSATION_ID, @@ -158,8 +157,8 @@ export function startPublishSpan( const span = startInactiveSpan({ name: `publish ${normalizedExchange}`, - kind: SpanKind.PRODUCER, attributes: { + [SENTRY_KIND]: 'producer', ...channel.connection[CONNECTION_ATTRIBUTES], [ATTR_MESSAGING_DESTINATION]: exchange, [ATTR_MESSAGING_DESTINATION_KIND]: MESSAGING_DESTINATION_KIND_VALUE_TOPIC, @@ -192,8 +191,8 @@ export function startConsumeSpan( ): Span { return startInactiveSpan({ name: `${queue} process`, - kind: SpanKind.CONSUMER, attributes: { + [SENTRY_KIND]: 'consumer', ...channel?.connection?.[CONNECTION_ATTRIBUTES], [ATTR_MESSAGING_DESTINATION]: msg.fields?.exchange, [ATTR_MESSAGING_DESTINATION_KIND]: MESSAGING_DESTINATION_KIND_VALUE_TOPIC, diff --git a/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts index 9d37febcb8a1..4fb13c0755b4 100644 --- a/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/dataloader/vendored/instrumentation.ts @@ -9,15 +9,9 @@ */ import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation'; -import { CACHE_KEY } from '@sentry/conventions/attributes'; +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, - SPAN_KIND, - startSpan, -} from '@sentry/core'; +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'; @@ -169,8 +163,8 @@ export class DataloaderInstrumentation extends InstrumentationBase { return startSpan( { name: getSpanName(this, 'load'), - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('load'), [CACHE_KEY]: getCacheKey(args[0]), @@ -208,8 +202,8 @@ export class DataloaderInstrumentation extends InstrumentationBase { return startSpan( { name: getSpanName(this, 'loadMany'), - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('loadMany'), [CACHE_KEY]: getCacheKey(args[0]), @@ -235,8 +229,8 @@ export class DataloaderInstrumentation extends InstrumentationBase { return startSpan( { name: getSpanName(this, 'prime'), - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('prime'), }, @@ -261,8 +255,8 @@ export class DataloaderInstrumentation extends InstrumentationBase { return startSpan( { name: getSpanName(this, 'clear'), - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('clear'), }, @@ -287,8 +281,8 @@ export class DataloaderInstrumentation extends InstrumentationBase { return startSpan( { name: getSpanName(this, 'clearAll'), - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: getSpanOp('clearAll'), }, diff --git a/packages/node/src/integrations/tracing/firebase/otel/patches/firestore.ts b/packages/node/src/integrations/tracing/firebase/otel/patches/firestore.ts index 93bd839ec8a0..0f09d0209fe3 100644 --- a/packages/node/src/integrations/tracing/firebase/otel/patches/firestore.ts +++ b/packages/node/src/integrations/tracing/firebase/otel/patches/firestore.ts @@ -6,11 +6,12 @@ import { DB_NAMESPACE, DB_OPERATION_NAME, DB_SYSTEM_NAME, + SENTRY_KIND, SERVER_ADDRESS, SERVER_PORT, } from '@sentry/conventions/attributes'; import type { SpanAttributes } from '@sentry/core'; -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_KIND, startSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/core'; import type { FirebaseInstrumentation } from '../firebaseInstrumentation'; import type { AddDocType, @@ -178,8 +179,8 @@ function startFirestoreSpan( { name: `${spanName} ${reference.path}`, op: 'db.query', - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.firebase.otel.firestore', [DB_OPERATION_NAME]: spanName, ...buildAttributes(reference), diff --git a/packages/node/src/integrations/tracing/firebase/otel/patches/functions.ts b/packages/node/src/integrations/tracing/firebase/otel/patches/functions.ts index dd8740f57130..e54167d43d27 100644 --- a/packages/node/src/integrations/tracing/firebase/otel/patches/functions.ts +++ b/packages/node/src/integrations/tracing/firebase/otel/patches/functions.ts @@ -1,12 +1,12 @@ import type { InstrumentationBase } from '@opentelemetry/instrumentation'; import { InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation'; import { InstrumentationNodeModuleFile } from '../../../InstrumentationNodeModuleFile'; +import { SENTRY_KIND } from '@sentry/conventions/attributes'; import type { SpanAttributes } from '@sentry/core'; import { captureException, flush, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startSpanManual, } from '@sentry/core'; @@ -68,6 +68,7 @@ export function patchV2Functions { diff --git a/packages/node/src/integrations/tracing/kafka/vendored/utils.ts b/packages/node/src/integrations/tracing/kafka/vendored/utils.ts index 74cef295e1fa..d9a2bd88acd8 100644 --- a/packages/node/src/integrations/tracing/kafka/vendored/utils.ts +++ b/packages/node/src/integrations/tracing/kafka/vendored/utils.ts @@ -15,13 +15,13 @@ import { MESSAGING_OPERATION_NAME, MESSAGING_OPERATION_TYPE, MESSAGING_SYSTEM, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes, SpanLink } from '@sentry/core'; import { getTraceData, propagationContextFromHeaders, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, } from '@sentry/core'; @@ -99,9 +99,9 @@ export function startConsumerSpan({ topic, message, operationType, links, attrib return startInactiveSpan({ name: `${operationName} ${topic}`, - kind: operationType === MESSAGING_OPERATION_TYPE_VALUE_RECEIVE ? SPAN_KIND.CLIENT : SPAN_KIND.CONSUMER, links, attributes: { + [SENTRY_KIND]: operationType === MESSAGING_OPERATION_TYPE_VALUE_RECEIVE ? 'client' : 'consumer', ...attributes, [MESSAGING_SYSTEM]: MESSAGING_SYSTEM_VALUE_KAFKA, [MESSAGING_DESTINATION_NAME]: topic, @@ -121,8 +121,8 @@ export function startConsumerSpan({ topic, message, operationType, links, attrib export function startProducerSpan(topic: string, message: Message): Span { const span = startInactiveSpan({ name: `send ${topic}`, - kind: SPAN_KIND.PRODUCER, attributes: { + [SENTRY_KIND]: 'producer', [MESSAGING_SYSTEM]: MESSAGING_SYSTEM_VALUE_KAFKA, [MESSAGING_DESTINATION_NAME]: topic, [ATTR_MESSAGING_KAFKA_MESSAGE_KEY]: message.key ? String(message.key) : undefined, diff --git a/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts index 89ae16cd6c4d..e3b00ed2fcc4 100644 --- a/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/knex/vendored/instrumentation.ts @@ -18,7 +18,6 @@ import { getActiveSpan, SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startSpan, } from '@sentry/core'; @@ -31,6 +30,7 @@ import { 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'; @@ -122,6 +122,7 @@ export class KnexInstrumentation extends InstrumentationBase | undefined; diff --git a/packages/node/src/integrations/tracing/redis/vendored/redis-instrumentation.ts b/packages/node/src/integrations/tracing/redis/vendored/redis-instrumentation.ts index 0bd639bbbe71..0f474564c136 100644 --- a/packages/node/src/integrations/tracing/redis/vendored/redis-instrumentation.ts +++ b/packages/node/src/integrations/tracing/redis/vendored/redis-instrumentation.ts @@ -17,12 +17,11 @@ import { getActiveSpan, SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, withActiveSpan, } from '@sentry/core'; -import { DB_STATEMENT, DB_SYSTEM, NET_PEER_NAME, NET_PEER_PORT } from '@sentry/conventions/attributes'; +import { DB_STATEMENT, DB_SYSTEM, NET_PEER_NAME, NET_PEER_PORT, SENTRY_KIND } from '@sentry/conventions/attributes'; import { defaultDbStatementSerializer } from '@sentry/server-utils'; import { DEBUG_BUILD } from '../../../../debug-build'; import { InstrumentationNodeModuleFile } from '../../InstrumentationNodeModuleFile'; @@ -115,6 +114,7 @@ function removeCredentialsFromDBConnectionStringAttribute(url: string | undefine function getClientAttributes(options: any): SpanAttributes { return { + [SENTRY_KIND]: 'client', // oxlint-disable-next-line typescript/no-deprecated [DB_SYSTEM]: DB_SYSTEM_VALUE_REDIS, // oxlint-disable-next-line typescript/no-deprecated @@ -163,6 +163,7 @@ class RedisInstrumentationV2_V3 extends InstrumentationBase original.apply(this)); @@ -450,7 +449,6 @@ class RedisInstrumentationV4_V5 extends InstrumentationBase origFunction.apply(origThis, origArguments)); diff --git a/packages/node/src/integrations/tracing/tedious/vendored/instrumentation.ts b/packages/node/src/integrations/tracing/tedious/vendored/instrumentation.ts index 6ac1ef7fd41b..a4ae168e849d 100644 --- a/packages/node/src/integrations/tracing/tedious/vendored/instrumentation.ts +++ b/packages/node/src/integrations/tracing/tedious/vendored/instrumentation.ts @@ -19,6 +19,7 @@ import { DB_USER, NET_PEER_NAME, NET_PEER_PORT, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { DB_SYSTEM_VALUE_MSSQL, ATTR_DB_SQL_TABLE } from './semconv'; import type * as tedious from './tedious-types'; @@ -27,7 +28,6 @@ import type { SpanAttributes } from '@sentry/core'; import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, withActiveSpan, @@ -137,6 +137,7 @@ export class TediousInstrumentation extends InstrumentationBase', attributesForInference, kind); - if (kind !== SpanKind.INTERNAL && attributes['otel.kind'] === undefined) { - span.setAttribute('otel.kind', SpanKind[kind]); - } + const inferred = inferSpanData(spanJSON.description || '', attributesForInference); + const kind = attributes[SENTRY_KIND]; if (inferred.op && attributes[SEMANTIC_ATTRIBUTE_SENTRY_OP] === undefined) { span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, inferred.op); @@ -67,7 +60,7 @@ export function applyOtelSpanData(span: Span, options: { finalizeStatus?: boolea inferred.source !== undefined && inferred.source !== 'custom' && (options.finalizeStatus || inferred.source !== 'url') && - (spanJSON.parent_span_id === undefined || kind === SpanKind.SERVER); + (spanJSON.parent_span_id === undefined || kind === 'server'); if (shouldApplyInferredSource && (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === undefined || canInferSource)) { span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, inferred.source); @@ -101,11 +94,6 @@ export function applyOtelSpanData(span: Span, options: { finalizeStatus?: boolea } } -/** Stash the OTel span kind on a Sentry span so {@link applyOtelSpanData} can read it. */ -export function applyOtelSpanKind(span: Span, kind: SpanKind | undefined): void { - addNonEnumerableProperty(span as SentrySpanWithOtelKind, 'kind', kind ?? SpanKind.INTERNAL); -} - function applyOtelSpanStatus( span: Span, attributes: SpanAttributes, diff --git a/packages/opentelemetry/src/exports.ts b/packages/opentelemetry/src/exports.ts index f034be3bdf67..7c3d992dae92 100644 --- a/packages/opentelemetry/src/exports.ts +++ b/packages/opentelemetry/src/exports.ts @@ -5,8 +5,6 @@ export { getRequestSpanData } from './utils/getRequestSpanData'; export type { OpenTelemetryClient } from './types'; export { wrapClientClass } from './custom/client'; -export { getSpanKind } from './utils/getSpanKind'; - export { getScopesFromContext } from './utils/contextData'; export { diff --git a/packages/opentelemetry/src/sampler.ts b/packages/opentelemetry/src/sampler.ts index 0d7b2acabad1..ad532a8e4ff9 100644 --- a/packages/opentelemetry/src/sampler.ts +++ b/packages/opentelemetry/src/sampler.ts @@ -91,7 +91,7 @@ export class SentrySampler implements Sampler { // Likewise, we only record client outcomes for child spans when streaming if (parentSampled) { if (ignoreSpans?.length) { - const { description: inferredChildName, op: childOp } = inferSpanData(spanName, spanAttributes, spanKind); + const { description: inferredChildName, op: childOp } = inferSpanData(spanName, spanAttributes); if ( shouldIgnoreSpan( { @@ -127,11 +127,7 @@ export class SentrySampler implements Sampler { } // We want to pass the inferred name & attributes to the sampler method - const { - description: inferredSpanName, - data: inferredAttributes, - op, - } = inferSpanData(spanName, spanAttributes, spanKind); + const { description: inferredSpanName, data: inferredAttributes, op } = inferSpanData(spanName, spanAttributes); const mergedAttributes = { ...inferredAttributes, diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index 3e72d2a1cc0f..47c8a3d38f5f 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -26,6 +26,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, + spanKindToName, spanTimeInputToSeconds, timedEventsToMeasurements, } from '@sentry/core'; @@ -438,7 +439,7 @@ function getData(span: ReadableSpan): Record { const data: Record = {}; if (span.kind !== SpanKind.INTERNAL) { - data['otel.kind'] = SpanKind[span.kind]; + data['sentry.kind'] = spanKindToName(span.kind); } // eslint-disable-next-line typescript/no-deprecated diff --git a/packages/opentelemetry/src/tracer.ts b/packages/opentelemetry/src/tracer.ts index 5d7161cead5f..69dab7b9ef1c 100644 --- a/packages/opentelemetry/src/tracer.ts +++ b/packages/opentelemetry/src/tracer.ts @@ -16,13 +16,15 @@ import { SentryNonRecordingSpan, setCapturedScopesOnSpan, spanIsIgnored, + spanKindToName, startNewTrace, withScope, } from '@sentry/core'; import type { Span, SpanAttributes, SpanLink } from '@sentry/core'; -import { applyOtelSpanData, applyOtelSpanKind } from './applyOtelSpanData'; +import { applyOtelSpanData } from './applyOtelSpanData'; import { SENTRY_FORK_SET_ISOLATION_SCOPE_CONTEXT_KEY, SENTRY_TRACE_STATE_DSC } from './constants'; import { getSamplingDecision } from './utils/getSamplingDecision'; +import { SENTRY_KIND } from '@sentry/conventions/attributes'; export class SentryTracer implements Tracer { /** @inheritdoc */ @@ -41,7 +43,6 @@ export class SentryTracer implements Tracer { // are not marked and keep their mutable behavior. markSpanAsTracerProviderSpan(span); - applyOtelSpanKind(span, options.kind); if (options.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === undefined) { markSpanForOtelSourceInference(span); } @@ -109,11 +110,16 @@ export class SentryTracer implements Tracer { ): Span { const sentryOptions = { name, - attributes: options.attributes as SpanAttributes | undefined, + attributes: (options.attributes as SpanAttributes) || {}, links: options.links as SpanLink[] | undefined, startTime: options.startTime, }; + // Convert otel kind to our sentry.kind attribtue + if (options.kind) { + sentryOptions.attributes[SENTRY_KIND] = spanKindToName(options.kind); + } + if (options.root) { return startNewTrace(() => _INTERNAL_startInactiveSpan({ ...sentryOptions, parentSpan: null })); } diff --git a/packages/opentelemetry/src/utils/backfillStreamedSpanData.ts b/packages/opentelemetry/src/utils/backfillStreamedSpanData.ts index dc215d95e7db..a77371c00b22 100644 --- a/packages/opentelemetry/src/utils/backfillStreamedSpanData.ts +++ b/packages/opentelemetry/src/utils/backfillStreamedSpanData.ts @@ -3,8 +3,6 @@ import { safeSetSpanJSONAttributes, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SPAN_KIND, - spanKindToName, } from '@sentry/core'; import { inferSpanData } from './parseSpanDescription'; import { SENTRY_ORIGIN } from '@sentry/conventions/attributes'; @@ -20,11 +18,10 @@ import { SENTRY_ORIGIN } from '@sentry/conventions/attributes'; * child spans, which `applyOtelSpanData` only sets on segment roots). `inferSpanData` is deterministic * on the same attributes, so re-running it here is a no-op for already-inferred fields. */ -export function backfillStreamedSpanDataFromOtel(spanJSON: StreamedSpanJSON, hint?: { spanKind?: number }): void { +export function backfillStreamedSpanDataFromOtel(spanJSON: StreamedSpanJSON): void { const attributes = spanJSON.attributes ?? {}; - const kind = hint?.spanKind ?? SPAN_KIND.INTERNAL; - const { op, description, source, data } = inferSpanData(spanJSON.name, attributes as unknown as SpanAttributes, kind); + const { op, description, source, data } = inferSpanData(spanJSON.name, attributes as unknown as SpanAttributes); spanJSON.name = description; @@ -38,10 +35,4 @@ export function backfillStreamedSpanDataFromOtel(spanJSON: StreamedSpanJSON, hin [SENTRY_ORIGIN]: 'manual', ...data, }); - - if (kind !== SPAN_KIND.INTERNAL) { - safeSetSpanJSONAttributes(spanJSON, { - 'otel.kind': spanKindToName(kind), - }); - } } diff --git a/packages/opentelemetry/src/utils/getSpanKind.ts b/packages/opentelemetry/src/utils/getSpanKind.ts deleted file mode 100644 index de0e9b33e490..000000000000 --- a/packages/opentelemetry/src/utils/getSpanKind.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { SpanKind } from '@opentelemetry/api'; -import type { AbstractSpan } from '../types'; -import { spanHasKind } from './spanTypes'; - -/** - * Get the span kind from a span. - * For whatever reason, this is not public API on the generic "Span" type, - * so we need to check if we actually have a `SDKTraceBaseSpan` where we can fetch this from. - * Otherwise, we fall back to `SpanKind.INTERNAL`. - */ -export function getSpanKind(span: AbstractSpan): SpanKind { - if (spanHasKind(span)) { - return span.kind; - } - - return SpanKind.INTERNAL; -} diff --git a/packages/opentelemetry/src/utils/parseSpanDescription.ts b/packages/opentelemetry/src/utils/parseSpanDescription.ts index 0707697ce7f9..61cbabcd3933 100644 --- a/packages/opentelemetry/src/utils/parseSpanDescription.ts +++ b/packages/opentelemetry/src/utils/parseSpanDescription.ts @@ -1,5 +1,4 @@ import type { Attributes, AttributeValue } from '@opentelemetry/api'; -import { SpanKind } from '@opentelemetry/api'; import { DB_STATEMENT, DB_SYSTEM, @@ -12,9 +11,10 @@ import { HTTP_URL, MESSAGING_SYSTEM, RPC_SERVICE, + SENTRY_KIND, URL_FULL, } from '@sentry/conventions/attributes'; -import type { Span, SpanAttributes, TransactionSource } from '@sentry/core'; +import type { Span, SpanAttributes, TransactionSource, SpanKind } from '@sentry/core'; import { getSanitizedUrlString, parseUrl, @@ -27,7 +27,6 @@ import { } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_GRAPHQL_OPERATION } from '../semanticAttributes'; import type { AbstractSpan } from '../types'; -import { getSpanKind } from './getSpanKind'; import { spanHasAttributes, spanHasName } from './spanTypes'; interface SpanDescription { @@ -40,7 +39,9 @@ interface SpanDescription { /** * Infer the op & description for a set of name, attributes and kind of a span. */ -export function inferSpanData(spanName: string, attributes: SpanAttributes, kind: SpanKind): SpanDescription { +export function inferSpanData(spanName: string, attributes: SpanAttributes): SpanDescription { + const kind = attributes[SENTRY_KIND]; + // if http.method exists, this is an http request span // eslint-disable-next-line typescript/no-deprecated const httpMethod = attributes[HTTP_REQUEST_METHOD] || attributes[HTTP_METHOD]; @@ -120,8 +121,7 @@ export function parseSpanDescription(span: AbstractSpan): SpanDescription { name = spanHasName(span) ? span.name : json?.description || ''; } - const kind = getSpanKind(span); - return inferSpanData(name, attributes, kind); + return inferSpanData(name, attributes); } function descriptionForDbSystem({ attributes, name }: { attributes: Attributes; name: string }): SpanDescription { @@ -151,16 +151,16 @@ function descriptionForDbSystem({ attributes, name }: { attributes: Attributes; /** Only exported for tests. */ export function descriptionForHttpMethod( - { name, kind, attributes }: { name: string; attributes: Attributes; kind: SpanKind }, + { name, kind, attributes }: { name: string; attributes: Attributes; kind: SpanKind | undefined }, httpMethod: AttributeValue, ): SpanDescription { const opParts = ['http']; switch (kind) { - case SpanKind.CLIENT: + case 'client': opParts.push('client'); break; - case SpanKind.SERVER: + case 'server': opParts.push('server'); break; } @@ -208,7 +208,7 @@ export function descriptionForHttpMethod( // If the span kind is neither client nor server, we use the original name // this infers that somebody manually started this span, in which case we don't want to overwrite the name - const isClientOrServerKind = kind === SpanKind.CLIENT || kind === SpanKind.SERVER; + const isClientOrServerKind = kind === 'client' || kind === 'server'; // If the span is an auto-span (=it comes from one of our instrumentations), // we always want to infer the name @@ -255,7 +255,7 @@ function getGraphqlOperationNamesFromAttribute(attr: AttributeValue): string { /** Exported for tests only */ export function getSanitizedUrl( attributes: Attributes, - kind: SpanKind, + kind: SpanKind | undefined, ): { url: string | undefined; urlPath: string | undefined; @@ -281,7 +281,7 @@ export function getSanitizedUrl( return { urlPath: httpRoute, url, query, fragment, hasRoute: true }; } - if (kind === SpanKind.SERVER && typeof httpTarget === 'string') { + if (kind === 'server' && typeof httpTarget === 'string') { return { urlPath: stripUrlQueryAndFragment(httpTarget), url, query, fragment, hasRoute: false }; } diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index aef970a515d8..75a8c7aa5624 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -2,7 +2,7 @@ import type { Span, TimeInput } from '@opentelemetry/api'; import { context, ROOT_CONTEXT, SpanKind, trace, TraceFlags } from '@opentelemetry/api'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; -import { HTTP_METHOD } from '@sentry/conventions/attributes'; +import { HTTP_METHOD, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { Event, Scope } from '@sentry/core'; import { getClient, @@ -26,7 +26,6 @@ import { continueTrace, startInactiveSpan, startNewTrace, startSpan, startSpanMa import type { AbstractSpan } from '../src/types'; import { getActiveSpan } from '../src/utils/getActiveSpan'; import { getSamplingDecision } from '../src/utils/getSamplingDecision'; -import { getSpanKind } from '../src/utils/getSpanKind'; import { makeTraceState } from '../src/utils/makeTraceState'; import { spanHasAttributes, spanHasName } from '../src/utils/spanTypes'; import { isSpan } from './helpers/isSpan'; @@ -269,8 +268,8 @@ describe('trace', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, test1: 'test 1', test2: 2, + [SENTRY_KIND]: 'client', }); - expect(getSpanKind(span)).toEqual(SpanKind.CLIENT); }, ); }); @@ -670,8 +669,8 @@ describe('trace', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, test1: 'test 1', test2: 2, + [SENTRY_KIND]: 'client', }); - expect(getSpanKind(span)).toEqual(SpanKind.CLIENT); }); it('allows to pass a startTime in seconds', () => { @@ -1012,8 +1011,8 @@ describe('trace', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, test1: 'test 1', test2: 2, + [SENTRY_KIND]: 'client', }); - expect(getSpanKind(span)).toEqual(SpanKind.CLIENT); }, ); }); diff --git a/packages/opentelemetry/test/tracerProvider.test.ts b/packages/opentelemetry/test/tracerProvider.test.ts index c7aa9b928e95..1564d786adb4 100644 --- a/packages/opentelemetry/test/tracerProvider.test.ts +++ b/packages/opentelemetry/test/tracerProvider.test.ts @@ -146,7 +146,7 @@ describe('SentryTracerProvider', () => { expect(json.trace_id).toBe('12312012123120121231201212312012'); expect(json.parent_span_id).toBe('1121201211212012'); - expect(json.data?.['otel.kind']).toBe('SERVER'); + expect(json.data?.['sentry.kind']).toBe('server'); }); it('finalizes span statuses like the OpenTelemetry exporter', () => { diff --git a/packages/opentelemetry/test/utils/getSpanKind.test.ts b/packages/opentelemetry/test/utils/getSpanKind.test.ts deleted file mode 100644 index 1a90fbc23ede..000000000000 --- a/packages/opentelemetry/test/utils/getSpanKind.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { Span } from '@opentelemetry/api'; -import { SpanKind } from '@opentelemetry/api'; -import { describe, expect, it } from 'vitest'; -import { getSpanKind } from '../../src/utils/getSpanKind'; - -describe('getSpanKind', () => { - it('works', () => { - expect(getSpanKind({} as Span)).toBe(SpanKind.INTERNAL); - expect(getSpanKind({ kind: SpanKind.CLIENT } as unknown as Span)).toBe(SpanKind.CLIENT); - }); -}); diff --git a/packages/remix/src/server/integrations/tracing-channel.ts b/packages/remix/src/server/integrations/tracing-channel.ts index 04d5e4a21269..485554e13d15 100644 --- a/packages/remix/src/server/integrations/tracing-channel.ts +++ b/packages/remix/src/server/integrations/tracing-channel.ts @@ -7,7 +7,6 @@ import { parseStringToURLObject, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, waitForTracingChannelBinding, } from '@sentry/core'; @@ -20,6 +19,7 @@ import { HTTP_URL, URL_FULL, URL_PATH, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { remixChannels } from '@sentry/server-utils/orchestrion'; @@ -134,8 +134,8 @@ function subscribeRequestHandler(): void { data => startInactiveSpan({ name: 'remix.request', - kind: SPAN_KIND.SERVER, attributes: { + [SENTRY_KIND]: 'server', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server', [CODE_FUNCTION]: 'requestHandler', diff --git a/packages/remix/test/server/tracing-channel.test.ts b/packages/remix/test/server/tracing-channel.test.ts index ae675a15f1a6..a9a1c243f1c3 100644 --- a/packages/remix/test/server/tracing-channel.test.ts +++ b/packages/remix/test/server/tracing-channel.test.ts @@ -44,9 +44,9 @@ describe('remixIntegration (Orchestrion-based)', () => { expect(startInactiveSpanSpy).toHaveBeenCalledWith( expect.objectContaining({ name: 'remix.request', - kind: SentryCore.SPAN_KIND.SERVER, attributes: expect.objectContaining({ 'sentry.origin': 'auto.http.orchestrion.remix', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'code.function': 'requestHandler', 'http.method': 'GET', diff --git a/packages/server-utils/src/integrations/tracing-channel/amqplib.ts b/packages/server-utils/src/integrations/tracing-channel/amqplib.ts index a745ed88c9d2..e6e5925c7c5a 100644 --- a/packages/server-utils/src/integrations/tracing-channel/amqplib.ts +++ b/packages/server-utils/src/integrations/tracing-channel/amqplib.ts @@ -7,7 +7,6 @@ import { defineIntegration, getTraceData, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, timestampInSeconds, @@ -23,6 +22,7 @@ import { NET_PEER_PORT, NETWORK_PROTOCOL_NAME, NETWORK_PROTOCOL_VERSION, + SENTRY_KIND, SERVER_ADDRESS, SERVER_PORT, URL_FULL, @@ -475,8 +475,8 @@ function startPublishSpan(data: AmqpChannelContext): Span { const span = startInactiveSpan({ name: `publish ${normalizeExchange(exchange)}`, op: 'message', - kind: SPAN_KIND.PRODUCER, attributes: { + [SENTRY_KIND]: 'producer', ...getStoredConnectionAttributes(data.self), [ATTR_MESSAGING_DESTINATION]: exchange, // TODO(v11) remove this attribute [MESSAGING_DESTINATION_NAME]: exchange, @@ -513,8 +513,8 @@ function startConsumeSpan(queue: string, msg: ConsumeMessage, channel: ChannelLi return startInactiveSpan({ name: `${queue} process`, op: 'message', - kind: SPAN_KIND.CONSUMER, attributes: { + [SENTRY_KIND]: 'consumer', ...getStoredConnectionAttributes(channel), [ATTR_MESSAGING_DESTINATION]: msg.fields?.exchange, // TODO(v11) remove this attribute [MESSAGING_DESTINATION_NAME]: msg.fields?.exchange, diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts index 4ed048a9de1f..70482dcbfd5f 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/index.ts @@ -4,7 +4,6 @@ import { debug, defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, waitForTracingChannelBinding, } from '@sentry/core'; @@ -13,6 +12,7 @@ import { AWS_REQUEST_EXTENDED_ID, CLOUD_REGION, HTTP_STATUS_CODE, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { DEBUG_BUILD } from '../../../debug-build'; import { CHANNELS } from '../../../orchestrion/channels'; @@ -110,11 +110,11 @@ const _awsChannelIntegration = (() => { const span = startInactiveSpan({ name: requestMetadata.spanName ?? `${normalizedRequest.serviceName}.${normalizedRequest.commandName}`, - kind: requestMetadata.spanKind ?? SPAN_KIND.CLIENT, // `rpc` matches what the exporter infers from `rpc.service` for the OTel aws-sdk spans; // service extensions override it where inference yields a different op (DynamoDB: `db`). op: requestMetadata.spanOp || 'rpc', attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: AWS_SDK_ORIGIN, ...extractAttributesFromNormalizedRequest(normalizedRequest), ...requestMetadata.spanAttributes, diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/dynamodb.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/dynamodb.ts index f9276fc20d96..8602793f5702 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/dynamodb.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/dynamodb.ts @@ -1,5 +1,4 @@ import type { Span } from '@sentry/core'; -import { SPAN_KIND } from '@sentry/core'; import { AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS as ATTR_AWS_DYNAMODB_ATTRIBUTE_DEFINITIONS, AWS_DYNAMODB_CONSISTENT_READ as ATTR_AWS_DYNAMODB_CONSISTENT_READ, @@ -152,7 +151,6 @@ export class DynamodbServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind: SPAN_KIND.CLIENT, // Matches what the exporter infers from `db.system` for the OTel DynamoDB spans. spanOp: 'db', }; diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/kinesis.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/kinesis.ts index 22599882d443..c8959dd26c68 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/kinesis.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/kinesis.ts @@ -1,4 +1,3 @@ -import { SPAN_KIND } from '@sentry/core'; import { _AWS_KINESIS_STREAM_NAME as AWS_KINESIS_STREAM_NAME } from '@sentry/conventions/attributes'; import type { NormalizedRequest } from '../types'; import type { RequestMetadata, ServiceExtension } from './ServiceExtension'; @@ -15,7 +14,6 @@ export class KinesisServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind: SPAN_KIND.CLIENT, }; } } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/lambda.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/lambda.ts index e1a7cd1fce43..381f46a3cec7 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/lambda.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/lambda.ts @@ -1,5 +1,5 @@ import type { Span } from '@sentry/core'; -import { debug, getTraceData, SPAN_KIND } from '@sentry/core'; +import { debug, getTraceData } from '@sentry/core'; import { FAAS_EXECUTION as ATTR_FAAS_EXECUTION, FAAS_INVOKED_NAME as ATTR_FAAS_INVOKED_NAME, @@ -27,7 +27,6 @@ export class LambdaServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind: SPAN_KIND.CLIENT, spanName, }; } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/s3.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/s3.ts index 24062efe3cd8..351d9306c17a 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/s3.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/s3.ts @@ -1,4 +1,3 @@ -import { SPAN_KIND } from '@sentry/core'; import { AWS_S3_BUCKET } from '@sentry/conventions/attributes'; import type { NormalizedRequest } from '../types'; import type { RequestMetadata, ServiceExtension } from './ServiceExtension'; @@ -14,7 +13,6 @@ export class S3ServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind: SPAN_KIND.CLIENT, }; } } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/secretsmanager.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/secretsmanager.ts index b73318ef23b8..fd9a845b938f 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/secretsmanager.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/secretsmanager.ts @@ -1,5 +1,4 @@ import type { Span } from '@sentry/core'; -import { SPAN_KIND } from '@sentry/core'; import { AWS_SECRETSMANAGER_SECRET_ARN as ATTR_AWS_SECRETSMANAGER_SECRET_ARN } from '@sentry/conventions/attributes'; import type { NormalizedRequest, NormalizedResponse } from '../types'; import type { RequestMetadata, ServiceExtension } from './ServiceExtension'; @@ -14,7 +13,6 @@ export class SecretsManagerServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind: SPAN_KIND.CLIENT, }; } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sns.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sns.ts index ca12a69c54aa..2efe96d721d4 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sns.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sns.ts @@ -1,10 +1,11 @@ -import type { Span, SpanKindValue } from '@sentry/core'; -import { getTraceData, SPAN_KIND } from '@sentry/core'; +import type { Span } from '@sentry/core'; +import { getTraceData } from '@sentry/core'; import { AWS_SNS_TOPIC_ARN as ATTR_AWS_SNS_TOPIC_ARN, MESSAGING_DESTINATION as ATTR_MESSAGING_DESTINATION, MESSAGING_DESTINATION_NAME, MESSAGING_SYSTEM, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { ATTR_MESSAGING_DESTINATION_KIND, MESSAGING_DESTINATION_KIND_VALUE_TOPIC } from '../constants'; import type { NormalizedRequest, NormalizedResponse } from '../types'; @@ -13,14 +14,14 @@ import type { RequestMetadata, ServiceExtension } from './ServiceExtension'; export class SnsServiceExtension implements ServiceExtension { public requestPreSpanHook(request: NormalizedRequest): RequestMetadata { - let spanKind: SpanKindValue = SPAN_KIND.CLIENT; let spanName = `SNS ${request.commandName}`; const spanAttributes: Record = { [MESSAGING_SYSTEM]: 'aws.sns', + [SENTRY_KIND]: 'client', }; if (request.commandName === 'Publish') { - spanKind = SPAN_KIND.PRODUCER; + spanAttributes[SENTRY_KIND] = 'producer'; spanAttributes[ATTR_MESSAGING_DESTINATION_KIND] = MESSAGING_DESTINATION_KIND_VALUE_TOPIC; const { TopicArn, TargetArn, PhoneNumber } = request.commandInput; @@ -39,7 +40,6 @@ export class SnsServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind, spanName, }; } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sqs.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sqs.ts index da1ec52ff013..06c5a8543db2 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sqs.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/sqs.ts @@ -1,11 +1,12 @@ -import type { Span, SpanKindValue } from '@sentry/core'; -import { getTraceData, propagationContextFromHeaders, SPAN_KIND } from '@sentry/core'; +import type { Span } from '@sentry/core'; +import { getTraceData, propagationContextFromHeaders } from '@sentry/core'; import { MESSAGING_BATCH_MESSAGE_COUNT, MESSAGING_DESTINATION_NAME, MESSAGING_MESSAGE_ID, MESSAGING_OPERATION_TYPE, MESSAGING_SYSTEM, + SENTRY_KIND, URL_FULL, } from '@sentry/conventions/attributes'; import type { SQS } from '../aws-sdk.types'; @@ -21,21 +22,21 @@ export class SqsServiceExtension implements ServiceExtension { public requestPreSpanHook(request: NormalizedRequest): RequestMetadata { const queueUrl = extractQueueUrl(request.commandInput); const queueName = extractQueueNameFromUrl(queueUrl); - let spanKind: SpanKindValue = SPAN_KIND.CLIENT; let spanName: string | undefined; const spanAttributes: Record = { [MESSAGING_SYSTEM]: 'aws_sqs', [MESSAGING_DESTINATION_NAME]: queueName, [URL_FULL]: queueUrl, + [SENTRY_KIND]: 'client', }; switch (request.commandName) { case 'ReceiveMessage': { - spanKind = SPAN_KIND.CONSUMER; spanName = `${queueName} receive`; spanAttributes[MESSAGING_OPERATION_TYPE] = 'receive'; + spanAttributes[SENTRY_KIND] = 'consumer'; request.commandInput.MessageAttributeNames = addPropagationFieldsToAttributeNames( request.commandInput.MessageAttributeNames, @@ -45,14 +46,13 @@ export class SqsServiceExtension implements ServiceExtension { case 'SendMessage': case 'SendMessageBatch': - spanKind = SPAN_KIND.PRODUCER; + spanAttributes[SENTRY_KIND] = 'producer'; spanName = `${queueName} send`; break; } return { spanAttributes, - spanKind, spanName, }; } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/stepfunctions.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/stepfunctions.ts index 05afa34d6a39..07ba007e0781 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/stepfunctions.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/services/stepfunctions.ts @@ -1,4 +1,3 @@ -import { SPAN_KIND } from '@sentry/core'; import { AWS_STEP_FUNCTIONS_ACTIVITY_ARN as ATTR_AWS_STEP_FUNCTIONS_ACTIVITY_ARN, AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN as ATTR_AWS_STEP_FUNCTIONS_STATE_MACHINE_ARN, @@ -22,7 +21,6 @@ export class StepFunctionsServiceExtension implements ServiceExtension { return { spanAttributes, - spanKind: SPAN_KIND.CLIENT, }; } } diff --git a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/types.ts b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/types.ts index 93d1ebade30d..da6e978cfc45 100644 --- a/packages/server-utils/src/integrations/tracing-channel/aws-sdk/types.ts +++ b/packages/server-utils/src/integrations/tracing-channel/aws-sdk/types.ts @@ -1,5 +1,3 @@ -import type { SpanKindValue } from '@sentry/core'; - // Command inputs are service-specific shapes from hundreds of AWS APIs; typing them would require // depending on the `@aws-sdk/*` client types. The per-service hooks read fields defensively instead. export type CommandInput = Record; @@ -29,7 +27,6 @@ export interface RequestMetadata { // consumed. isStream?: boolean; spanAttributes?: Record; - spanKind?: SpanKindValue; spanName?: string; // Overrides the default `rpc` span op (e.g. `db` for DynamoDB). spanOp?: string; diff --git a/packages/server-utils/src/integrations/tracing-channel/dataloader.ts b/packages/server-utils/src/integrations/tracing-channel/dataloader.ts index 5c951b2465c8..727eabc700c1 100644 --- a/packages/server-utils/src/integrations/tracing-channel/dataloader.ts +++ b/packages/server-utils/src/integrations/tracing-channel/dataloader.ts @@ -1,11 +1,10 @@ import * as diagnosticsChannel from 'node:diagnostics_channel'; -import { CACHE_KEY } from '@sentry/conventions/attributes'; +import { CACHE_KEY, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { IntegrationFn, Span, StartSpanOptions } from '@sentry/core'; import { debug, defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, startSpan, waitForTracingChannelBinding, @@ -81,13 +80,13 @@ function makeSpanOptions( return { name: getSpanName(loader, operation), - // Every direct operation (`load`/`loadMany`/`prime`/`clear`/`clearAll`) is a client call, matching - // the vendored OTel instrumentation. The `batch` runs off a deferred tick with no obvious network - // peer, so it gets no kind. - kind: operation === 'batch' ? undefined : SPAN_KIND.CLIENT, op: isCacheGet ? CACHE_GET_OP : undefined, onlyIfParent: true, attributes: { + // Every direct operation (`load`/`loadMany`/`prime`/`clear`/`clearAll`) is a client call, matching + // the vendored OTel instrumentation. The `batch` runs off a deferred tick with no obvious network + // peer, so it gets no kind. + [SENTRY_KIND]: operation === 'batch' ? undefined : 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [CACHE_KEY]: isCacheGet ? getCacheKey(keyArg) : undefined, }, diff --git a/packages/server-utils/src/integrations/tracing-channel/firebase/firestore.ts b/packages/server-utils/src/integrations/tracing-channel/firebase/firestore.ts index e4df109d9a20..3075e581b2bf 100644 --- a/packages/server-utils/src/integrations/tracing-channel/firebase/firestore.ts +++ b/packages/server-utils/src/integrations/tracing-channel/firebase/firestore.ts @@ -4,11 +4,12 @@ import { DB_NAMESPACE, DB_OPERATION_NAME, DB_SYSTEM_NAME, + SENTRY_KIND, SERVER_ADDRESS, SERVER_PORT, } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes } from '@sentry/core'; -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_KIND, startInactiveSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core'; import type { FirebaseApp, FirebaseOptions, FirestoreReference, FirestoreSettings } from './firestore-types'; /** @@ -20,8 +21,8 @@ export function startFirestoreSpan(spanName: string, reference: FirestoreReferen return startInactiveSpan({ name: `${spanName} ${reference.path}`, op: 'db.query', - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.firebase.orchestrion.firestore', [DB_OPERATION_NAME]: spanName, ...buildAttributes(reference), diff --git a/packages/server-utils/src/integrations/tracing-channel/firebase/functions.ts b/packages/server-utils/src/integrations/tracing-channel/firebase/functions.ts index 5917513dbb84..f50f71a445c3 100644 --- a/packages/server-utils/src/integrations/tracing-channel/firebase/functions.ts +++ b/packages/server-utils/src/integrations/tracing-channel/firebase/functions.ts @@ -1,10 +1,9 @@ -import { FAAS_NAME, FAAS_TRIGGER } from '@sentry/conventions/attributes'; +import { FAAS_NAME, FAAS_TRIGGER, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { SpanAttributes } from '@sentry/core'; import { captureException, flush, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startSpanManual, } from '@sentry/core'; @@ -57,6 +56,7 @@ function wrapHandler(handler: Handler, triggerType: string): Handler { [FAAS_NAME]: functionName, [FAAS_TRIGGER]: triggerType, 'faas.provider': 'firebase', + [SENTRY_KIND]: 'server', }; if (process.env.GCLOUD_PROJECT) { @@ -72,7 +72,6 @@ function wrapHandler(handler: Handler, triggerType: string): Handler { { name: `firebase.function.${triggerType}`, op: 'function.firebase', - kind: SPAN_KIND.SERVER, attributes, }, async span => { diff --git a/packages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts b/packages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts index 966488828d20..08e862f90d54 100644 --- a/packages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts +++ b/packages/server-utils/src/integrations/tracing-channel/kafkajs/spans.ts @@ -16,13 +16,13 @@ import { MESSAGING_OPERATION_NAME, MESSAGING_OPERATION_TYPE, MESSAGING_SYSTEM, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes, SpanLink } from '@sentry/core'; import { getTraceData, propagationContextFromHeaders, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, } from '@sentry/core'; @@ -104,9 +104,9 @@ export function startConsumerSpan({ topic, message, operationType, links, attrib name: `${operationName} ${topic}`, // todo(v11): Use https://getsentry.github.io/sentry-conventions/ops/#messaging op: 'message', - kind: operationType === MESSAGING_OPERATION_TYPE_VALUE_RECEIVE ? SPAN_KIND.CLIENT : SPAN_KIND.CONSUMER, links, attributes: { + [SENTRY_KIND]: operationType === MESSAGING_OPERATION_TYPE_VALUE_RECEIVE ? 'client' : 'consumer', ...attributes, [MESSAGING_SYSTEM]: MESSAGING_SYSTEM_VALUE_KAFKA, [MESSAGING_DESTINATION_NAME]: topic, @@ -127,8 +127,8 @@ export function startProducerSpan(topic: string, message: Message): Span { const span = startInactiveSpan({ name: `send ${topic}`, op: 'message', - kind: SPAN_KIND.PRODUCER, attributes: { + [SENTRY_KIND]: 'producer', [MESSAGING_SYSTEM]: MESSAGING_SYSTEM_VALUE_KAFKA, [MESSAGING_DESTINATION_NAME]: topic, [ATTR_MESSAGING_KAFKA_MESSAGE_KEY]: message.key ? String(message.key) : undefined, diff --git a/packages/server-utils/src/integrations/tracing-channel/knex.ts b/packages/server-utils/src/integrations/tracing-channel/knex.ts index 68f08edbf6f1..81eda8f9eea8 100644 --- a/packages/server-utils/src/integrations/tracing-channel/knex.ts +++ b/packages/server-utils/src/integrations/tracing-channel/knex.ts @@ -9,7 +9,6 @@ import { defineIntegration, getActiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, truncate, @@ -24,6 +23,7 @@ import { NET_PEER_NAME, NET_PEER_PORT, NET_TRANSPORT, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { DEBUG_BUILD } from '../../debug-build'; import { CHANNELS } from '../../orchestrion/channels'; @@ -167,6 +167,7 @@ function subscribeQuery(): void { connection?.filename || connection?.database || extractDatabaseFromConnectionString(connectionString); const attributes: SpanAttributes = { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, 'knex.version': data.moduleVersion, [DB_SYSTEM]: mapSystem(client?.driverName), @@ -182,7 +183,6 @@ function subscribeQuery(): void { return startInactiveSpan({ name: getName(name, operation, table) ?? 'knex.query', - kind: SPAN_KIND.CLIENT, op: 'db', parentSpan, attributes, diff --git a/packages/server-utils/src/integrations/tracing-channel/mysql.ts b/packages/server-utils/src/integrations/tracing-channel/mysql.ts index 9e96e23e3900..02588b15d0c3 100644 --- a/packages/server-utils/src/integrations/tracing-channel/mysql.ts +++ b/packages/server-utils/src/integrations/tracing-channel/mysql.ts @@ -1,4 +1,5 @@ import * as diagnosticsChannel from 'node:diagnostics_channel'; +import { SENTRY_KIND } from '@sentry/conventions/attributes'; import type { IntegrationFn, Scope } from '@sentry/core'; import { isObjectLike, @@ -7,7 +8,6 @@ import { defineIntegration, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, waitForTracingChannelBinding, } from '@sentry/core'; @@ -84,9 +84,9 @@ const _mysqlChannelIntegration = (() => { return startInactiveSpan({ name: sql ?? 'mysql.query', - kind: SPAN_KIND.CLIENT, op: 'db', attributes: { + [SENTRY_KIND]: 'client', [ATTR_DB_SYSTEM]: 'mysql', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.db.orchestrion.mysql', [ATTR_DB_CONNECTION_STRING]: getJDBCString(host, portIsNumber ? portNumber : undefined, database), diff --git a/packages/server-utils/src/integrations/tracing-channel/mysql2.ts b/packages/server-utils/src/integrations/tracing-channel/mysql2.ts index 9e59f521d363..d8f8e1c7bf0d 100644 --- a/packages/server-utils/src/integrations/tracing-channel/mysql2.ts +++ b/packages/server-utils/src/integrations/tracing-channel/mysql2.ts @@ -5,7 +5,6 @@ import { isObjectLike, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, waitForTracingChannelBinding, } from '@sentry/core'; @@ -20,6 +19,7 @@ import { DB_USER, NET_PEER_NAME, NET_PEER_PORT, + SENTRY_KIND, } from '@sentry/conventions/attributes'; const INTEGRATION_NAME = 'Mysql2' as const; @@ -82,8 +82,8 @@ function subscribeQueryChannel(channelName: ChannelName): void { return startInactiveSpan({ name: statement ?? 'mysql2.query', - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db', // oxlint-disable-next-line typescript/no-deprecated diff --git a/packages/server-utils/src/integrations/tracing-channel/postgres-js.ts b/packages/server-utils/src/integrations/tracing-channel/postgres-js.ts index 0a2440937643..c00b36efb73a 100644 --- a/packages/server-utils/src/integrations/tracing-channel/postgres-js.ts +++ b/packages/server-utils/src/integrations/tracing-channel/postgres-js.ts @@ -1,5 +1,5 @@ import * as diagnosticsChannel from 'node:diagnostics_channel'; -import { DB_QUERY_TEXT, DB_SYSTEM_NAME, ERROR_TYPE } from '@sentry/conventions/attributes'; +import { DB_QUERY_TEXT, DB_SYSTEM_NAME, ERROR_TYPE, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { IntegrationFn, PostgresConnectionContext, Span } from '@sentry/core'; import { _INTERNAL_buildPostgresConnectionContext, @@ -10,7 +10,6 @@ import { debug, defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, waitForTracingChannelBinding, @@ -266,12 +265,12 @@ const _postgresJsChannelIntegration = ((options: PostgresJsChannelIntegrationOpt const fullQuery = _INTERNAL_reconstructPostgresQuery(query.strings); const sanitizedSqlQuery = _INTERNAL_sanitizeSqlQuery(fullQuery); - // `kind: CLIENT` matches the mysql/pg channel subscribers. + // `sentry.kind: 'client'` matches the mysql/pg channel subscribers. const span = startInactiveSpan({ name: sanitizedSqlQuery || 'postgresjs.query', op: 'db', - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [DB_SYSTEM_NAME]: 'postgres', [DB_QUERY_TEXT]: sanitizedSqlQuery, diff --git a/packages/server-utils/src/integrations/tracing-channel/postgres.ts b/packages/server-utils/src/integrations/tracing-channel/postgres.ts index 9c69bdb5140b..ee9d975acb40 100644 --- a/packages/server-utils/src/integrations/tracing-channel/postgres.ts +++ b/packages/server-utils/src/integrations/tracing-channel/postgres.ts @@ -1,4 +1,5 @@ import * as diagnosticsChannel from 'node:diagnostics_channel'; +import { SENTRY_KIND } from '@sentry/conventions/attributes'; import type { IntegrationFn, Scope, SpanAttributes } from '@sentry/core'; import { isObjectLike, @@ -7,7 +8,6 @@ import { defineIntegration, getCurrentScope, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, waitForTracingChannelBinding, } from '@sentry/core'; @@ -126,9 +126,13 @@ function subscribeQueryLikeChannel( // replays this scope onto that emitter. data._sentryCallerScope = getCurrentScope(); - // `kind: CLIENT` mirrors the OTel pg instrumentation, so the emitted - // `otel.kind` matches across the OTel and diagnostics-channel paths. - return startInactiveSpan({ ...getSpanOptions(data), kind: SPAN_KIND.CLIENT }); + // `sentry.kind: 'client'` mirrors the OTel pg instrumentation, so the emitted + // `sentry.kind` matches across the OTel and diagnostics-channel paths. + const spanOptions = getSpanOptions(data); + return startInactiveSpan({ + ...spanOptions, + attributes: { ...spanOptions.attributes, [SENTRY_KIND]: 'client' }, + }); }, // `connect`/`pool-connect` resolve with a persistent `Client` (itself an // `EventEmitter`), which is NOT a streamed result. Deferring their span diff --git a/packages/server-utils/src/integrations/tracing-channel/redis.ts b/packages/server-utils/src/integrations/tracing-channel/redis.ts index 6dedde81bafb..42f23341b419 100644 --- a/packages/server-utils/src/integrations/tracing-channel/redis.ts +++ b/packages/server-utils/src/integrations/tracing-channel/redis.ts @@ -9,6 +9,7 @@ import { DB_SYSTEM_NAME, NET_PEER_NAME, NET_PEER_PORT, + SENTRY_KIND, SERVER_ADDRESS, SERVER_PORT, } from '@sentry/conventions/attributes'; @@ -20,7 +21,6 @@ import { getActiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, waitForTracingChannelBinding, @@ -145,8 +145,8 @@ function nodeRedisAttributes(options: NodeRedisClientOptions | undefined): SpanA function startCommandSpan(commandName: string, commandArgs: Array, attributes: SpanAttributes): Span { return startInactiveSpan({ name: `redis-${commandName}`, - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', ...attributes, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db', [DB_STATEMENT]: defaultDbStatementSerializer(commandName, commandArgs), @@ -272,8 +272,7 @@ function bindNodeRedisConnectChannel(): void { const options = (data.self as NodeRedisClient | undefined)?.options; return startInactiveSpan({ name: 'redis-connect', - kind: SPAN_KIND.CLIENT, - attributes: { ...nodeRedisAttributes(options), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' }, + attributes: { [SENTRY_KIND]: 'client', ...nodeRedisAttributes(options), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db' }, }); }); } @@ -289,8 +288,8 @@ function bindNodeRedisBatchChannel(channelName: string, getOperation: (data: Com const socket = (data.self as NodeRedisClient | undefined)?.options?.socket; return startInactiveSpan({ name: getOperation(data), - kind: SPAN_KIND.CLIENT, attributes: { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db.redis', [DB_SYSTEM_NAME]: DB_SYSTEM_VALUE_REDIS, diff --git a/packages/server-utils/src/integrations/tracing-channel/tedious.ts b/packages/server-utils/src/integrations/tracing-channel/tedious.ts index 99a927f5dd7e..ebcf1524d494 100644 --- a/packages/server-utils/src/integrations/tracing-channel/tedious.ts +++ b/packages/server-utils/src/integrations/tracing-channel/tedious.ts @@ -9,7 +9,6 @@ import { debug, defineIntegration, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, SPAN_STATUS_ERROR, startInactiveSpan, waitForTracingChannelBinding, @@ -21,6 +20,7 @@ import { DB_USER, NET_PEER_NAME, NET_PEER_PORT, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { DEBUG_BUILD } from '../../debug-build'; import { CHANNELS } from '../../orchestrion/channels'; @@ -129,6 +129,7 @@ function subscribeQuery(channelName: string, operation: string): void { const sql = extractSql(request); const attributes: SpanAttributes = { + [SENTRY_KIND]: 'client', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN, [DB_SYSTEM]: DB_SYSTEM_VALUE_MSSQL, [DB_NAME]: databaseName, @@ -142,7 +143,6 @@ function subscribeQuery(channelName: string, operation: string): void { const span = startInactiveSpan({ name: getSpanName(operation, databaseName, sql, request.table), - kind: SPAN_KIND.CLIENT, op: 'db', attributes, }); diff --git a/packages/server-utils/src/mongodb/mongodb-span.ts b/packages/server-utils/src/mongodb/mongodb-span.ts index 3904274a99f3..e0d2c81af579 100644 --- a/packages/server-utils/src/mongodb/mongodb-span.ts +++ b/packages/server-utils/src/mongodb/mongodb-span.ts @@ -1,5 +1,6 @@ +import { SENTRY_KIND } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes } from '@sentry/core'; -import { isObjectLike, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_KIND, startInactiveSpan } from '@sentry/core'; +import { isObjectLike, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core'; // OTel "OLD" db/net semantic-conventions, reproduced from the vendored // `@opentelemetry/instrumentation-mongodb` span shape so the orchestrion @@ -223,7 +224,9 @@ export function startMongoSpan(attributes: SpanAttributes): Span { return startInactiveSpan({ name: `mongodb.${attributes[ATTR_DB_OPERATION] || 'command'}`, op: 'db', - kind: SPAN_KIND.CLIENT, - attributes, + attributes: { + [SENTRY_KIND]: 'client', + ...attributes, + }, }); } diff --git a/packages/server-utils/src/mongoose/mongoose-legacy-span.ts b/packages/server-utils/src/mongoose/mongoose-legacy-span.ts index 301b9be210d7..a2d133c517e3 100644 --- a/packages/server-utils/src/mongoose/mongoose-legacy-span.ts +++ b/packages/server-utils/src/mongoose/mongoose-legacy-span.ts @@ -1,5 +1,6 @@ +import { SENTRY_KIND } from '@sentry/conventions/attributes'; import type { Span, SpanAttributes } from '@sentry/core'; -import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SPAN_KIND, startInactiveSpan } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core'; // OTel "OLD" db/net semantic-conventions, reproduced from the vendored // `@opentelemetry/instrumentation-mongoose` span shape. Inlined as literals to @@ -43,6 +44,7 @@ export function startMongooseLegacySpan({ parentSpan, }: StartMongooseLegacySpanOptions): Span { const attributes: SpanAttributes = { + [SENTRY_KIND]: 'client', [ATTR_DB_MONGODB_COLLECTION]: collection?.name, [ATTR_DB_NAME]: collection?.conn?.name, [ATTR_DB_USER]: collection?.conn?.user, @@ -57,7 +59,6 @@ export function startMongooseLegacySpan({ name: `mongoose.${modelName}.${operation}`, // Set this explicitly, for platforms lacking `inferDbSpanData` op: 'db', - kind: SPAN_KIND.CLIENT, attributes, parentSpan, }); diff --git a/packages/server-utils/src/prisma/tracing-helper.ts b/packages/server-utils/src/prisma/tracing-helper.ts index bef80a9acfee..c653658cc0ee 100644 --- a/packages/server-utils/src/prisma/tracing-helper.ts +++ b/packages/server-utils/src/prisma/tracing-helper.ts @@ -19,13 +19,12 @@ import { getActiveSpan, LRUMap, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SPAN_KIND, startInactiveSpan, startSpanManual, } from '@sentry/core'; import { DEBUG_BUILD } from '../debug-build'; import type { EngineSpan, ExtendedSpanOptions, SpanCallback, TracingHelper } from './types'; -import { DB_SYSTEM } from '@sentry/conventions/attributes'; +import { DB_SYSTEM, SENTRY_KIND } from '@sentry/conventions/attributes'; // Reading `process.env` can throw in runtimes that gate env access (e.g. Deno without `--allow-env`) // and `process` may be absent altogether (edge runtimes), so this degrades to `false` in those cases. @@ -135,8 +134,10 @@ function createResolvedEngineSpans(): void { const attributes = buildSpanAttributes(engineSpan.name, engineSpan.attributes); const span = startInactiveSpan({ name: buildSpanName(engineSpan.name, attributes), - attributes, - kind: engineSpan.kind === 'client' ? SPAN_KIND.CLIENT : SPAN_KIND.INTERNAL, + attributes: { + ...attributes, + [SENTRY_KIND]: engineSpan.kind === 'client' ? 'client' : undefined, + }, startTime: engineSpan.start_time, parentSpan, }); @@ -275,8 +276,10 @@ function dispatchEngineSpan( startSpanManual( { name: buildSpanName(engineSpan.name, attributes), - attributes, - kind: engineSpan.kind === 'client' ? SPAN_KIND.CLIENT : SPAN_KIND.INTERNAL, + attributes: { + ...attributes, + [SENTRY_KIND]: engineSpan.kind === 'client' ? 'client' : undefined, + }, startTime: engineSpan.startTime, }, span => { diff --git a/packages/server-utils/src/prisma/types.ts b/packages/server-utils/src/prisma/types.ts index 409d166efee9..ee29c88e0fbd 100644 --- a/packages/server-utils/src/prisma/types.ts +++ b/packages/server-utils/src/prisma/types.ts @@ -11,7 +11,7 @@ * package does not need to depend on OpenTelemetry */ -import type { Span, SpanAttributes, SpanKindValue, SpanLink, SpanTimeInput } from '@sentry/core'; +import type { Span, SpanAttributes, SpanKind, SpanLink, SpanTimeInput } from '@sentry/core'; export type SpanCallback = (span?: Span, parentSpan?: Span) => R; @@ -23,7 +23,7 @@ export interface ExtendedSpanOptions { /** Whether it propagates context (?=true) */ active?: boolean; attributes?: SpanAttributes; - kind?: SpanKindValue; + kind?: SpanKind; links?: SpanLink[]; startTime?: SpanTimeInput; } From bd55a0f56defe895a43c7cbdb4bb48f7a94f8e06 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 23 Jul 2026 10:28:02 +0200 Subject: [PATCH 2/7] unrelated --- packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts b/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts index d65ebfb01233..75f657b6601c 100644 --- a/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts +++ b/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts @@ -159,7 +159,6 @@ export class AwsInstrumentation extends InstrumentationBase Date: Thu, 23 Jul 2026 10:29:59 +0200 Subject: [PATCH 3/7] fix tests --- .../aws-serverless-layer/tests/layer.test.ts | 8 ++++---- .../test-applications/aws-serverless/tests/npm.test.ts | 4 ++-- .../nestjs-11/tests/transactions.test.ts | 2 +- .../test-applications/nestjs-8/tests/transactions.test.ts | 2 +- .../nestjs-basic/tests/transactions.test.ts | 2 +- .../nestjs-distributed-tracing/tests/propagation.test.ts | 8 ++++---- .../nestjs-fastify/tests/transactions.test.ts | 2 +- .../tests/transactions.test.ts | 2 +- .../nestjs-with-submodules/tests/transactions.test.ts | 2 +- .../nextjs-15/tests/server-components.test.ts | 2 +- .../nextjs-16-bun/tests/server-components.test.ts | 2 +- .../nextjs-16-cf-workers/tests/server-components.test.ts | 2 +- .../test-applications/nextjs-16/tests/middleware.test.ts | 2 +- .../nextjs-16/tests/server-components.test.ts | 2 +- .../nextjs-app-dir/tests/server-components.test.ts | 2 +- .../nextjs-orpc/tests/orpc-tracing.test.ts | 4 ++-- .../node-express-cjs-preload/tests/server.test.ts | 2 +- .../node-express-esm-loader/tests/server.test.ts | 2 +- .../node-express-esm-preload/tests/server.test.ts | 4 ++-- .../tests/transactions.test.ts | 2 +- .../node-express-orchestrion/tests/transactions.test.ts | 2 +- .../node-express-v5/tests/transactions.test.ts | 2 +- .../node-express/tests/transactions.test.ts | 2 +- .../node-fastify-3/tests/propagation.test.ts | 8 ++++---- .../node-fastify-3/tests/transactions.test.ts | 2 +- .../node-fastify-4/tests/propagation.test.ts | 8 ++++---- .../node-fastify-4/tests/transactions.test.ts | 2 +- .../node-fastify-5/tests/propagation.test.ts | 8 ++++---- .../node-fastify-5/tests/transactions.test.ts | 2 +- .../node-firebase/tests/functions.test.ts | 8 ++++---- .../node-firebase/tests/transactions.test.ts | 2 +- .../node-hapi/tests/transactions.test.ts | 2 +- .../test-applications/node-koa/tests/propagation.test.ts | 8 ++++---- .../test-applications/node-koa/tests/transactions.test.ts | 2 +- .../node-otel-custom-sampler/tests/sampling.test.ts | 2 +- .../node-otel-sdk-node/tests/transactions.test.ts | 2 +- .../node-otel/tests/transactions.test.ts | 2 +- .../tsx-express/tests/transactions.test.ts | 2 +- 38 files changed, 62 insertions(+), 62 deletions(-) diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts b/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts index 9c49cb2cdf7b..63b167e819fb 100644 --- a/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-serverless-layer/tests/layer.test.ts @@ -43,7 +43,7 @@ test.describe('Lambda layer', () => { 'faas.execution': expect.any(String), 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:LayerTracingCjs', 'faas.coldstart': true, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', }, op: 'function.aws.lambda', origin: 'auto.otel.aws_lambda', @@ -111,7 +111,7 @@ test.describe('Lambda layer', () => { 'faas.execution': expect.any(String), 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:LayerTracingEsm', 'faas.coldstart': true, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', }, op: 'function.aws.lambda', origin: 'auto.otel.aws_lambda', @@ -234,7 +234,7 @@ test.describe('Lambda layer', () => { 'faas.execution': expect.any(String), 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:LayerStreaming', 'faas.coldstart': true, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', }, op: 'function.aws.lambda', origin: 'auto.otel.aws_lambda', @@ -279,7 +279,7 @@ test.describe('Lambda layer', () => { data: expect.objectContaining({ 'sentry.op': 'function.aws.lambda', 'sentry.origin': 'auto.otel.aws_lambda', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:LayerCallback', }), }), diff --git a/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts b/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts index 3f07fdd9b696..2faed1e5bd52 100644 --- a/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts +++ b/dev-packages/e2e-tests/test-applications/aws-serverless/tests/npm.test.ts @@ -29,7 +29,7 @@ test.describe('NPM package', () => { 'faas.execution': expect.any(String), 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:NpmTracingCjs', 'faas.coldstart': true, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', }, op: 'function.aws.lambda', origin: 'auto.otel.aws_lambda', @@ -97,7 +97,7 @@ test.describe('NPM package', () => { 'faas.execution': expect.any(String), 'faas.id': 'arn:aws:lambda:us-east-1:012345678912:function:NpmTracingEsm', 'faas.coldstart': true, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', }, op: 'function.aws.lambda', origin: 'auto.otel.aws_lambda', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts index 31fd0c8f6970..2c27dc0cea0a 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-11/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts index 23a11f67b0a3..d35693a7bea2 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-8/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts index d6bec81e67db..ecc6b8829b58 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-basic/tests/transactions.test.ts @@ -46,7 +46,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts index 1da006fca893..46795aaaf527 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-distributed-tracing/tests/propagation.test.ts @@ -61,7 +61,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-http/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, @@ -102,7 +102,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, @@ -194,7 +194,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-fetch/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, @@ -235,7 +235,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, diff --git a/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts index d83fc351d216..818756943c5e 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-fastify/tests/transactions.test.ts @@ -25,7 +25,7 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'http.host': 'localhost:3030', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts index 344d2440a9da..56a4251a6c34 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules-decorator/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/example-module/transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/example-module/transaction', 'url.full': 'http://localhost:3030/example-module/transaction', diff --git a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts index b0b9e71a4bfe..1944e9444f3b 100644 --- a/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/nestjs-with-submodules/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction from module', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/example-module/transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/example-module/transaction', 'url.full': 'http://localhost:3030/example-module/transaction', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/server-components.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/server-components.test.ts index 2f3488976d28..1cc750a213e3 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/server-components.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/server-components.test.ts @@ -24,7 +24,7 @@ test('Sends a transaction for a request to app router with URL', async ({ page } 'http.route': '/parameterized/[one]/beep/[two]', 'http.status_code': 200, 'http.target': '/parameterized/1337/beep/42', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'next.route': '/parameterized/[one]/beep/[two]', }), op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16-bun/tests/server-components.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-16-bun/tests/server-components.test.ts index 9a5a0a7d372f..b5d88321b72f 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-16-bun/tests/server-components.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-16-bun/tests/server-components.test.ts @@ -24,7 +24,7 @@ test('Sends a transaction for a request to app router with URL', async ({ page } 'http.route': '/parameterized/[one]/beep/[two]', 'http.status_code': 200, 'http.target': '/parameterized/1337/beep/42', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'next.route': '/parameterized/[one]/beep/[two]', }), op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/server-components.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/server-components.test.ts index 1fe9a38b93e7..4aaebac51337 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/server-components.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-16-cf-workers/tests/server-components.test.ts @@ -25,7 +25,7 @@ test.skip('Sends a transaction for a request to app router with URL', async ({ p 'http.route': '/parameterized/[one]/beep/[two]', 'http.status_code': 200, 'http.target': '/parameterized/1337/beep/42', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'next.route': '/parameterized/[one]/beep/[two]', }), op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts index 6ff58ee5e586..9fea7701312b 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-16/tests/middleware.test.ts @@ -119,7 +119,7 @@ test('Should trace outgoing fetch requests inside middleware and create breadcru 'http.response.status_code': 200, 'network.peer.address': '::1', 'network.peer.port': 3030, - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.otel.node_fetch', 'server.address': 'localhost', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-16/tests/server-components.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-16/tests/server-components.test.ts index 85638d9bef68..da72685789c7 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-16/tests/server-components.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-16/tests/server-components.test.ts @@ -27,7 +27,7 @@ test('Sends a transaction for a request to app router with URL', async ({ page } 'http.route': '/parameterized/[one]/beep/[two]', 'http.status_code': 200, 'http.target': '/parameterized/1337/beep/42', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'next.route': '/parameterized/[one]/beep/[two]', }), op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts index 5aca8a0b1688..12199c8d5085 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-app-dir/tests/server-components.test.ts @@ -24,7 +24,7 @@ test('Sends a transaction for a request to app router', async ({ page }) => { 'http.route': '/server-component/parameter/[...parameters]', 'http.status_code': 200, 'http.target': '/server-component/parameter/1337/42', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'next.route': '/server-component/parameter/[...parameters]', }), op: 'http.server', diff --git a/dev-packages/e2e-tests/test-applications/nextjs-orpc/tests/orpc-tracing.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-orpc/tests/orpc-tracing.test.ts index f2863b4e5095..b379f3d7e02b 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-orpc/tests/orpc-tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-orpc/tests/orpc-tracing.test.ts @@ -35,7 +35,7 @@ test('should trace orpc server component', async ({ page }) => { 'sentry.op': 'http.server', 'sentry.origin': 'auto', 'sentry.source': 'route', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'next.span_name': 'POST /rpc/[[...rest]]/route', 'next.span_type': 'BaseServer.handleRequest', @@ -92,7 +92,7 @@ test('should trace orpc client component', async ({ page }) => { 'sentry.op': 'http.server', 'sentry.origin': 'auto', 'sentry.source': 'route', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'next.span_name': 'POST /rpc/[[...rest]]/route', 'next.span_type': 'BaseServer.handleRequest', diff --git a/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts index df5ba8e47352..cb7fbbe46f01 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-cjs-preload/tests/server.test.ts @@ -51,7 +51,7 @@ test('Should record a transaction for route with parameters', async ({ request } 'net.peer.ip': expect.any(String), 'net.peer.port': expect.any(Number), 'net.transport': 'ip_tcp', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, diff --git a/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts index e6337bf7ba83..9b1960bb4e78 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-esm-loader/tests/server.test.ts @@ -51,7 +51,7 @@ test('Should record a transaction for route with parameters', async ({ request } 'net.peer.ip': expect.any(String), 'net.peer.port': expect.any(Number), 'net.transport': 'ip_tcp', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, diff --git a/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts index 7e1b95e9e53f..393128ef9fb8 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-esm-preload/tests/server.test.ts @@ -51,7 +51,7 @@ test('Should record a transaction for route with parameters', async ({ request } 'net.peer.ip': expect.any(String), 'net.peer.port': expect.any(Number), 'net.transport': 'ip_tcp', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', 'sentry.sample_rate': 1, @@ -144,7 +144,7 @@ test('Should record spans from http instrumentation', async ({ request }) => { 'net.peer.name': 'example.com', 'net.peer.port': 80, 'net.transport': 'ip_tcp', - 'otel.kind': 'CLIENT', + 'sentry.kind': 'client', 'sentry.op': 'http.client', 'sentry.origin': 'auto.http.client', url: 'http://example.com/', diff --git a/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts index 1b9d488958c7..76f6c59bb29e 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-orchestrion-cjs/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts index cf1790853c86..2b1d6b691c35 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-orchestrion/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts index c44da1ed290f..08030a7f9852 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-v5/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts index 5d995d844f93..501b1adb29e0 100644 --- a/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-express/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts index 41028122b492..2f474eed8915 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/propagation.test.ts @@ -61,7 +61,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-http/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, @@ -102,7 +102,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, @@ -194,7 +194,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-fetch/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, @@ -235,7 +235,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts index 22b12c322169..c13b2e51af24 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-3/tests/transactions.test.ts @@ -25,7 +25,7 @@ test.skip('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts index 4b3e79b8b21d..41602ab0f6a2 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/propagation.test.ts @@ -61,7 +61,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-http/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, @@ -102,7 +102,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, @@ -194,7 +194,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-fetch/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, @@ -235,7 +235,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts index 7209031eb53c..b0341f8a2b04 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-4/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts index c7f833701f52..96c230b6eec9 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/propagation.test.ts @@ -61,7 +61,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-http/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, @@ -102,7 +102,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, @@ -194,7 +194,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-fetch/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, @@ -235,7 +235,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, diff --git a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts index f90bcf06b717..a1f342cf0df5 100644 --- a/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-fastify-5/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-firebase/tests/functions.test.ts b/dev-packages/e2e-tests/test-applications/node-firebase/tests/functions.test.ts index 2600b8bc1ec5..4bd6e4eaf3a7 100644 --- a/dev-packages/e2e-tests/test-applications/node-firebase/tests/functions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-firebase/tests/functions.test.ts @@ -19,7 +19,7 @@ test('should only call the function once without any extra calls', async () => { 'faas.name': 'helloWorld', 'faas.provider': 'firebase', 'faas.trigger': 'http.request', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.request', 'sentry.origin': 'auto.firebase.otel.functions', 'sentry.sample_rate': expect.any(Number), @@ -96,7 +96,7 @@ test('should create a document and trigger onDocumentCreated and another with au 'faas.name': 'onCallSomething', 'faas.provider': 'firebase', 'faas.trigger': 'http.request', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': 'http.request', 'sentry.origin': 'auto.firebase.otel.functions', 'sentry.sample_rate': expect.any(Number), @@ -115,7 +115,7 @@ test('should create a document and trigger onDocumentCreated and another with au 'faas.name': 'onDocumentCreate', 'faas.provider': 'firebase', 'faas.trigger': 'firestore.document.created', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': expect.any(String), 'sentry.origin': 'auto.firebase.otel.functions', 'sentry.sample_rate': expect.any(Number), @@ -134,7 +134,7 @@ test('should create a document and trigger onDocumentCreated and another with au 'faas.name': 'onDocumentCreateWithAuthContext', 'faas.provider': 'firebase', 'faas.trigger': 'firestore.document.created', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'sentry.op': expect.any(String), 'sentry.origin': 'auto.firebase.otel.functions', 'sentry.sample_rate': expect.any(Number), diff --git a/dev-packages/e2e-tests/test-applications/node-firebase/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-firebase/tests/transactions.test.ts index fa07880c87d1..ab8b44897145 100644 --- a/dev-packages/e2e-tests/test-applications/node-firebase/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-firebase/tests/transactions.test.ts @@ -21,7 +21,7 @@ function firestoreSpan(operation: string): unknown { 'sentry.op': 'db.query', }; if (!orchestrion) { - data['otel.kind'] = 'CLIENT'; + data['sentry.kind'] = 'client'; } return expect.objectContaining({ diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts index bfd71c2be730..3f6c8e10244f 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts @@ -19,7 +19,7 @@ test('Sends successful transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-success', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-success', 'url.full': 'http://localhost:3030/test-success', diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts index dcb952069bef..a892a0f6cf83 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/propagation.test.ts @@ -60,7 +60,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-http/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-http/${id}`, 'url.full': `http://localhost:3030/test-outgoing-http/${id}`, @@ -101,7 +101,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, @@ -193,7 +193,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: `http://localhost:3030/test-outgoing-fetch/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-outgoing-fetch/${id}`, 'url.full': `http://localhost:3030/test-outgoing-fetch/${id}`, @@ -234,7 +234,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => { 'sentry.origin': 'auto.http.otel.http', 'sentry.op': 'http.server', url: `http://localhost:3030/test-inbound-headers/${id}`, - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': `http://localhost:3030/test-inbound-headers/${id}`, 'url.full': `http://localhost:3030/test-inbound-headers/${id}`, diff --git a/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts index 8952ec88a8ae..028663808973 100644 --- a/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-koa/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts index 12753312cdb2..04348a3245a4 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-custom-sampler/tests/sampling.test.ts @@ -18,7 +18,7 @@ test('Sends a sampled API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.origin': 'auto.http.otel.http', url: 'http://localhost:3030/task', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/task', 'url.full': 'http://localhost:3030/task', diff --git a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts index b128a537b856..e9cc9ce152ea 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel-sdk-node/tests/transactions.test.ts @@ -32,7 +32,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/node-otel/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-otel/tests/transactions.test.ts index b77c0a610512..12f129f18c89 100644 --- a/dev-packages/e2e-tests/test-applications/node-otel/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/node-otel/tests/transactions.test.ts @@ -32,7 +32,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', diff --git a/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts index c76c7653d30f..4371f2a8178e 100644 --- a/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts +++ b/dev-packages/e2e-tests/test-applications/tsx-express/tests/transactions.test.ts @@ -20,7 +20,7 @@ test('Sends an API route transaction', async ({ baseURL }) => { 'sentry.op': 'http.server', 'sentry.sample_rate': 1, url: 'http://localhost:3030/test-transaction', - 'otel.kind': 'SERVER', + 'sentry.kind': 'server', 'http.response.status_code': 200, 'http.url': 'http://localhost:3030/test-transaction', 'url.full': 'http://localhost:3030/test-transaction', From 5cc8293b0dbc0e5c640c56e38745526f94e04d34 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 23 Jul 2026 10:30:20 +0200 Subject: [PATCH 4/7] fixes --- .../aws-serverless/src/integration/aws/vendored/aws-sdk.ts | 7 +------ packages/opentelemetry/src/applyOtelSpanData.ts | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts b/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts index 75f657b6601c..de218bc58b98 100644 --- a/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts +++ b/packages/aws-serverless/src/integration/aws/vendored/aws-sdk.ts @@ -36,12 +36,7 @@ import { import { propwrap } from './propwrap'; import { RequestMetadata } from './services/ServiceExtension'; import { HTTP_STATUS_CODE, SENTRY_KIND } from '@sentry/conventions/attributes'; -import { - SDK_VERSION, - SEMANTIC_ATTRIBUTE_SENTRY_OP, - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - startInactiveSpan, -} from '@sentry/core'; +import { SDK_VERSION, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan } from '@sentry/core'; const PACKAGE_NAME = '@sentry/instrumentation-aws-sdk'; diff --git a/packages/opentelemetry/src/applyOtelSpanData.ts b/packages/opentelemetry/src/applyOtelSpanData.ts index 61fa6a25b209..af1d621bcb64 100644 --- a/packages/opentelemetry/src/applyOtelSpanData.ts +++ b/packages/opentelemetry/src/applyOtelSpanData.ts @@ -11,7 +11,7 @@ import { SPAN_STATUS_ERROR, SPAN_STATUS_OK, } from '@sentry/core'; -import type { Span, SpanAttributes, SpanKind } from '@sentry/core'; +import type { Span, SpanAttributes } from '@sentry/core'; import { inferStatusFromAttributes, isStatusErrorMessageValid } from './utils/mapStatus'; import { inferSpanData } from './utils/parseSpanDescription'; From 48a776abc4e4a8f952dd75f41e3798c30e7e5123 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 23 Jul 2026 13:15:51 +0200 Subject: [PATCH 5/7] fixes and tests --- .../core/test/lib/tracing/spans/captureSpan.test.ts | 10 ++-------- .../wrapApiHandlerWithSentry.ts | 3 ++- .../src/common/withServerActionInstrumentation.ts | 2 ++ packages/nextjs/src/common/wrapMiddlewareWithSentry.ts | 2 ++ packages/nextjs/src/edge/index.ts | 4 +++- packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts | 3 ++- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/core/test/lib/tracing/spans/captureSpan.test.ts b/packages/core/test/lib/tracing/spans/captureSpan.test.ts index 28a3f0d48e0b..0560ebd2f702 100644 --- a/packages/core/test/lib/tracing/spans/captureSpan.test.ts +++ b/packages/core/test/lib/tracing/spans/captureSpan.test.ts @@ -424,10 +424,7 @@ describe('captureSpan', () => { captureSpan(span, client); - expect(preprocessSpanFn).toHaveBeenCalledWith( - expect.objectContaining({ span_id: span.spanContext().spanId }), - expect.objectContaining({ spanKind: undefined }), - ); + expect(preprocessSpanFn).toHaveBeenCalledWith(expect.objectContaining({ span_id: span.spanContext().spanId })); expect(processSpanFn).toHaveBeenCalledWith(expect.objectContaining({ span_id: span.spanContext().spanId })); expect(processSegmentSpanFn).toHaveBeenCalledWith( expect.objectContaining({ span_id: span.spanContext().spanId }), @@ -471,10 +468,7 @@ describe('captureSpan', () => { expect(serializedChildSpan?.name).toBe('child'); expect(serializedChildSpan?.is_segment).toBe(false); - expect(preprocessSpanFn).toHaveBeenCalledWith( - expect.objectContaining({ span_id: serializedChildSpan?.span_id }), - expect.objectContaining({ spanKind: undefined }), - ); + expect(preprocessSpanFn).toHaveBeenCalledWith(expect.objectContaining({ span_id: serializedChildSpan?.span_id })); expect(processSpanFn).toHaveBeenCalledWith(expect.objectContaining({ span_id: serializedChildSpan?.span_id })); expect(processSegmentSpanFn).not.toHaveBeenCalled(); }); diff --git a/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts index 406965ee696a..6b60d56ad866 100644 --- a/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/common/pages-router-instrumentation/wrapApiHandlerWithSentry.ts @@ -18,7 +18,7 @@ import type { NextApiRequest } from 'next'; import type { AugmentedNextApiResponse, NextApiHandler } from '../types'; import { flushSafelyWithTimeout, waitUntil } from '../utils/responseEnd'; import { dropNextjsRootContext, escapeNextjsTracing } from '../utils/tracingUtils'; -import { URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; +import { SENTRY_KIND, URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; export type AugmentedNextApiRequest = NextApiRequest & { __withSentry_applied__?: boolean; @@ -90,6 +90,7 @@ export function wrapApiHandlerWithSentry(apiHandler: NextApiHandler, parameteriz op: 'http.server', forceTransaction: true, attributes: { + [SENTRY_KIND]: 'server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nextjs', [URL_FULL]: urlObject && !isURLObjectRelative(urlObject) ? urlObject.href : undefined, diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index 370aeff2bb33..5aedfa66558f 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -17,6 +17,7 @@ import { import { flushSafelyWithTimeout, waitUntil } from '../common/utils/responseEnd'; import { DEBUG_BUILD } from './debug-build'; import { isNotFoundNavigationError, isRedirectNavigationError } from './nextNavigationErrorUtils'; +import { SENTRY_KIND } from '@sentry/conventions/attributes'; interface Options { formData?: FormData; @@ -116,6 +117,7 @@ async function withServerActionInstrumentationImplementation( name: spanName, op: 'http.server.middleware', attributes: { + [SENTRY_KIND]: 'server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: spanSource, [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.wrap_middleware', }, diff --git a/packages/nextjs/src/edge/index.ts b/packages/nextjs/src/edge/index.ts index 556a98afa439..943ba1c84f5a 100644 --- a/packages/nextjs/src/edge/index.ts +++ b/packages/nextjs/src/edge/index.ts @@ -27,6 +27,7 @@ import { flushSafelyWithTimeout, isCloudflareWaitUntilAvailable, waitUntil } fro import { setUrlProcessingMetadata } from '../common/utils/setUrlProcessingMetadata'; import { distDirRewriteFramesIntegration } from './distDirRewriteFramesIntegration'; import { enhanceMiddlewareRootSpan } from '../common/enhanceMiddlewareRootSpan'; +import { SENTRY_KIND } from '@sentry/conventions/attributes'; export * from '@sentry/vercel-edge'; export * from '../common'; @@ -125,9 +126,10 @@ export function init(options: VercelEdgeOptions = {}): void { dropMiddlewareTunnelRequests(span, spanAttributes); - // Mark all spans generated by Next.js as 'auto' + // Mark all spans generated by Next.js as 'auto' & server if (spanAttributes?.['next.span_type'] !== undefined) { span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto'); + span.setAttribute(SENTRY_KIND, 'server'); } // Make sure middleware spans get the right op diff --git a/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts b/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts index 1aac5499130f..9b5be2f7b81c 100644 --- a/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts +++ b/packages/nextjs/src/edge/wrapApiHandlerWithSentry.ts @@ -18,7 +18,7 @@ import { import { addHeadersAsAttributes } from '../common/utils/addHeadersAsAttributes'; import { flushSafelyWithTimeout, waitUntil } from '../common/utils/responseEnd'; import type { EdgeRouteHandler } from './types'; -import { URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; +import { SENTRY_KIND, URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; /** * Wraps a Next.js edge route handler with Sentry error and performance instrumentation. @@ -90,6 +90,7 @@ export function wrapApiHandlerWithSentry( name: spanName, op: op, attributes: { + [SENTRY_KIND]: 'server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.nextjs.wrap_api_handler', ...urlAttributes, From 110f7ff0d49745ec3924ee9d7ce8d8bac703717f Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 23 Jul 2026 14:30:19 +0200 Subject: [PATCH 6/7] fixes --- .../src/utils/parseSpanDescription.ts | 18 ++-- packages/opentelemetry/test/sampler.test.ts | 7 +- packages/opentelemetry/test/trace.test.ts | 8 +- .../test/utils/parseSpanDescription.test.ts | 85 ++++++++----------- 4 files changed, 51 insertions(+), 67 deletions(-) diff --git a/packages/opentelemetry/src/utils/parseSpanDescription.ts b/packages/opentelemetry/src/utils/parseSpanDescription.ts index 61cbabcd3933..545bd4fffd0c 100644 --- a/packages/opentelemetry/src/utils/parseSpanDescription.ts +++ b/packages/opentelemetry/src/utils/parseSpanDescription.ts @@ -14,7 +14,7 @@ import { SENTRY_KIND, URL_FULL, } from '@sentry/conventions/attributes'; -import type { Span, SpanAttributes, TransactionSource, SpanKind } from '@sentry/core'; +import type { Span, SpanAttributes, TransactionSource } from '@sentry/core'; import { getSanitizedUrlString, parseUrl, @@ -40,13 +40,11 @@ interface SpanDescription { * Infer the op & description for a set of name, attributes and kind of a span. */ export function inferSpanData(spanName: string, attributes: SpanAttributes): SpanDescription { - const kind = attributes[SENTRY_KIND]; - // if http.method exists, this is an http request span // eslint-disable-next-line typescript/no-deprecated const httpMethod = attributes[HTTP_REQUEST_METHOD] || attributes[HTTP_METHOD]; if (httpMethod) { - return descriptionForHttpMethod({ attributes, name: spanName, kind }, httpMethod); + return descriptionForHttpMethod({ attributes, name: spanName }, httpMethod); } // eslint-disable-next-line typescript/no-deprecated @@ -151,10 +149,11 @@ function descriptionForDbSystem({ attributes, name }: { attributes: Attributes; /** Only exported for tests. */ export function descriptionForHttpMethod( - { name, kind, attributes }: { name: string; attributes: Attributes; kind: SpanKind | undefined }, + { name, attributes }: { name: string; attributes: Attributes }, httpMethod: AttributeValue, ): SpanDescription { const opParts = ['http']; + const kind = attributes[SENTRY_KIND]; switch (kind) { case 'client': @@ -170,7 +169,7 @@ export function descriptionForHttpMethod( opParts.push('prefetch'); } - const { urlPath, url, query, fragment, hasRoute } = getSanitizedUrl(attributes, kind); + const { urlPath, url, query, fragment, hasRoute } = getSanitizedUrl(attributes); if (!urlPath) { return { ...getUserUpdatedNameAndSource(name, attributes), op: opParts.join('.') }; @@ -253,16 +252,15 @@ function getGraphqlOperationNamesFromAttribute(attr: AttributeValue): string { } /** Exported for tests only */ -export function getSanitizedUrl( - attributes: Attributes, - kind: SpanKind | undefined, -): { +export function getSanitizedUrl(attributes: Attributes): { url: string | undefined; urlPath: string | undefined; query: string | undefined; fragment: string | undefined; hasRoute: boolean; } { + const kind = attributes[SENTRY_KIND]; + // This is the relative path of the URL, e.g. /sub // eslint-disable-next-line typescript/no-deprecated const httpTarget = attributes[HTTP_TARGET]; diff --git a/packages/opentelemetry/test/sampler.test.ts b/packages/opentelemetry/test/sampler.test.ts index 95f705ce4d96..0337c43e8113 100644 --- a/packages/opentelemetry/test/sampler.test.ts +++ b/packages/opentelemetry/test/sampler.test.ts @@ -1,7 +1,7 @@ import { context, SpanKind, trace, TraceFlags } from '@opentelemetry/api'; import { TraceState } from '../src/utils/TraceState'; import { SamplingDecision } from '@opentelemetry/sdk-trace-base'; -import { HTTP_REQUEST_METHOD } from '@sentry/conventions/attributes'; +import { HTTP_REQUEST_METHOD, SENTRY_KIND } from '@sentry/conventions/attributes'; import { generateSpanId, generateTraceId } from '@sentry/core'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { @@ -205,7 +205,10 @@ describe('SentrySampler', () => { const traceId = generateTraceId(); const spanName = 'GET /health'; const spanKind = SpanKind.SERVER; - const spanAttributes = { [HTTP_REQUEST_METHOD]: 'GET' }; + const spanAttributes = { + [HTTP_REQUEST_METHOD]: 'GET', + [SENTRY_KIND]: 'server' as const, + }; const actual = sampler.shouldSample(ctx, traceId, spanName, spanKind, spanAttributes, undefined); expect(actual.decision).toBe(SamplingDecision.NOT_RECORD); diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index 75a8c7aa5624..d8e461e94fe9 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -1,6 +1,6 @@ /* eslint-disable typescript/no-deprecated */ import type { Span, TimeInput } from '@opentelemetry/api'; -import { context, ROOT_CONTEXT, SpanKind, trace, TraceFlags } from '@opentelemetry/api'; +import { context, ROOT_CONTEXT, trace, TraceFlags } from '@opentelemetry/api'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import { HTTP_METHOD, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { Event, Scope } from '@sentry/core'; @@ -253,10 +253,10 @@ describe('trace', () => { startSpan( { name: 'outer', - kind: SpanKind.CLIENT, attributes: { test1: 'test 1', test2: 2, + [SENTRY_KIND]: 'client', }, startTime: date, }, @@ -654,10 +654,10 @@ describe('trace', () => { const span = startInactiveSpan({ name: 'outer', - kind: SpanKind.CLIENT, attributes: { test1: 'test 1', test2: 2, + [SENTRY_KIND]: 'client', }, startTime: date, }); @@ -996,10 +996,10 @@ describe('trace', () => { startSpanManual( { name: 'outer', - kind: SpanKind.CLIENT, attributes: { test1: 'test 1', test2: 2, + [SENTRY_KIND]: 'client', }, startTime: date, }, diff --git a/packages/opentelemetry/test/utils/parseSpanDescription.test.ts b/packages/opentelemetry/test/utils/parseSpanDescription.test.ts index 3036d315568e..367f90777955 100644 --- a/packages/opentelemetry/test/utils/parseSpanDescription.test.ts +++ b/packages/opentelemetry/test/utils/parseSpanDescription.test.ts @@ -1,6 +1,5 @@ /* eslint-disable typescript/no-deprecated */ import type { Span } from '@opentelemetry/api'; -import { SpanKind } from '@opentelemetry/api'; import { DB_STATEMENT, DB_SYSTEM, @@ -14,6 +13,7 @@ import { HTTP_URL, MESSAGING_SYSTEM, RPC_SERVICE, + SENTRY_KIND, } from '@sentry/conventions/attributes'; import { SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import { describe, expect, it } from 'vitest'; @@ -30,7 +30,6 @@ describe('parseSpanDescription', () => { 'works without attributes & name', undefined, undefined, - undefined, { description: '', op: undefined, @@ -41,7 +40,6 @@ describe('parseSpanDescription', () => { 'works with empty attributes', {}, 'test name', - SpanKind.CLIENT, { description: 'test name', op: undefined, @@ -52,9 +50,9 @@ describe('parseSpanDescription', () => { 'works with deprecated http method', { [HTTP_METHOD]: 'GET', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'test name', op: 'http.client', @@ -65,9 +63,9 @@ describe('parseSpanDescription', () => { 'works with http method', { 'http.request.method': 'GET', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'test name', op: 'http.client', @@ -79,9 +77,9 @@ describe('parseSpanDescription', () => { { [DB_SYSTEM]: 'mysql', [DB_STATEMENT]: 'SELECT * from users', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'SELECT * from users', op: 'db', @@ -94,9 +92,9 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', [DB_SYSTEM]: 'mysql', [DB_STATEMENT]: 'SELECT * from users', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'test name', op: 'db', @@ -110,9 +108,9 @@ describe('parseSpanDescription', () => { [DB_SYSTEM]: 'mysql', [DB_STATEMENT]: 'SELECT * from users', [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'custom name', op: 'db', @@ -126,9 +124,9 @@ describe('parseSpanDescription', () => { [DB_SYSTEM]: 'mysql', [DB_STATEMENT]: 'SELECT * from users', [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'custom name', op: 'db', @@ -139,9 +137,9 @@ describe('parseSpanDescription', () => { 'works with db system without statement', { [DB_SYSTEM]: 'mysql', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'test name', op: 'db', @@ -153,9 +151,9 @@ describe('parseSpanDescription', () => { { [DB_SYSTEM_NAME]: 'postgresql', [DB_STATEMENT]: 'SELECT * from users', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'SELECT * from users', op: 'db', @@ -166,9 +164,9 @@ describe('parseSpanDescription', () => { 'works with db.system.name without statement', { [DB_SYSTEM_NAME]: 'postgresql', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'test name', op: 'db', @@ -181,9 +179,9 @@ describe('parseSpanDescription', () => { [DB_SYSTEM_NAME]: 'postgresql', [DB_SYSTEM]: 'mysql', [DB_STATEMENT]: 'SELECT * from users', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { description: 'SELECT * from users', op: 'db', @@ -196,7 +194,6 @@ describe('parseSpanDescription', () => { [RPC_SERVICE]: 'rpc-test-service', }, 'test name', - undefined, { description: 'test name', op: 'rpc', @@ -210,7 +207,6 @@ describe('parseSpanDescription', () => { [RPC_SERVICE]: 'rpc-test-service', }, 'test name', - undefined, { description: 'test name', op: 'rpc', @@ -225,7 +221,6 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', }, 'test name', - undefined, { description: 'custom name', op: 'rpc', @@ -240,7 +235,6 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', }, 'test name', - undefined, { description: 'custom name', op: 'rpc', @@ -253,7 +247,6 @@ describe('parseSpanDescription', () => { [MESSAGING_SYSTEM]: 'test-messaging-system', }, 'test name', - undefined, { description: 'test name', op: 'message', @@ -267,7 +260,6 @@ describe('parseSpanDescription', () => { [MESSAGING_SYSTEM]: 'test-messaging-system', }, 'test name', - undefined, { description: 'test name', op: 'message', @@ -282,7 +274,6 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', }, 'test name', - undefined, { description: 'custom name', op: 'message', @@ -297,7 +288,6 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', }, 'test name', - undefined, { description: 'custom name', op: 'message', @@ -310,7 +300,6 @@ describe('parseSpanDescription', () => { [FAAS_TRIGGER]: 'test-faas-trigger', }, 'test name', - undefined, { description: 'test name', op: 'test-faas-trigger', @@ -324,7 +313,6 @@ describe('parseSpanDescription', () => { [FAAS_TRIGGER]: 'test-faas-trigger', }, 'test name', - undefined, { description: 'test name', op: 'test-faas-trigger', @@ -339,7 +327,6 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', }, 'test name', - undefined, { description: 'custom name', op: 'test-faas-trigger', @@ -354,15 +341,14 @@ describe('parseSpanDescription', () => { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', }, 'test name', - undefined, { description: 'custom name', op: 'test-faas-trigger', source: 'component', }, ], - ])('%s', (_, attributes, name, kind, expected) => { - const actual = parseSpanDescription({ attributes, kind, name } as unknown as Span); + ])('%s', (_, attributes, name, expected) => { + const actual = parseSpanDescription({ attributes, name } as unknown as Span); expect(actual).toEqual(expected); }); }); @@ -374,9 +360,8 @@ describe('descriptionForHttpMethod', () => { 'GET', {}, 'test name', - SpanKind.CLIENT, { - op: 'http.client', + op: 'http', description: 'test name', source: 'custom', }, @@ -388,9 +373,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_METHOD]: 'GET', [HTTP_URL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client', description: 'GET https://www.example.com/my-path', @@ -408,9 +393,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_URL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', 'sentry.http.prefetch': true, + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client.prefetch', description: 'GET https://www.example.com/my-path', @@ -427,9 +412,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_METHOD]: 'POST', [HTTP_URL]: 'https://www.example.com/my-path', [HTTP_TARGET]: '/my-path', + [SENTRY_KIND]: 'server', }, 'test name', - SpanKind.SERVER, { op: 'http.server', description: 'POST /my-path', @@ -447,9 +432,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_URL]: 'https://www.example.com/my-path/123', [HTTP_TARGET]: '/my-path/123', [HTTP_ROUTE]: '/my-path/:id', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client', description: 'GET /my-path/:id', @@ -460,7 +445,7 @@ describe('descriptionForHttpMethod', () => { }, ], [ - 'works with basic client GET with SpanKind.INTERNAL', + 'works with basic client GET without span kind', 'GET', { [HTTP_METHOD]: 'GET', @@ -468,7 +453,6 @@ describe('descriptionForHttpMethod', () => { [HTTP_TARGET]: '/my-path', }, 'test name', - SpanKind.INTERNAL, { op: 'http', description: 'test name', @@ -487,9 +471,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_TARGET]: '/my-path/123', [HTTP_ROUTE]: '/my-path/:id', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client', description: 'test name', @@ -509,9 +493,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_ROUTE]: '/my-path/:id', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client', description: 'custom name', @@ -531,9 +515,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_ROUTE]: '/my-path/:id', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client', description: 'custom name', @@ -550,9 +534,9 @@ describe('descriptionForHttpMethod', () => { [HTTP_METHOD]: 'GET', [HTTP_URL]: 'https://www.example.com/my-path?id=1#section', [HTTP_TARGET]: '/my-path?id=1#section', + [SENTRY_KIND]: 'client', }, 'test name', - SpanKind.CLIENT, { op: 'http.client', description: 'GET https://www.example.com/my-path', @@ -564,8 +548,8 @@ describe('descriptionForHttpMethod', () => { source: 'url', }, ], - ])('%s', (_, httpMethod, attributes, name, kind, expected) => { - const actual = descriptionForHttpMethod({ attributes, kind, name }, httpMethod); + ])('%s', (_, httpMethod, attributes, name, expected) => { + const actual = descriptionForHttpMethod({ attributes, name }, httpMethod); expect(actual).toEqual(expected); }); }); @@ -575,7 +559,6 @@ describe('getSanitizedUrl', () => { [ 'works without attributes', {}, - SpanKind.CLIENT, { urlPath: undefined, url: undefined, @@ -592,8 +575,8 @@ describe('getSanitizedUrl', () => { [HTTP_TARGET]: '/?what=true', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'client', }, - SpanKind.CLIENT, { urlPath: 'http://example.com/', url: 'http://example.com/', @@ -610,8 +593,8 @@ describe('getSanitizedUrl', () => { [HTTP_TARGET]: '/sub#hash', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'client', }, - SpanKind.CLIENT, { urlPath: 'http://example.com/sub', url: 'http://example.com/sub', @@ -629,8 +612,8 @@ describe('getSanitizedUrl', () => { [HTTP_ROUTE]: '/my-route', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'client', }, - SpanKind.CLIENT, { urlPath: '/my-route', url: 'http://example.com/', @@ -646,8 +629,8 @@ describe('getSanitizedUrl', () => { [HTTP_TARGET]: '/?what=true', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'client', }, - SpanKind.CLIENT, { urlPath: '/', url: undefined, @@ -664,8 +647,8 @@ describe('getSanitizedUrl', () => { [HTTP_TARGET]: '/?what=true', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'server', }, - SpanKind.SERVER, { urlPath: '/', url: 'http://example.com/', @@ -682,8 +665,8 @@ describe('getSanitizedUrl', () => { [HTTP_TARGET]: '/sub#hash', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'server', }, - SpanKind.SERVER, { urlPath: '/sub', url: 'http://example.com/', @@ -701,8 +684,8 @@ describe('getSanitizedUrl', () => { [HTTP_ROUTE]: '/my-route', [HTTP_HOST]: 'example.com:80', [HTTP_STATUS_CODE]: 200, + [SENTRY_KIND]: 'server', }, - SpanKind.SERVER, { urlPath: '/my-route', url: 'http://example.com/', @@ -711,8 +694,8 @@ describe('getSanitizedUrl', () => { hasRoute: true, }, ], - ])('%s', (_, attributes, kind, expected) => { - const actual = getSanitizedUrl(attributes, kind); + ])('%s', (_, attributes, expected) => { + const actual = getSanitizedUrl(attributes); expect(actual).toEqual(expected); }); From 0d264ab832a153ac60b6c786ebf76e8155a089a5 Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 23 Jul 2026 14:58:10 +0200 Subject: [PATCH 7/7] fixes --- packages/nextjs/test/config/withSentry.test.ts | 3 ++- packages/opentelemetry/test/trace.test.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/test/config/withSentry.test.ts b/packages/nextjs/test/config/withSentry.test.ts index bcc19a1ef568..9f6f3dc83040 100644 --- a/packages/nextjs/test/config/withSentry.test.ts +++ b/packages/nextjs/test/config/withSentry.test.ts @@ -1,5 +1,5 @@ import * as SentryCore from '@sentry/core'; -import { URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; +import { SENTRY_KIND, URL_FULL, URL_PATH } from '@sentry/conventions/attributes'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import type { NextApiRequest, NextApiResponse } from 'next'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; @@ -51,6 +51,7 @@ describe('withSentry', () => { op: 'http.server', forceTransaction: true, attributes: { + [SENTRY_KIND]: 'server', [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.nextjs', [URL_FULL]: 'https://dogs.are.great/api/dogs?good=true', diff --git a/packages/opentelemetry/test/trace.test.ts b/packages/opentelemetry/test/trace.test.ts index d8e461e94fe9..dcc1b1aaf118 100644 --- a/packages/opentelemetry/test/trace.test.ts +++ b/packages/opentelemetry/test/trace.test.ts @@ -1,6 +1,6 @@ /* eslint-disable typescript/no-deprecated */ import type { Span, TimeInput } from '@opentelemetry/api'; -import { context, ROOT_CONTEXT, trace, TraceFlags } from '@opentelemetry/api'; +import { context, ROOT_CONTEXT, trace, TraceFlags } from '@opentelemetry/api'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import { HTTP_METHOD, SENTRY_KIND } from '@sentry/conventions/attributes'; import type { Event, Scope } from '@sentry/core';