Skip to content

Commit

Permalink
Fix encoding of timestamps, IDs, and strings
Browse files Browse the repository at this point in the history
This makes the OTLP exporter able to export test traces to the OTel
collector.
  • Loading branch information
abh authored and jjatria committed Nov 23, 2023
1 parent f03af81 commit 7c33d7a
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 26 deletions.
2 changes: 2 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Revision history for OpenTelemetry-Exporter-OTLP
support for field initialisers
* Make all shutdown and force_flush methods async.
This adds a new dependency on Future::AsyncAwait
* Fix issues with JSON encoding of timestamps,
span and trace IDs, and string values

0.013 2023-11-21 23:19:28+00:00 Europe/London

Expand Down
29 changes: 12 additions & 17 deletions lib/OpenTelemetry/Exporter/OTLP/Encoder/JSON.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,14 @@ our $VERSION = '0.014';

class OpenTelemetry::Exporter::OTLP::Encoder::JSON {
use JSON::MaybeXS;
use MIME::Base64;
use OpenTelemetry::Constants 'INVALID_SPAN_ID';
use OpenTelemetry::Constants 'HEX_INVALID_SPAN_ID';
use Ref::Util qw( is_hashref is_arrayref );
use Scalar::Util 'refaddr';

method content_type () { 'application/json' }

method serialise ($data) { encode_json $data }

method encode_id ( $id ) {
MIME::Base64::encode_base64( $id, '' )
}

method encode_arraylist ($v) {
[ map $self->encode_anyvalue($_), @$v ]
}
Expand Down Expand Up @@ -48,7 +43,7 @@ class OpenTelemetry::Exporter::OTLP::Encoder::JSON {
}

# TODO: not strings
return { stringValue => $v };
return { stringValue => "$v" };
}

method encode_resource ( $resource ) {
Expand All @@ -63,16 +58,16 @@ class OpenTelemetry::Exporter::OTLP::Encoder::JSON {
attributes => $self->encode_kvlist($event->attributes),
droppedAttributesCount => $event->dropped_attributes,
name => $event->name,
timeUnixNano => $event->timestamp * 1_000_000_000,
timeUnixNano => int $event->timestamp * 1_000_000_000,
};
}

method encode_link ( $link ) {
{
attributes => $self->encode_kvlist($link->attributes),
droppedAttributesCount => $link->dropped_attributes,
spanId => $self->encode_id( $link->context->span_id ),
traceId => $self->encode_id( $link->context->trace_id ),
spanId => $link->context->hex_span_id,
traceId => $link->context->hex_trace_id,
};
}

Expand All @@ -89,21 +84,21 @@ class OpenTelemetry::Exporter::OTLP::Encoder::JSON {
droppedAttributesCount => $span->dropped_attributes,
droppedEventsCount => $span->dropped_events,
droppedLinksCount => $span->dropped_links,
endTimeUnixNano => $span->end_timestamp * 1_000_000_000,
endTimeUnixNano => int $span->end_timestamp * 1_000_000_000,
events => [ map $self->encode_event($_), $span->events ],
kind => $span->kind,
links => [ map $self->encode_link($_), $span->links ],
name => $span->name,
spanId => $self->encode_id( $span->span_id ),
startTimeUnixNano => $span->start_timestamp * 1_000_000_000,
spanId => $span->hex_span_id,
startTimeUnixNano => int $span->start_timestamp * 1_000_000_000,
status => $self->encode_status($span->status),
traceId => $self->encode_id( $span->trace_id ),
traceId => $span->hex_trace_id,
traceState => $span->trace_state->to_string,
};

my $parent = $span->parent_span_id;
$data->{parent_span_id} = $self->encode_id($parent)
unless $parent eq INVALID_SPAN_ID;
my $parent = $span->hex_parent_span_id;
$data->{parent_span_id} = $parent
unless $parent eq HEX_INVALID_SPAN_ID;

$data;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/OpenTelemetry/Exporter/OTLP/Encoder/Protobuf.pm
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class OpenTelemetry::Exporter::OTLP::Encoder::Protobuf
attributes => $self->encode_kvlist($event->attributes),
dropped_attributes_count => $event->dropped_attributes,
name => $event->name,
time_unix_nano => $event->timestamp * 1_000_000_000,
time_unix_nano => int $event->timestamp * 1_000_000_000,
};
}

Expand All @@ -67,13 +67,13 @@ class OpenTelemetry::Exporter::OTLP::Encoder::Protobuf
dropped_attributes_count => $span->dropped_attributes,
dropped_events_count => $span->dropped_events,
dropped_links_count => $span->dropped_links,
end_time_unix_nano => $span->end_timestamp * 1_000_000_000,
end_time_unix_nano => int $span->end_timestamp * 1_000_000_000,
events => [ map $self->encode_event($_), $span->events ],
kind => $span->kind,
links => [ map $self->encode_link($_), $span->links ],
name => $span->name,
span_id => $span->span_id,
start_time_unix_nano => $span->start_timestamp * 1_000_000_000,
start_time_unix_nano => int $span->start_timestamp * 1_000_000_000,
status => $self->encode_status($span->status),
trace_id => $span->trace_id,
trace_state => $span->trace_state->to_string,
Expand Down
12 changes: 6 additions & 6 deletions t/OpenTelemetry/Exporter/OTLP/Encoder/JSON.t
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use experimental 'signatures';

use JSON::MaybeXS;
use OpenTelemetry::Constants
'INVALID_SPAN_ID',
'HEX_INVALID_SPAN_ID',
-trace_export,
-span_kind,
-span_status;
Expand Down Expand Up @@ -45,18 +45,18 @@ my $span_mock = mock 'Local::Span' => add => [
dropped_links => 0,
end_timestamp => 100,
events => sub { },
hex_parent_span_id => sub { HEX_INVALID_SPAN_ID },
hex_span_id => sub { shift->{context}->hex_span_id },
hex_trace_id => sub { shift->{context}->hex_trace_id },
instrumentation_scope => sub { shift->{scope} //= Local::Scope->new },
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 },
resource => sub { shift->{resource} //= Local::Resource->new },
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([
Expand Down

0 comments on commit 7c33d7a

Please sign in to comment.