diff --git a/packages/opentelemetry-node/CHANGELOG.md b/packages/opentelemetry-node/CHANGELOG.md index 93b5e222..2de3a510 100644 --- a/packages/opentelemetry-node/CHANGELOG.md +++ b/packages/opentelemetry-node/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- feat: Default to stable semantic conventions for HTTP instrumentation. + (https://github.com/elastic/elastic-otel-node/pull/669) + - Upgrade upstream OTel dependencies to SDK 2.0. This should be non-breaking for users of `node --import @elastic/opentelemetry-node my-app.js` to start EDOT Node.js for their application. diff --git a/packages/opentelemetry-node/lib/instrumentations.js b/packages/opentelemetry-node/lib/instrumentations.js index 02f8b7fa..68a01248 100644 --- a/packages/opentelemetry-node/lib/instrumentations.js +++ b/packages/opentelemetry-node/lib/instrumentations.js @@ -259,6 +259,17 @@ function getInstrumentations(opts = {}) { 'OTEL_NODE_DISABLED_INSTRUMENTATIONS' ); + // `@opentelemetry/instrumentation-http` defaults to emit old semconv attributes. + // Set the default to stable HTTP semconv if not defined by the user (http, http/dup) + // TODO: remove this once https://github.com/open-telemetry/opentelemetry-js/pull/5552 + // is merged and published. + const semconvOptIn = + getStringListFromEnv('OTEL_SEMCONV_STABILITY_OPT_IN') || []; + if (!semconvOptIn.includes('http') && !semconvOptIn.includes('http/dup')) { + semconvOptIn.push('http'); + process.env.OTEL_SEMCONV_STABILITY_OPT_IN = semconvOptIn.join(','); + } + Object.keys(instrumentationsMap).forEach((name) => { // Skip if env has an `enabled` list and does not include this one if (enabledFromEnv && !enabledFromEnv.includes(name)) { diff --git a/packages/opentelemetry-node/test/instr-aws-sdk.test.js b/packages/opentelemetry-node/test/instr-aws-sdk.test.js index 3620941d..b2f8d965 100644 --- a/packages/opentelemetry-node/test/instr-aws-sdk.test.js +++ b/packages/opentelemetry-node/test/instr-aws-sdk.test.js @@ -10,7 +10,7 @@ const http = require('http'); const path = require('path'); const test = require('tape'); -const {runTestFixtures} = require('./testutils'); +const {runTestFixtures, filterOutGcpDetectorSpans} = require('./testutils'); const TEST_REGION = 'us-east-2'; @@ -41,7 +41,7 @@ const testFixtures = [ // span b592a3 "manual-parent-span" (26.1ms, SPAN_KIND_INTERNAL) // +4ms `- span bbe07e "S3.ListBuckets" (21.5ms, SPAN_KIND_CLIENT) // +10ms `- span b3b885 "GET" (7.0ms, SPAN_KIND_CLIENT, GET http://localhost:4566/?x-id=ListBuckets -> 200) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 2); t.equal( @@ -77,7 +77,7 @@ const testFixtures = [ // span b592a3 "manual-parent-span" (26.1ms, SPAN_KIND_INTERNAL) // +4ms `- span bbe07e "SNS ListBuckets" (21.5ms, SPAN_KIND_CLIENT) // +10ms `- span b3b885 "POST" (7.0ms, SPAN_KIND_CLIENT, POST http://localhost:4566/ -> 200) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 2); t.equal( @@ -114,7 +114,7 @@ const testFixtures = [ // span b592a3 "manual-parent-span" (26.1ms, SPAN_KIND_INTERNAL) // +4ms `- span bbe07e "SQS.ListQueues" (21.5ms, SPAN_KIND_CLIENT) // +10ms `- span b3b885 "POST" (7.0ms, SPAN_KIND_CLIENT, POST http://localhost:4566/ -> 200) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 2); t.equal( @@ -152,7 +152,7 @@ const testFixtures = [ // span b592a3 "manual-parent-span" (26.1ms, SPAN_KIND_INTERNAL) // +4ms `- span bbe07e "DynamoDB.ListTables" (21.5ms, SPAN_KIND_CLIENT) // +10ms `- span b3b885 "POST" (7.0ms, SPAN_KIND_CLIENT, POST http://localhost:4566/ -> 200) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 2); t.equal( diff --git a/packages/opentelemetry-node/test/instr-elastic-openai.test.js b/packages/opentelemetry-node/test/instr-elastic-openai.test.js index b9c9c860..b70ead1f 100644 --- a/packages/opentelemetry-node/test/instr-elastic-openai.test.js +++ b/packages/opentelemetry-node/test/instr-elastic-openai.test.js @@ -7,7 +7,11 @@ const http = require('http'); const {basename} = require('path'); const test = require('tape'); const semver = require('semver'); -const {runTestFixtures, assertDeepMatch} = require('./testutils'); +const { + runTestFixtures, + filterOutGcpDetectorSpans, + assertDeepMatch, +} = require('./testutils'); let skip = process.env.TEST_GENAI_MODEL === undefined; if (skip) { @@ -35,7 +39,7 @@ const testFixtures = [ // Expected a trace like this: // span 7e8ca8 "embeddings all-minilm:22m" (26.4ms, SPAN_KIND_CLIENT, GenAI openai) // +9ms `- span 39fc32 "POST" (16.7ms, SPAN_KIND_CLIENT, POST http://127.0.0.1:11434/v1/embeddings -> 200) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); assertDeepMatch( t, spans, @@ -58,7 +62,7 @@ const testFixtures = [ name: 'POST', parentSpanId: spans[0].spanId, attributes: { - 'http.target': '/v1/embeddings', + 'url.full': 'http://127.0.0.1:11434/v1/embeddings', }, scope: { name: '@opentelemetry/instrumentation-http', diff --git a/packages/opentelemetry-node/test/instr-elasticsearch.test.js b/packages/opentelemetry-node/test/instr-elasticsearch.test.js index 13aeb844..7900933d 100644 --- a/packages/opentelemetry-node/test/instr-elasticsearch.test.js +++ b/packages/opentelemetry-node/test/instr-elasticsearch.test.js @@ -7,7 +7,11 @@ // and later. const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); const skip = process.env.ES_URL === undefined; if (skip) { @@ -20,7 +24,9 @@ function checkTelemetry(t, col) { // Expected a trace like this: // span 91a6b1 "search" (13.4ms, SPAN_KIND_CLIENT, GET http://localhost:9200/) // +2ms `- span 14278c "GET" (10.8ms, SPAN_KIND_CLIENT, GET http://localhost:9200/_search?q=pants -> 200) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 2); t.equal(spans[0].name, 'search'); t.equal(spans[0].kind, 'SPAN_KIND_CLIENT', 'kind'); diff --git a/packages/opentelemetry-node/test/instr-express.test.js b/packages/opentelemetry-node/test/instr-express.test.js index 3fa9473e..a5e523db 100644 --- a/packages/opentelemetry-node/test/instr-express.test.js +++ b/packages/opentelemetry-node/test/instr-express.test.js @@ -10,6 +10,7 @@ const { filterOutDnsNetSpans, runTestFixtures, findObjInArray, + filterOutGcpDetectorSpans, } = require('./testutils'); /** @type {import('./testutils').TestFixture[]} */ @@ -36,7 +37,9 @@ const testFixtures = [ // +0ms `- span 2092ee "middleware - query" (0.1ms, SPAN_KIND_INTERNAL) // +0ms `- span 033a59 "middleware - expressInit" (0.1ms, SPAN_KIND_INTERNAL) // +1ms `- span 5573dc "request handler - /hi/:name" (0.0ms, SPAN_KIND_INTERNAL) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 10); t.equal(spans[0].scope.name, '@opentelemetry/instrumentation-http'); diff --git a/packages/opentelemetry-node/test/instr-fastify.test.js b/packages/opentelemetry-node/test/instr-fastify.test.js index 5ba4dc1f..a26e42d7 100644 --- a/packages/opentelemetry-node/test/instr-fastify.test.js +++ b/packages/opentelemetry-node/test/instr-fastify.test.js @@ -10,6 +10,7 @@ const { filterOutDnsNetSpans, runTestFixtures, findObjInArray, + filterOutGcpDetectorSpans, } = require('./testutils'); /** @type {import('./testutils').TestFixture[]} */ @@ -27,7 +28,9 @@ const testFixtures = [ }, // verbose: true, checkTelemetry: (t, col) => { - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 4); t.ok( @@ -70,7 +73,9 @@ const testFixtures = [ // span 6e0fc9 "GET" (1.6ms, SPAN_KIND_CLIENT, GET http://localhost:3000/hi/Bob -> 200) // +1ms `- span 40c4a8 "GET /hi/:name" (0.3ms, SPAN_KIND_SERVER, GET http://localhost:3000/hi/Bob -> 200) // +0ms `- span 74a68a "request handler - fastify" (0.1ms, SPAN_KIND_INTERNAL) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 6); t.equal(spans[0].scope.name, '@opentelemetry/instrumentation-http'); diff --git a/packages/opentelemetry-node/test/instr-grpc.test.js b/packages/opentelemetry-node/test/instr-grpc.test.js index d6a1911d..0cdbc4a8 100644 --- a/packages/opentelemetry-node/test/instr-grpc.test.js +++ b/packages/opentelemetry-node/test/instr-grpc.test.js @@ -6,7 +6,11 @@ // Test that instrumentation-grpc generates the telemetry we expect. const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + runTestFixtures, + filterOutGcpDetectorSpans, +} = require('./testutils'); /** @type {import('./testutils').TestFixture[]} */ const testFixtures = [ @@ -19,7 +23,9 @@ const testFixtures = [ }, // verbose: true, checkTelemetry: (t, col) => { - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 2); t.equal(spans[0].kind, 'SPAN_KIND_CLIENT'); t.equal(spans[1].kind, 'SPAN_KIND_SERVER'); diff --git a/packages/opentelemetry-node/test/instr-hapi.test.js b/packages/opentelemetry-node/test/instr-hapi.test.js index e743e238..fc2c63c7 100644 --- a/packages/opentelemetry-node/test/instr-hapi.test.js +++ b/packages/opentelemetry-node/test/instr-hapi.test.js @@ -6,7 +6,11 @@ // Test that 'hapi' instrumentation generates the telemetry we expect. const test = require('tape'); -const {runTestFixtures, findObjInArray} = require('./testutils'); +const { + runTestFixtures, + findObjInArray, + filterOutGcpDetectorSpans, +} = require('./testutils'); /** @type {import('./testutils').TestFixture[]} */ const testFixtures = [ @@ -31,7 +35,7 @@ const testFixtures = [ // span 9a96c1 "GET" (2.0ms, SPAN_KIND_CLIENT, GET http://localhost:3000/hi/Bob -> 200) // +1ms `- span dfacba "GET /hi/{name}" (0.5ms, SPAN_KIND_SERVER, GET http://localhost:3000/hi/Bob -> 200) // +0ms `- span 71a126 "route - /hi/{name}" (0.0ms, SPAN_KIND_INTERNAL, GET) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 6); t.equal(spans[0].scope.name, '@opentelemetry/instrumentation-http'); diff --git a/packages/opentelemetry-node/test/instr-http.test.js b/packages/opentelemetry-node/test/instr-http.test.js index 91dd1238..be65567b 100644 --- a/packages/opentelemetry-node/test/instr-http.test.js +++ b/packages/opentelemetry-node/test/instr-http.test.js @@ -6,12 +6,12 @@ // Test that 'http' instrumentation generates the telemetry we expect. const test = require('tape'); -const {runTestFixtures} = require('./testutils'); +const {runTestFixtures, filterOutGcpDetectorSpans} = require('./testutils'); /** @type {import('./testutils').TestFixture[]} */ const testFixtures = [ { - name: 'http.get', + name: 'http.get (stable HTTP semconv if env not set)', args: ['./fixtures/use-http-get.js'], cwd: __dirname, env: { @@ -19,31 +19,93 @@ const testFixtures = [ }, // verbose: true, checkTelemetry: (t, col) => { - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); + t.equal(spans.length, 1); + const span = spans[0]; + t.equal(span.scope.name, '@opentelemetry/instrumentation-http'); + t.equal(span.name, 'GET'); + t.equal(span.kind, 'SPAN_KIND_CLIENT'); + t.equal(span.attributes['http.url'], undefined); + t.equal(span.attributes['url.full'], 'http://www.google.com/'); + }, + }, + { + name: 'http.get (stable HTTP semconv if env set with other values)', + args: ['./fixtures/use-http-get.js'], + cwd: __dirname, + env: { + NODE_OPTIONS: '--require=@elastic/opentelemetry-node', + OTEL_SEMCONV_STABILITY_OPT_IN: 'db/dup,foo', + }, + // verbose: true, + checkTelemetry: (t, col) => { + const spans = filterOutGcpDetectorSpans(col.sortedSpans); + t.equal(spans.length, 1); + const span = spans[0]; + t.equal(span.scope.name, '@opentelemetry/instrumentation-http'); + t.equal(span.name, 'GET'); + t.equal(span.kind, 'SPAN_KIND_CLIENT'); + t.equal(span.attributes['http.url'], undefined); + t.equal(span.attributes['url.full'], 'http://www.google.com/'); + }, + }, + { + name: 'https.get (stable HTTP semconv if env not set)', + args: ['./fixtures/use-https-get.js'], + cwd: __dirname, + env: { + NODE_OPTIONS: '--require=@elastic/opentelemetry-node', + }, + // verbose: true, + checkTelemetry: (t, col) => { + const spans = filterOutGcpDetectorSpans(col.sortedSpans); + t.equal(spans.length, 1); + const span = spans[0]; + t.equal(span.scope.name, '@opentelemetry/instrumentation-http'); + t.equal(span.name, 'GET'); + t.equal(span.kind, 'SPAN_KIND_CLIENT'); + t.equal(span.attributes['http.url'], undefined); + t.equal(span.attributes['url.full'], 'https://www.google.com/'); + }, + }, + { + name: 'http.get (dual HTTP semconv if user set in env)', + args: ['./fixtures/use-http-get.js'], + cwd: __dirname, + env: { + NODE_OPTIONS: '--require=@elastic/opentelemetry-node', + OTEL_SEMCONV_STABILITY_OPT_IN: 'http/dup', + }, + // verbose: true, + checkTelemetry: (t, col) => { + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 1); const span = spans[0]; t.equal(span.scope.name, '@opentelemetry/instrumentation-http'); t.equal(span.name, 'GET'); t.equal(span.kind, 'SPAN_KIND_CLIENT'); t.equal(span.attributes['http.url'], 'http://www.google.com/'); + t.equal(span.attributes['url.full'], 'http://www.google.com/'); }, }, { - name: 'https.get', + name: 'https.get (dual HTTP semconv if user set in env)', args: ['./fixtures/use-https-get.js'], cwd: __dirname, env: { NODE_OPTIONS: '--require=@elastic/opentelemetry-node', + OTEL_SEMCONV_STABILITY_OPT_IN: 'http/dup', }, // verbose: true, checkTelemetry: (t, col) => { - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 1); const span = spans[0]; t.equal(span.scope.name, '@opentelemetry/instrumentation-http'); t.equal(span.name, 'GET'); t.equal(span.kind, 'SPAN_KIND_CLIENT'); t.equal(span.attributes['http.url'], 'https://www.google.com/'); + t.equal(span.attributes['url.full'], 'https://www.google.com/'); }, }, { @@ -52,6 +114,7 @@ const testFixtures = [ cwd: __dirname, env: { NODE_OPTIONS: '--require=@elastic/opentelemetry-node', + OTEL_SEMCONV_STABILITY_OPT_IN: 'http/dup', }, // verbose: true, checkTelemetry: (t, col) => { @@ -62,7 +125,7 @@ const testFixtures = [ // ------ trace b8467d (2 spans) ------ // span bc8a2c "POST" (3.8ms, SPAN_KIND_CLIENT, POST http://127.0.0.1:64972/echo -> 200) // +2ms `- span 4e7adf "POST" (1.1ms, SPAN_KIND_SERVER, POST http://127.0.0.1:64972/echo -> 200) - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 4); t.equal(spans[0].scope.name, '@opentelemetry/instrumentation-http'); t.equal(spans[0].name, 'GET'); diff --git a/packages/opentelemetry-node/test/instr-mongodb.test.js b/packages/opentelemetry-node/test/instr-mongodb.test.js index 31a832af..ae5ca488 100644 --- a/packages/opentelemetry-node/test/instr-mongodb.test.js +++ b/packages/opentelemetry-node/test/instr-mongodb.test.js @@ -6,7 +6,11 @@ // Test that 'mongodb' instrumentation generates the telemetry we expect. const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); let skip = process.env.MONGODB_HOST === undefined; if (skip) { @@ -36,7 +40,9 @@ const testFixtures = [ // +13ms `- span 1e5ee2 "mongodb.insert" (1.4ms, SPAN_KIND_CLIENT) // +3ms `- span 3d4723 "mongodb.delete" (0.6ms, SPAN_KIND_CLIENT) // +1ms `- span 1c1373 "mongodb.endSessions" (0.3ms, SPAN_KIND_CLIENT) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 4); t.equal(spans[0].name, 'manual-parent-span'); diff --git a/packages/opentelemetry-node/test/instr-mongoose.test.js b/packages/opentelemetry-node/test/instr-mongoose.test.js index e5b900c8..38197d9f 100644 --- a/packages/opentelemetry-node/test/instr-mongoose.test.js +++ b/packages/opentelemetry-node/test/instr-mongoose.test.js @@ -6,7 +6,11 @@ // Test that 'mongoose' instrumentation generates the telemetry we expect. const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); let skip = process.env.MONGODB_HOST === undefined; if (skip) { @@ -40,7 +44,9 @@ const testFixtures = [ // +13ms `- span 5be842 "mongodb.drop" (0.8ms, SPAN_KIND_CLIENT) // +1ms `- span 13d56b "mongodb.endSessions" (0.3ms, SPAN_KIND_CLIENT) // -20ms `- span c4e688 "mongoose.User.save" (18.9ms, SPAN_KIND_CLIENT) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 7); t.equal(spans[0].name, 'manual-parent-span'); diff --git a/packages/opentelemetry-node/test/instr-mysql.test.js b/packages/opentelemetry-node/test/instr-mysql.test.js index 6d635955..8b49e804 100644 --- a/packages/opentelemetry-node/test/instr-mysql.test.js +++ b/packages/opentelemetry-node/test/instr-mysql.test.js @@ -6,7 +6,11 @@ // Test that 'mysql' instrumentation generates the telemetry we expect. const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); let skip = process.env.MYSQL_HOST === undefined; if (skip) { @@ -31,7 +35,9 @@ const testFixtures = [ // span 8ef53e "manual-parent-span" (21.7ms, SPAN_KIND_INTERNAL) // +1ms `- span 715182 "tcp.connect" (9.4ms, SPAN_KIND_INTERNAL) // +2ms `- span 430253 "SELECT" (18.2ms, SPAN_KIND_CLIENT) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 2); t.equal(spans[0].name, 'manual-parent-span'); diff --git a/packages/opentelemetry-node/test/instr-mysql2.test.js b/packages/opentelemetry-node/test/instr-mysql2.test.js index dda1f39a..c4694be4 100644 --- a/packages/opentelemetry-node/test/instr-mysql2.test.js +++ b/packages/opentelemetry-node/test/instr-mysql2.test.js @@ -6,7 +6,11 @@ // Test that 'mysql2' instrumentation generates the telemetry we expect. const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); let skip = process.env.MYSQL_HOST === undefined; if (skip) { @@ -31,7 +35,9 @@ const testFixtures = [ // span 8ef53e "manual-parent-span" (21.7ms, SPAN_KIND_INTERNAL) // +1ms `- span 715182 "tcp.connect" (9.4ms, SPAN_KIND_INTERNAL) // +2ms `- span 430253 "SELECT" (18.2ms, SPAN_KIND_CLIENT) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 2); t.equal(spans[0].name, 'manual-parent-span'); diff --git a/packages/opentelemetry-node/test/instr-pg.test.js b/packages/opentelemetry-node/test/instr-pg.test.js index 1c0f2bf9..be1b5f3d 100644 --- a/packages/opentelemetry-node/test/instr-pg.test.js +++ b/packages/opentelemetry-node/test/instr-pg.test.js @@ -4,7 +4,11 @@ */ const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); const skip = process.env.PGHOST === undefined; if (skip) { @@ -29,7 +33,9 @@ const testFixtures = [ // span 102150 "manual-parent-span" (7.5ms, SPAN_KIND_INTERNAL) // +3ms `- span 539d9d "pg.connect" (12.0ms, SPAN_KIND_CLIENT) // +13ms `- span 115c08 "pg.query:SELECT postgres" (2.4ms, SPAN_KIND_CLIENT) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 3); spans.slice(1).forEach((s) => { t.equal(s.traceId, spans[0].traceId, 'traceId'); diff --git a/packages/opentelemetry-node/test/instr-tedious.test.js b/packages/opentelemetry-node/test/instr-tedious.test.js index 54f08432..ee7db60b 100644 --- a/packages/opentelemetry-node/test/instr-tedious.test.js +++ b/packages/opentelemetry-node/test/instr-tedious.test.js @@ -5,7 +5,11 @@ const test = require('tape'); const semver = require('semver'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + filterOutGcpDetectorSpans, + runTestFixtures, +} = require('./testutils'); const tediousVer = require('tedious/package.json').version; let skip = process.env.MSSQL_HOST === undefined; @@ -45,7 +49,9 @@ const testFixtures = [ // ------ trace d1755e (2 spans) ------ // span 6bb8d8 "manual-parent-span" (54.3ms, SPAN_KIND_INTERNAL) // +51ms `- span fb837e "execSql master" (3.0ms, SPAN_KIND_CLIENT) - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 2); const s = spans.pop(); diff --git a/packages/opentelemetry-node/test/instr-undici.test.js b/packages/opentelemetry-node/test/instr-undici.test.js index fc055182..73817989 100644 --- a/packages/opentelemetry-node/test/instr-undici.test.js +++ b/packages/opentelemetry-node/test/instr-undici.test.js @@ -6,7 +6,11 @@ const {satisfies} = require('semver'); const test = require('tape'); -const {filterOutDnsNetSpans, runTestFixtures} = require('./testutils'); +const { + filterOutDnsNetSpans, + runTestFixtures, + filterOutGcpDetectorSpans, +} = require('./testutils'); function getNodeVerRangeForCurrUndici() { const undiciVer = require('undici/package.json').version; @@ -34,7 +38,9 @@ const testFixtures = [ }, // verbose: true, checkTelemetry: (t, col) => { - const spans = filterOutDnsNetSpans(col.sortedSpans); + const spans = filterOutGcpDetectorSpans( + filterOutDnsNetSpans(col.sortedSpans) + ); t.equal(spans.length, 1); const span = spans[0]; t.equal(span.scope.name, '@opentelemetry/instrumentation-undici'); @@ -56,7 +62,7 @@ const testFixtures = [ }, // verbose: true, checkTelemetry: (t, col) => { - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 1); const span = spans[0]; t.equal(span.scope.name, '@opentelemetry/instrumentation-undici'); @@ -84,7 +90,7 @@ const testFixtures = [ }, // verbose: true, checkTelemetry: (t, col) => { - const spans = col.sortedSpans; + const spans = filterOutGcpDetectorSpans(col.sortedSpans); t.equal(spans.length, 1); const span = spans[0]; t.equal(span.scope.name, '@opentelemetry/instrumentation-undici'); diff --git a/packages/opentelemetry-node/test/testutils.js b/packages/opentelemetry-node/test/testutils.js index 6345fbf1..7deb2f55 100644 --- a/packages/opentelemetry-node/test/testutils.js +++ b/packages/opentelemetry-node/test/testutils.js @@ -84,6 +84,26 @@ function filterOutDnsNetSpans(spans) { ); } +/** + * Filter out HTTP spans from GCP resource detector + * Temporary solution until https://github.com/open-telemetry/opentelemetry-js-contrib/issues/2320 + * is completed. + * + * @param {CollectedSpan[]} spans + * @returns {CollectedSpan[]} + */ +function filterOutGcpDetectorSpans(spans) { + // Filter out GCP resource detector spans for testing. + return spans.filter((s) => { + if (s.scope.name !== '@opentelemetry/instrumentation-http') { + return true; + } + const urlAttr = + s.attributes['http.url'] || s.attributes['url.full'] || ''; + return !urlAttr.endsWith('/computeMetadata/v1/instance'); + }); +} + /** * Lookup the property "str" (given in dot-notation) in the object "obj". * If the property isn't found, then `undefined` is returned. @@ -374,7 +394,8 @@ class TestCollector { }); }); }); - spans.sort((a, b) => { + + return spans.sort((a, b) => { assert(typeof a.startTimeUnixNano === 'string'); assert(typeof b.startTimeUnixNano === 'string'); let aStartInt = BigInt(a.startTimeUnixNano); @@ -395,15 +416,6 @@ class TestCollector { return aStartInt < bStartInt ? -1 : aStartInt > bStartInt ? 1 : 0; }); - - // NOTE: Ignore spans from the GCP detector for testing. It shouldn't be - // creating spans, but that should be fixed upstream. - return spans.filter((s) => { - const attrs = s.attributes; - const url = attrs && attrs['http.url']; - // GCP detector does request to a specific path - return !url || !url.endsWith('/computeMetadata/v1/instance'); - }); } get metrics() { @@ -687,6 +699,7 @@ function runTestFixtures(suite, testFixtures) { module.exports = { assertDeepMatch, filterOutDnsNetSpans, + filterOutGcpDetectorSpans, dottedLookup, findObjInArray, findObjsInArray,