Skip to content

Commit c3937bc

Browse files
authored
Fix the inconsistent hex value encoding for log metadata (#851)
* Fix the inconsistent hex value encoding for log metadata * Format * Dialyzer error * Add test
1 parent 7faf931 commit c3937bc

File tree

5 files changed

+65
-24
lines changed

5 files changed

+65
-24
lines changed

apps/opentelemetry_api/lib/open_telemetry.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ defmodule OpenTelemetry do
5353
"""
5454
@type span_id() :: non_neg_integer()
5555

56+
@typedoc """
57+
Hex-encoded TraceId as a 32-character lowercase binary string.
58+
"""
59+
@type hex_trace_id() :: :opentelemetry.hex_trace_id()
60+
61+
@typedoc """
62+
Hex-encoded SpanId as a 16-character lowercase binary string.
63+
"""
64+
@type hex_span_id() :: :opentelemetry.hex_span_id()
65+
5666
@type attribute_key() :: :opentelemetry.attribute_key()
5767
@type attribute_value() :: :opentelemetry.attribute_value()
5868

apps/opentelemetry_api/lib/open_telemetry/span.ex

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,33 @@ defmodule OpenTelemetry.Span do
4141
defdelegate span_id(span), to: :otel_span
4242

4343
@doc """
44-
Get the TraceId of a Span.
44+
Get the hex-encoded trace context.
4545
"""
46-
@spec trace_id(OpenTelemetry.span_ctx()) :: OpenTelemetry.trace_id()
47-
defdelegate trace_id(span), to: :otel_span
46+
@spec hex_span_ctx(OpenTelemetry.span_ctx() | nil) ::
47+
%{
48+
otel_trace_id: OpenTelemetry.hex_trace_id(),
49+
otel_span_id: OpenTelemetry.hex_span_id(),
50+
otel_trace_flags: binary()
51+
}
52+
| %{}
53+
defdelegate hex_span_ctx(span_ctx), to: :otel_span
4854

4955
@doc """
5056
Get the lowercase hex encoded span ID.
5157
"""
52-
@spec hex_span_id(OpenTelemetry.span_ctx()) :: binary()
58+
@spec hex_span_id(OpenTelemetry.span_ctx()) :: OpenTelemetry.hex_span_id()
5359
defdelegate hex_span_id(span), to: :otel_span
5460

61+
@doc """
62+
Get the TraceId of a Span.
63+
"""
64+
@spec trace_id(OpenTelemetry.span_ctx()) :: OpenTelemetry.trace_id()
65+
defdelegate trace_id(span), to: :otel_span
66+
5567
@doc """
5668
Get the lowercase hex encoded trace ID.
5769
"""
58-
@spec hex_trace_id(OpenTelemetry.span_ctx()) :: binary()
70+
@spec hex_trace_id(OpenTelemetry.span_ctx()) :: OpenTelemetry.hex_trace_id()
5971
defdelegate hex_trace_id(span), to: :otel_span
6072

6173
@doc """

apps/opentelemetry_api/src/otel_span.erl

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,16 @@ span_id(#span_ctx{span_id=SpanId}) ->
112112
SpanId.
113113

114114
%% keys are prefixed with `otel_' because the main use of this function is logger metadata
115-
-spec hex_span_ctx(opentelemetry:span_ctx() | undefined) -> #{otel_trace_id := unicode:charlist(),
116-
otel_span_id := unicode:charlist(),
117-
otel_trace_flags := unicode:charlist()} | #{}.
118-
hex_span_ctx(#span_ctx{trace_id=TraceId,
119-
span_id=SpanId,
120-
trace_flags=TraceFlags}) ->
121-
#{otel_trace_id => io_lib:format("~32.16.0b", [TraceId]),
122-
otel_span_id => io_lib:format("~16.16.0b", [SpanId]),
123-
otel_trace_flags => case TraceFlags band 1 of 1 -> "01"; _ -> "00" end};
115+
-spec hex_span_ctx(opentelemetry:span_ctx() | undefined) -> #{otel_trace_id := opentelemetry:hex_trace_id(),
116+
otel_span_id := opentelemetry:hex_span_id(),
117+
otel_trace_flags := binary()} | #{}.
118+
hex_span_ctx(SpanCtx = #span_ctx{trace_flags=TraceFlags}) ->
119+
TraceIdBin = hex_trace_id(SpanCtx),
120+
SpanIdBin = hex_span_id(SpanCtx),
121+
TraceFlagsBin = case TraceFlags band 1 of 1 -> <<"01">>; _ -> <<"00">> end,
122+
#{otel_trace_id => TraceIdBin,
123+
otel_span_id => SpanIdBin,
124+
otel_trace_flags => TraceFlagsBin};
124125
hex_span_ctx(_) ->
125126
#{}.
126127

apps/opentelemetry_api/test/opentelemetry_api_SUITE.erl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,13 @@ noop_with_span(_Config) ->
247247
ok.
248248

249249
hex_trace_ids(_Config) ->
250+
HexTraceId = <<"0000000000000000000000000000a1b2">>,
251+
HexSpanId = <<"000000000000c3d4">>,
250252
SpanCtx=#span_ctx{trace_id=41394, span_id=50132},
251-
?assertEqual(<<"0000000000000000000000000000a1b2">>, otel_span:hex_trace_id(SpanCtx)),
252-
?assertEqual(<<"000000000000c3d4">>, otel_span:hex_span_id(SpanCtx)),
253+
?assertEqual(HexTraceId, otel_span:hex_trace_id(SpanCtx)),
254+
?assertEqual(HexSpanId, otel_span:hex_span_id(SpanCtx)),
255+
?assertEqual(#{otel_trace_id => HexTraceId,
256+
otel_span_id => HexSpanId,
257+
otel_trace_flags => <<"00">>},
258+
otel_span:hex_span_ctx(SpanCtx)),
253259
ok.

apps/opentelemetry_experimental/src/otel_otlp_logs.erl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,26 @@ log_record(#{level := Level,
8989
DroppedAttributesCount = maps:size(Attributes) - length(Attributes1),
9090
Flags = 0,
9191

92-
LogRecord = case Metadata of
93-
#{otel_trace_id := TraceId,
94-
otel_span_id := SpanId} ->
95-
#{trace_id => TraceId,
96-
span_id => SpanId};
97-
_ ->
98-
#{}
99-
end,
92+
%% Note: otel_trace_id and otel_span_id from hex_span_ctx are now binaries, not charlists.
93+
LogRecord = case Metadata of
94+
#{otel_trace_id := TraceId,
95+
otel_span_id := SpanId,
96+
otel_trace_flags := TraceFlagsHex} ->
97+
TraceFlags = case TraceFlagsHex of
98+
<<_:0, _/binary>> when byte_size(TraceFlagsHex) == 2 ->
99+
erlang:binary_to_integer(TraceFlagsHex, 16);
100+
_ -> 0
101+
end,
102+
#{trace_id => TraceId,
103+
span_id => SpanId,
104+
trace_flags => TraceFlags};
105+
#{otel_trace_id := TraceId,
106+
otel_span_id := SpanId} ->
107+
#{trace_id => TraceId,
108+
span_id => SpanId};
109+
_ ->
110+
#{}
111+
end,
100112

101113

102114

0 commit comments

Comments
 (0)