Skip to content

Commit d2c27f2

Browse files
committed
fix support for attribute lists of strings to not flatten them
No longer are attribute values that are lists of strings converted to a single string. This means Erlang charlists will be sent in OTLP as a list of integers and iolists as a list of strings. The user must use characters_to_binary to convert to a binary string if they wish to set the value to a string when they have a value of those types now.
1 parent c81e99d commit d2c27f2

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## Exporter
11+
12+
### Fixes
13+
14+
- [BREAKING: Fixes support for attribute values that are lists when the elements
15+
are strings. Lists of strings in attribute values are no longer flattened but
16+
remain lists. Meaning to use an Erlang charlist string or iolist as a value in
17+
an attribute you must convert with `unicode:characters_to_binary` before
18+
adding to the
19+
attributes](https://github.com/open-telemetry/opentelemetry-erlang/pull/737)
20+
1021
## Experimental API 0.5.1 - 2024-03-18
1122

1223
### Added

apps/opentelemetry_api/src/otel_attributes.erl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
%% `Pairs' can be a list of key-value pairs or a map. If `Pairs' is not a list or map, the
5151
%% function returns an empty `Attributes'.
5252
-spec new(
53-
[opentelemetry:attribute()] | opentelemetry:attributes_map() | term(),
53+
[opentelemetry:attribute()] | opentelemetry:attributes_map(),
5454
integer(),
5555
integer() | infinity
5656
) -> t().
@@ -72,7 +72,7 @@ new(_, CountLimit, ValueLengthLimit) ->
7272
%%
7373
%% `NewListOrMap' can be a list of key-value pairs or a map. If `NewListOrMap' is not a list
7474
%% or map, the function returns `Attributes' as is. Returns the updated `Attributes'.
75-
-spec set([opentelemetry:attribute()] | opentelemetry:attributes_map() | term(), t()) -> t().
75+
-spec set([opentelemetry:attribute()] | opentelemetry:attributes_map(), t()) -> t().
7676
set(NewListOrMap, Attributes) when is_list(NewListOrMap) ->
7777
set(maps:from_list(NewListOrMap), Attributes);
7878
set(NewMap, Attributes) when is_map(NewMap) ->

apps/opentelemetry_exporter/src/otel_otlp_common.erl

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,7 @@ to_any_value(Value) when is_map(Value) ->
7373
to_any_value(Value) when is_tuple(Value) ->
7474
#{value => {array_value, to_array_value(tuple_to_list(Value))}};
7575
to_any_value(Value) when is_list(Value) ->
76-
try unicode:characters_to_binary(Value) of
77-
{Failure, _, _} when Failure =:= error ;
78-
Failure =:= incomplete ->
79-
to_array_or_kvlist(Value);
80-
String ->
81-
#{value => {string_value, String}}
82-
catch
83-
_:_ ->
84-
to_array_or_kvlist(Value)
85-
end;
76+
to_array_or_kvlist(Value);
8677
to_any_value(Value) ->
8778
#{value => {string_value, to_binary(io_lib:format("~p", [Value]))}}.
8879

apps/opentelemetry_exporter/test/opentelemetry_exporter_SUITE.erl

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ all() ->
1414
{group, grpc}, {group, grpc_gzip}].
1515

1616
groups() ->
17-
[{functional, [], [configuration, span_round_trip, ets_instrumentation_info]},
17+
[{functional, [], [configuration, span_round_trip, ets_instrumentation_info, to_attributes]},
1818
{grpc, [], [verify_export]},
1919
{grpc_gzip, [], [verify_export]},
2020
{http_protobuf, [], [verify_export, user_agent]},
@@ -332,6 +332,32 @@ span_round_trip(_Config) ->
332332

333333
ok.
334334

335+
%% test conversion of attributes to the map representation of the OTLP protobuf
336+
to_attributes(_Config) ->
337+
%% this tests the removal of support for iolists as values in attributes
338+
%% a list of strings remains a list when converted to OTLP instead of being
339+
%% flattened into a string value
340+
Attributes = otel_attributes:new(#{world => [<<"hello">>, <<"there">>],
341+
charlist => "ints"}, 100, 100),
342+
Converted = otel_otlp_common:to_attributes(Attributes),
343+
344+
?assertMatch([#{value :=
345+
#{value :=
346+
{array_value,
347+
#{values :=
348+
[#{value := {int_value,105}},
349+
#{value := {int_value,110}},
350+
#{value := {int_value,116}},
351+
#{value := {int_value,115}}]}}},
352+
key := <<"charlist">>},
353+
#{value :=
354+
#{value :=
355+
{array_value,
356+
#{values :=
357+
[#{value := {string_value,<<"hello">>}},
358+
#{value := {string_value,<<"there">>}}]}}},
359+
key := <<"world">>}], lists:sort(Converted)).
360+
335361
%% insert a couple spans and export to locally running otel collector
336362
verify_export(Config) ->
337363
os:putenv("OTEL_RESOURCE_ATTRIBUTES", "service.name=my-test-service,service.version=98da75ea6d38724743bf42b45565049238d86b3f"),

0 commit comments

Comments
 (0)