From fb72f26f32e35609e21c8109e21867f90a65f1fe Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Mon, 25 Nov 2024 10:20:12 -0500 Subject: [PATCH 1/5] parametric: otelkind start enum count from 0 --- tests/parametric/test_otel_span_methods.py | 4 +- tests/parametric/test_parametric_endpoints.py | 4 +- .../parametric/Endpoints/ApmTestApiOtel.cs | 10 ++--- utils/build/docker/golang/parametric/otel.go | 2 +- .../controller/OpenTelemetryController.java | 10 ++--- .../build/docker/nodejs/parametric/server.js | 13 +++++- utils/build/docker/php/parametric/server.php | 10 ++--- .../parametric/apm_test_client/server.py | 5 +-- utils/build/docker/ruby/parametric/server.rb | 10 ++--- utils/dd_constants.py | 41 +------------------ utils/parametric/_library_client.py | 2 +- 11 files changed, 40 insertions(+), 71 deletions(-) diff --git a/tests/parametric/test_otel_span_methods.py b/tests/parametric/test_otel_span_methods.py index 63b3ded69b..7a5b0b76b0 100644 --- a/tests/parametric/test_otel_span_methods.py +++ b/tests/parametric/test_otel_span_methods.py @@ -5,8 +5,8 @@ from typing import Union from utils.parametric._library_client import Link -from utils.dd_constants import StatusCode -from utils.dd_constants import SpanKind +from opentelemetry.trace import StatusCode +from opentelemetry.trace import SpanKind from utils.parametric.spec.trace import find_span from utils.parametric.spec.trace import find_trace from utils.parametric.spec.trace import retrieve_span_links diff --git a/tests/parametric/test_parametric_endpoints.py b/tests/parametric/test_parametric_endpoints.py index fae21452a9..d5009b9e95 100644 --- a/tests/parametric/test_parametric_endpoints.py +++ b/tests/parametric/test_parametric_endpoints.py @@ -16,8 +16,8 @@ from utils.parametric.spec.trace import retrieve_span_links from utils.parametric.spec.trace import find_only_span from utils import irrelevant, bug, scenarios, features, context -from utils.dd_constants import SpanKind -from utils.dd_constants import StatusCode +from opentelemetry.trace import SpanKind +from opentelemetry.trace import StatusCode from utils.parametric._library_client import Link diff --git a/utils/build/docker/dotnet/parametric/Endpoints/ApmTestApiOtel.cs b/utils/build/docker/dotnet/parametric/Endpoints/ApmTestApiOtel.cs index 334f518157..983ee5c809 100644 --- a/utils/build/docker/dotnet/parametric/Endpoints/ApmTestApiOtel.cs +++ b/utils/build/docker/dotnet/parametric/Endpoints/ApmTestApiOtel.cs @@ -69,19 +69,19 @@ private static async Task OtelStartSpan(HttpRequest request) { switch (Convert.ToInt64(spanKind)) { - case 1: + case 0: kind = ActivityKind.Internal; break; - case 2: + case 1: kind = ActivityKind.Server; break; - case 3: + case 2: kind = ActivityKind.Client; break; - case 4: + case 3: kind = ActivityKind.Producer; break; - case 5: + case 4: kind = ActivityKind.Consumer; break; default: diff --git a/utils/build/docker/golang/parametric/otel.go b/utils/build/docker/golang/parametric/otel.go index ff7102a4c6..8ec94218fe 100644 --- a/utils/build/docker/golang/parametric/otel.go +++ b/utils/build/docker/golang/parametric/otel.go @@ -49,7 +49,7 @@ func (s *apmClientServer) OtelStartSpan(args OtelStartSpanArgs) (OtelStartSpanRe } var otelOpts []otel_trace.SpanStartOption if args.SpanKind != nil { - otelOpts = append(otelOpts, otel_trace.WithSpanKind(otel_trace.ValidateSpanKind(otel_trace.SpanKind(*args.SpanKind)))) + otelOpts = append(otelOpts, otel_trace.WithSpanKind(otel_trace.ValidateSpanKind(otel_trace.SpanKind(*args.SpanKind + 1)))) } if t := args.Timestamp; t != nil { tm := time.UnixMicro(*t) diff --git a/utils/build/docker/java/parametric/src/main/java/com/datadoghq/trace/opentelemetry/controller/OpenTelemetryController.java b/utils/build/docker/java/parametric/src/main/java/com/datadoghq/trace/opentelemetry/controller/OpenTelemetryController.java index d2f5b2d63c..40a8e5907c 100644 --- a/utils/build/docker/java/parametric/src/main/java/com/datadoghq/trace/opentelemetry/controller/OpenTelemetryController.java +++ b/utils/build/docker/java/parametric/src/main/java/com/datadoghq/trace/opentelemetry/controller/OpenTelemetryController.java @@ -67,11 +67,11 @@ public OpenTelemetryController() { private static SpanKind parseSpanKindNumber(int spanKindNumber) { return switch (spanKindNumber) { - case 1 -> INTERNAL; - case 2 -> SERVER; - case 3 -> CLIENT; - case 4 -> PRODUCER; - case 5 -> CONSUMER; + case 0 -> INTERNAL; + case 1 -> SERVER; + case 2 -> CLIENT; + case 3 -> PRODUCER; + case 4 -> CONSUMER; default -> null; }; } diff --git a/utils/build/docker/nodejs/parametric/server.js b/utils/build/docker/nodejs/parametric/server.js index 00bd698dba..cb9488d26c 100644 --- a/utils/build/docker/nodejs/parametric/server.js +++ b/utils/build/docker/nodejs/parametric/server.js @@ -8,7 +8,7 @@ tracer.use('dns', false) const SpanContext = require('dd-trace/packages/dd-trace/src/opentracing/span_context') const OtelSpanContext = require('dd-trace/packages/dd-trace/src/opentelemetry/span_context') -const { trace, ROOT_CONTEXT } = require('@opentelemetry/api') +const { trace, ROOT_CONTEXT, SpanKind } = require('@opentelemetry/api') const { millisToHrTime } = require('@opentelemetry/core') const { TracerProvider } = tracer @@ -16,6 +16,7 @@ const tracerProvider = new TracerProvider() tracerProvider.register() const express = require('express'); +const Span = require('../../../../../../dd-trace-js/packages/dd-trace/src/opentelemetry/span') const app = express(); app.use(express.json()); @@ -37,6 +38,14 @@ const otelStatusCodes = { 'ERROR': 2 } +const otelSpanKinds = { + 0: SpanKind.INTERNAL, + 1: SpanKind.SERVER, + 2: SpanKind.CLIENT, + 3: SpanKind.PRODUCER, + 4: SpanKind.CONSUMER +} + const spans = new Map() const ddContext = new Map() const otelSpans = new Map() @@ -177,7 +186,7 @@ app.post('/trace/otel/start_span', (req, res) => { } const span = otelTracer.startSpan(request.name, { type: request.type, - kind: kind, + kind: otelSpanKinds[request.span_kind], attributes: request.attributes, links, startTime: microLongToHrTime(request.timestamp) diff --git a/utils/build/docker/php/parametric/server.php b/utils/build/docker/php/parametric/server.php index bf78e46e78..8e21c1e12d 100644 --- a/utils/build/docker/php/parametric/server.php +++ b/utils/build/docker/php/parametric/server.php @@ -80,15 +80,15 @@ function largeBaseConvert($numString, $fromBase, $toBase) function remappedSpanKind($spanKind) { switch ($spanKind) { - case 1: // SK_INTERNAL + case 0: // SK_INTERNAL return SpanKind::KIND_INTERNAL; - case 2: // SK_SERVER + case 1: // SK_SERVER return SpanKind::KIND_SERVER; - case 3: // SK_CLIENT + case 2: // SK_CLIENT return SpanKind::KIND_CLIENT; - case 4: // SK_PRODUCER + case 3: // SK_PRODUCER return SpanKind::KIND_PRODUCER; - case 5: // SK_CONSUMER + case 4: // SK_CONSUMER return SpanKind::KIND_CONSUMER; default: return null; diff --git a/utils/build/docker/python/parametric/apm_test_client/server.py b/utils/build/docker/python/parametric/apm_test_client/server.py index dcca196b9b..74ff76ede2 100644 --- a/utils/build/docker/python/parametric/apm_test_client/server.py +++ b/utils/build/docker/python/parametric/apm_test_client/server.py @@ -417,13 +417,10 @@ def otel_start_span(args: OtelStartSpanArgs): span_context = otel_spans[parent_id].get_span_context() links.append(opentelemetry.trace.Link(span_context, link.get("attributes"))) - # parametric tests expect span kind to be 0 for internal, 1 for server, 2 for client, .... - # while parametric tests set 0 for unset, 1 internal, 2 for server, 3 for client, .... - span_kind_int = (args.span_kind or 1) - 1 with otel_tracer.start_as_current_span( args.name, context=set_span_in_context(parent_span), - kind=SpanKind(span_kind_int), + kind=SpanKind(args.span_kind or 0), attributes=args.attributes, links=links, # parametric tests expect timestamps to be set in microseconds (required by go) diff --git a/utils/build/docker/ruby/parametric/server.rb b/utils/build/docker/ruby/parametric/server.rb index e284ac389b..b25931c0e4 100644 --- a/utils/build/docker/ruby/parametric/server.rb +++ b/utils/build/docker/ruby/parametric/server.rb @@ -51,11 +51,11 @@ def otel_tracer end OTEL_SPAN_KIND = { - 1 => :internal, - 2 => :server, - 3 => :client, - 4 => :producer, - 5 => :consumer + 0 => :internal, + 1 => :server, + 2 => :client, + 3 => :producer, + 4 => :consumer } # Ensure output is always flushed, to prevent a forced shutdown from losing all logs. diff --git a/utils/dd_constants.py b/utils/dd_constants.py index 59a3f51b98..83c063c41d 100644 --- a/utils/dd_constants.py +++ b/utils/dd_constants.py @@ -1,4 +1,6 @@ from enum import IntEnum +from opentelemetry.trace import SpanKind # pylint: disable=W0611 +from opentelemetry.trace import StatusCode # pylint: disable=W0611 # Key used in the metrics map to indicate tracer sampling priority @@ -61,42 +63,3 @@ class Capabilities(IntEnum): ASM_SESSION_FINGERPRINT = 33 ASM_NETWORK_FINGERPRINT = 34 ASM_HEADER_FINGERPRINT = 35 - - -class SpanKind(IntEnum): - """Specifies additional details on how this span relates to its parent span. - """ - - #: Default value. Indicates that the span is used internally in the - # application. - INTERNAL = 1 - - #: Indicates that the span describes an operation that handles a remote - # request. - SERVER = 2 - - #: Indicates that the span describes a request to some remote service. - CLIENT = 3 - - #: Indicates that the span describes a producer sending a message to a - #: broker. Unlike client and server, there is usually no direct critical - #: path latency relationship between producer and consumer spans. - PRODUCER = 4 - - #: Indicates that the span describes a consumer receiving a message from a - #: broker. Unlike client and server, there is usually no direct critical - #: path latency relationship between producer and consumer spans. - CONSUMER = 5 - - -class StatusCode(IntEnum): - """Represents the canonical set of status codes of a finished Span.""" - - UNSET = 0 - """The default status.""" - - OK = 1 - """The operation has been validated by an Application developer or Operator to have completed successfully.""" - - ERROR = 2 - """The operation contains an error.""" diff --git a/utils/parametric/_library_client.py b/utils/parametric/_library_client.py index 9da553df46..ba154748f0 100644 --- a/utils/parametric/_library_client.py +++ b/utils/parametric/_library_client.py @@ -10,7 +10,7 @@ import requests from utils import context -from utils.dd_constants import SpanKind, StatusCode +from opentelemetry.trace import SpanKind, StatusCode from utils.parametric.spec.otel_trace import OtelSpanContext from utils.tools import logger From 6afe220a19d3e674efe4fd95bed167fd243f69c3 Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Mon, 25 Nov 2024 10:38:07 -0500 Subject: [PATCH 2/5] remove --- utils/build/docker/nodejs/parametric/server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/utils/build/docker/nodejs/parametric/server.js b/utils/build/docker/nodejs/parametric/server.js index cb9488d26c..3fe6786bb5 100644 --- a/utils/build/docker/nodejs/parametric/server.js +++ b/utils/build/docker/nodejs/parametric/server.js @@ -16,7 +16,6 @@ const tracerProvider = new TracerProvider() tracerProvider.register() const express = require('express'); -const Span = require('../../../../../../dd-trace-js/packages/dd-trace/src/opentelemetry/span') const app = express(); app.use(express.json()); From c6b7926727db3ee24e98bbb90c3a1470a0d337cc Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Mon, 25 Nov 2024 11:18:51 -0500 Subject: [PATCH 3/5] fmt --- tests/parametric/test_otel_api_interoperability.py | 2 +- utils/parametric/_library_client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/parametric/test_otel_api_interoperability.py b/tests/parametric/test_otel_api_interoperability.py index 006d7c1c2b..99a8c7ccb6 100644 --- a/tests/parametric/test_otel_api_interoperability.py +++ b/tests/parametric/test_otel_api_interoperability.py @@ -3,7 +3,7 @@ import pytest from utils import bug, missing_feature, irrelevant, context, scenarios, features -from utils.dd_constants import SpanKind +from opentelemetry.trace import SpanKind from utils.parametric.spec.trace import find_trace, find_span, retrieve_span_links, find_only_span, find_root_span # this global mark applies to all tests in this file. diff --git a/utils/parametric/_library_client.py b/utils/parametric/_library_client.py index ba154748f0..804f12b65f 100644 --- a/utils/parametric/_library_client.py +++ b/utils/parametric/_library_client.py @@ -8,9 +8,9 @@ import pytest from _pytest.outcomes import Failed import requests +from opentelemetry.trace import SpanKind, StatusCode from utils import context -from opentelemetry.trace import SpanKind, StatusCode from utils.parametric.spec.otel_trace import OtelSpanContext from utils.tools import logger From 920ec93d09cc04c8b60ea2b9a4efad5a94a27c10 Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Mon, 25 Nov 2024 12:25:14 -0500 Subject: [PATCH 4/5] add otel-api as a dependency --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index c494e411b7..b159d8874c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,6 +30,7 @@ scp==0.14.5 ddapm-test-agent==1.18.0 filelock==3.12.2 # for parametric tests dictdiffer==0.9.0 # for parametric tests +opentelemetry-api==1.27.0 # for parametric tests #On Boarding requirements From a0d2cfb656e35c00f50e9b471284fda50805b2e3 Mon Sep 17 00:00:00 2001 From: Munir Abdinur Date: Mon, 25 Nov 2024 15:18:26 -0500 Subject: [PATCH 5/5] make golang workaround more clear --- utils/build/docker/golang/parametric/otel.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/build/docker/golang/parametric/otel.go b/utils/build/docker/golang/parametric/otel.go index 8ec94218fe..db2947ac0c 100644 --- a/utils/build/docker/golang/parametric/otel.go +++ b/utils/build/docker/golang/parametric/otel.go @@ -49,6 +49,9 @@ func (s *apmClientServer) OtelStartSpan(args OtelStartSpanArgs) (OtelStartSpanRe } var otelOpts []otel_trace.SpanStartOption if args.SpanKind != nil { + // SpanKindUnspecified is not supported by the parametric interface. + // SpanKind needs to be remapped (incremented by 1) to match the expected value golang value. + // https://github.com/open-telemetry/opentelemetry-go/blob/e98ef1bfdb4cc413a019ebdb64988e17bb331942/trace/span.go#L120 otelOpts = append(otelOpts, otel_trace.WithSpanKind(otel_trace.ValidateSpanKind(otel_trace.SpanKind(*args.SpanKind + 1)))) } if t := args.Timestamp; t != nil {