From a3c6cb60755b5eb4195a71e28d204877a22962c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Joaqu=C3=ADn=20Atria?= Date: Mon, 6 Nov 2023 18:17:34 +0000 Subject: [PATCH] Drop SDK dependency If the OTLP exporter is to be the default used by the SDK, then it doesn't sit right that the exporter would depend on the SDK. This commit makes it so that the exporter doesn't directly depend on the SDK to function, which means that the SDK can then recommend the exporter as an optional dependency without getting into a dependency cycle. This wasn't o difficult since the only place we were still using the SDK directly was in the test suite. It would still be a good idea to have an optional test that ensured the exporter worked with the real SDK classes, but for now it's enough to break the hard dependency. --- META.json | 1 - Makefile.PL | 2 - cpanfile | 1 - t/OpenTelemetry/Exporter/OTLP.t | 93 ++++++------- t/OpenTelemetry/Exporter/OTLP/Encoder/JSON.t | 111 +++++++++------ .../Exporter/OTLP/Encoder/Protobuf.t | 130 ++++++++++-------- 6 files changed, 186 insertions(+), 152 deletions(-) diff --git a/META.json b/META.json index 49c5c07..dc12165 100644 --- a/META.json +++ b/META.json @@ -50,7 +50,6 @@ "JSON::MaybeXS" : "0", "Metrics::Any" : "0", "Object::Pad" : "0", - "OpenTelemetry::SDK" : "0", "Path::Tiny" : "0", "perl" : "v5.20.0" } diff --git a/Makefile.PL b/Makefile.PL index a299add..e795b4e 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -28,7 +28,6 @@ my %WriteMakefileArgs = ( "JSON::MaybeXS" => 0, "Metrics::Any" => 0, "Object::Pad" => 0, - "OpenTelemetry::SDK" => 0, "Path::Tiny" => 0 }, "TEST_REQUIRES" => { @@ -51,7 +50,6 @@ my %FallbackPrereqs = ( "JSON::MaybeXS" => 0, "Metrics::Any" => 0, "Object::Pad" => 0, - "OpenTelemetry::SDK" => 0, "Path::Tiny" => 0, "Test2::V0" => 0, "Test::More" => 0 diff --git a/cpanfile b/cpanfile index 7c9eba0..989eee0 100644 --- a/cpanfile +++ b/cpanfile @@ -2,7 +2,6 @@ requires 'File::Share'; requires 'JSON::MaybeXS'; requires 'Metrics::Any'; requires 'Object::Pad'; -requires 'OpenTelemetry::SDK'; requires 'Path::Tiny'; recommends 'Compress::Zlib'; diff --git a/t/OpenTelemetry/Exporter/OTLP.t b/t/OpenTelemetry/Exporter/OTLP.t index 7268228..daa5404 100644 --- a/t/OpenTelemetry/Exporter/OTLP.t +++ b/t/OpenTelemetry/Exporter/OTLP.t @@ -3,65 +3,58 @@ use Log::Any::Adapter 'Stderr'; use Test2::V0 -target => 'OpenTelemetry::Exporter::OTLP'; +use experimental 'signatures'; + use HTTP::Tiny; -use OpenTelemetry::Constants -trace_export, -span_kind, -span_status; +use OpenTelemetry::Constants + 'INVALID_SPAN_ID', + -trace_export, + -span_kind, + -span_status; use OpenTelemetry::Trace::SpanContext; -use OpenTelemetry::SDK::Trace::Span::Readable; -use OpenTelemetry::SDK::Resource; -use OpenTelemetry::SDK::InstrumentationScope; use OpenTelemetry::Trace::Span::Status; -my $guard = mock 'HTTP::Tiny' => override => [ +my $http_mock = mock 'HTTP::Tiny' => override => [ request => sub { +{ success => 1 } }, ]; -my $a_scope = OpenTelemetry::SDK::InstrumentationScope->new( name => 'A' ); -my $b_scope = OpenTelemetry::SDK::InstrumentationScope->new( name => 'B' ); - -my $a_resource = OpenTelemetry::SDK::Resource->new( attributes => { name => 'A' } ); -my $b_resource = OpenTelemetry::SDK::Resource->new( attributes => { name => 'B' } ); +my $span_mock = mock 'Local::Span' => add => [ + attributes => sub { {} }, + dropped_attributes => 0, + dropped_events => 0, + dropped_links => 0, + end_timestamp => 100, + events => sub { }, + kind => sub { SPAN_KIND_INTERNAL }, + links => sub { }, + name => sub { shift->{name} //= 'X' }, + parent_span_id => sub { INVALID_SPAN_ID }, + span_id => sub { shift->{context}->span_id }, + start_timestamp => 0, + status => sub { OpenTelemetry::Trace::Span::Status->ok }, + trace_flags => sub { shift->{context}->trace_flags }, + trace_id => sub { shift->{context}->trace_id }, + trace_state => sub { shift->{context}->trace_state }, + new => sub ( $class, %data ) { + $data{context} //= OpenTelemetry::Trace::SpanContext->new; + bless \%data, $class; + }, + instrumentation_scope => sub { + shift->{scope} //= mock {} => add => [ name => 'X' ]; + }, + resource => sub { + shift->{resource} //= mock {} => add => [ + attributes => sub { +{} }, + dropped_attributes => 0, + ]; + }, +]; is CLASS->new->export([ - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $a_scope, - kind => SPAN_KIND_INTERNAL, - name => 'A-A', - resource => $a_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, - ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $a_scope, - kind => SPAN_KIND_INTERNAL, - name => 'A-B', - resource => $b_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, - ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $b_scope, - kind => SPAN_KIND_INTERNAL, - name => 'B-A', - resource => $a_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, - ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $b_scope, - kind => SPAN_KIND_INTERNAL, - name => 'B-B', - resource => $b_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, - ), + Local::Span->new, + Local::Span->new, + Local::Span->new, + Local::Span->new, ]), TRACE_EXPORT_SUCCESS; done_testing; diff --git a/t/OpenTelemetry/Exporter/OTLP/Encoder/JSON.t b/t/OpenTelemetry/Exporter/OTLP/Encoder/JSON.t index a325519..95bbe3a 100644 --- a/t/OpenTelemetry/Exporter/OTLP/Encoder/JSON.t +++ b/t/OpenTelemetry/Exporter/OTLP/Encoder/JSON.t @@ -2,60 +2,83 @@ use Test2::V0 -target => 'OpenTelemetry::Exporter::OTLP::Encoder::JSON'; +use experimental 'signatures'; + use JSON::MaybeXS; -use OpenTelemetry::Constants -trace_export, -span_kind, -span_status; +use OpenTelemetry::Constants + 'INVALID_SPAN_ID', + -trace_export, + -span_kind, + -span_status; use OpenTelemetry::Trace::SpanContext; -use OpenTelemetry::SDK::Trace::Span::Readable; -use OpenTelemetry::SDK::Resource; -use OpenTelemetry::SDK::InstrumentationScope; use OpenTelemetry::Trace::Span::Status; -my $a_scope = OpenTelemetry::SDK::InstrumentationScope->new( name => 'A' ); -my $b_scope = OpenTelemetry::SDK::InstrumentationScope->new( name => 'B' ); +my $scope_mock = mock 'Local::Scope' => add => [ + new => sub ( $class, %data ) { bless \%data, $class }, + dropped_attributes => 0, + version => '', + name => sub { shift->{name} //= 'SCOPE' }, + attributes => sub { +{} }, +]; + +my $resource_mock = mock 'Local::Resource' => add => [ + new => sub ( $class, %data ) { bless \%data, $class }, + dropped_attributes => 0, + schema_url => '', + attributes => sub { shift->{attributes} //= {} }, +]; + +my $a_scope = Local::Scope->new( name => 'A' ); +my $b_scope = Local::Scope->new( name => 'B' ); -my $a_resource = OpenTelemetry::SDK::Resource->new( attributes => { name => 'A' } ); -my $b_resource = OpenTelemetry::SDK::Resource->new( attributes => { name => 'B' } ); +my $a_resource = Local::Resource->new( attributes => { name => 'A' } ); +my $b_resource = Local::Resource->new( attributes => { name => 'B' } ); + +my $span_mock = mock 'Local::Span' => add => [ + new => sub ( $class, %data ) { + $data{context} //= OpenTelemetry::Trace::SpanContext->new; + bless \%data, $class; + }, + attributes => sub { {} }, + dropped_attributes => 0, + dropped_events => 0, + dropped_links => 0, + end_timestamp => 100, + events => sub { }, + kind => sub { SPAN_KIND_INTERNAL }, + links => sub { }, + name => sub { shift->{name} //= 'X' }, + parent_span_id => sub { INVALID_SPAN_ID }, + span_id => sub { shift->{context}->span_id }, + start_timestamp => 0, + status => sub { OpenTelemetry::Trace::Span::Status->ok }, + trace_flags => sub { shift->{context}->trace_flags }, + trace_id => sub { shift->{context}->trace_id }, + trace_state => sub { shift->{context}->trace_state }, + instrumentation_scope => sub { shift->{scope} //= Local::Scope->new }, + resource => sub { shift->{resource} //= Local::Resource->new }, +]; is decode_json(CLASS->new->encode([ - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $a_scope, - kind => SPAN_KIND_INTERNAL, - name => 'A-A', - resource => $a_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $a_scope, + name => 'A-A', + resource => $a_resource, ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $a_scope, - kind => SPAN_KIND_INTERNAL, - name => 'A-B', - resource => $b_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $a_scope, + name => 'A-B', + resource => $b_resource, ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $b_scope, - kind => SPAN_KIND_INTERNAL, - name => 'B-A', - resource => $a_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $b_scope, + name => 'B-A', + resource => $a_resource, ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $b_scope, - kind => SPAN_KIND_INTERNAL, - name => 'B-B', - resource => $b_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $b_scope, + name => 'B-B', + resource => $b_resource, ), ])), { resourceSpans => array { diff --git a/t/OpenTelemetry/Exporter/OTLP/Encoder/Protobuf.t b/t/OpenTelemetry/Exporter/OTLP/Encoder/Protobuf.t index f229ab6..363fccc 100644 --- a/t/OpenTelemetry/Exporter/OTLP/Encoder/Protobuf.t +++ b/t/OpenTelemetry/Exporter/OTLP/Encoder/Protobuf.t @@ -3,61 +3,85 @@ use Test2::Require::Module 'Google::ProtocolBuffers::Dynamic'; use Test2::V0 -target => 'OpenTelemetry::Exporter::OTLP::Encoder::Protobuf'; +use experimental 'signatures'; + use JSON::MaybeXS; -use OpenTelemetry::Constants -trace_export, -span_kind, -span_status; +use OpenTelemetry::Proto; +use OpenTelemetry::Constants + 'INVALID_SPAN_ID', + -trace_export, + -span_kind, + -span_status; use OpenTelemetry::Trace::SpanContext; -use OpenTelemetry::SDK::Trace::Span::Readable; -use OpenTelemetry::SDK::Resource; -use OpenTelemetry::SDK::InstrumentationScope; use OpenTelemetry::Trace::Span::Status; -my $a_scope = OpenTelemetry::SDK::InstrumentationScope->new( name => 'A' ); -my $b_scope = OpenTelemetry::SDK::InstrumentationScope->new( name => 'B' ); +my $scope_mock = mock 'Local::Scope' => add => [ + new => sub ( $class, %data ) { bless \%data, $class }, + dropped_attributes => 0, + version => '', + name => sub { shift->{name} //= 'SCOPE' }, + attributes => sub { +{} }, +]; + +my $resource_mock = mock 'Local::Resource' => add => [ + new => sub ( $class, %data ) { bless \%data, $class }, + dropped_attributes => 0, + schema_url => '', + attributes => sub { shift->{attributes} //= {} }, +]; + +my $a_scope = Local::Scope->new( name => 'A' ); +my $b_scope = Local::Scope->new( name => 'B' ); -my $a_resource = OpenTelemetry::SDK::Resource->new( attributes => { name => 'A' } ); -my $b_resource = OpenTelemetry::SDK::Resource->new( attributes => { name => 'B' } ); +my $a_resource = Local::Resource->new( attributes => { name => 'A' } ); +my $b_resource = Local::Resource->new( attributes => { name => 'B' } ); + +my $span_mock = mock 'Local::Span' => add => [ + new => sub ( $class, %data ) { + $data{context} //= OpenTelemetry::Trace::SpanContext->new; + bless \%data, $class; + }, + attributes => sub { {} }, + dropped_attributes => 0, + dropped_events => 0, + dropped_links => 0, + end_timestamp => 100, + events => sub { }, + kind => sub { SPAN_KIND_INTERNAL }, + links => sub { }, + name => sub { shift->{name} //= 'X' }, + parent_span_id => sub { INVALID_SPAN_ID }, + span_id => sub { shift->{context}->span_id }, + start_timestamp => 0, + status => sub { OpenTelemetry::Trace::Span::Status->ok }, + trace_flags => sub { shift->{context}->trace_flags }, + trace_id => sub { shift->{context}->trace_id }, + trace_state => sub { shift->{context}->trace_state }, + instrumentation_scope => sub { shift->{scope} //= Local::Scope->new }, + resource => sub { shift->{resource} //= Local::Resource->new }, +]; my $encoded = CLASS->new->encode([ - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $a_scope, - kind => SPAN_KIND_INTERNAL, - name => 'A-A', - resource => $a_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $a_scope, + name => 'A-A', + resource => $a_resource, ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $a_scope, - kind => SPAN_KIND_INTERNAL, - name => 'A-B', - resource => $b_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $a_scope, + name => 'A-B', + resource => $b_resource, ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $b_scope, - kind => SPAN_KIND_INTERNAL, - name => 'B-A', - resource => $a_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $b_scope, + name => 'B-A', + resource => $a_resource, ), - OpenTelemetry::SDK::Trace::Span::Readable->new( - context => OpenTelemetry::Trace::SpanContext->new, - end_timestamp => 100, - instrumentation_scope => $b_scope, - kind => SPAN_KIND_INTERNAL, - name => 'B-B', - resource => $b_resource, - start_timestamp => 0, - status => OpenTelemetry::Trace::Span::Status->ok, + Local::Span->new( + scope => $b_scope, + name => 'B-B', + resource => $b_resource, ), ]); @@ -82,18 +106,16 @@ is decode_json($decoded->encode_json), { scopeSpans => array { prop size => 2; all_items { - scope => { - name => match qr/[AB]/, - }, + scope => { name => match qr/[AB]/ }, spans => [ { - endTimeUnixNano => E, - kind => 'SPAN_KIND_INTERNAL', - name => match qr/[AB]-[AB]/, - spanId => match qr/[0-9a-zA-Z=+]+/, - traceId => match qr/[0-9a-zA-Z=+]+/, - status => { - code => 'STATUS_CODE_OK', + endTimeUnixNano => E, + kind => 'SPAN_KIND_INTERNAL', + name => match qr/[AB]-[AB]/, + spanId => match qr/[0-9a-zA-Z=+]+/, + traceId => match qr/[0-9a-zA-Z=+]+/, + status => { + code => 'STATUS_CODE_OK', }, }, ],