Skip to content

Commit a673c0f

Browse files
author
Tristan Sloughter
authored
Merge pull request #620 from tsloughter/attribute-processing
move attribute processing to otel-attribute module
2 parents d88504e + 6957343 commit a673c0f

File tree

5 files changed

+80
-76
lines changed

5 files changed

+80
-76
lines changed

CHANGELOG.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- [Add `otel_tracestate` module for creating and updating
1515
tracestate](https://github.com/open-telemetry/opentelemetry-erlang/pull/607)
1616
- [Attributes module `otel_attributes` moved to
17-
SDK](https://github.com/open-telemetry/opentelemetry-erlang/pull/618)
17+
API](https://github.com/open-telemetry/opentelemetry-erlang/pull/618)
18+
- [Moved attribute processing functions to `otel_attributes` from
19+
`otel_span`](https://github.com/open-telemetry/opentelemetry-erlang/pull/620)
1820

1921
## SDK
2022

2123
### Changes
2224

2325
- [Attributes module `otel_attributes` moved to
24-
SDK](https://github.com/open-telemetry/opentelemetry-erlang/pull/618)
26+
API](https://github.com/open-telemetry/opentelemetry-erlang/pull/618)
2527

2628
## Experimental API
2729

apps/opentelemetry_api/src/opentelemetry.erl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,12 @@ convert_timestamp(Timestamp, Unit) ->
340340
links(List) when is_list(List) ->
341341
lists:filtermap(fun({TraceId, SpanId, Attributes, TraceState}) when is_integer(TraceId) ,
342342
is_integer(SpanId) ->
343-
link_or_false(TraceId, SpanId, otel_span:process_attributes(Attributes), TraceState);
343+
link_or_false(TraceId, SpanId, otel_attributes:process_attributes(Attributes), TraceState);
344344
({#span_ctx{trace_id=TraceId,
345345
span_id=SpanId,
346346
tracestate=TraceState}, Attributes}) when is_integer(TraceId) ,
347347
is_integer(SpanId) ->
348-
link_or_false(TraceId, SpanId, otel_span:process_attributes(Attributes), TraceState);
348+
link_or_false(TraceId, SpanId, otel_attributes:process_attributes(Attributes), TraceState);
349349
(#span_ctx{trace_id=TraceId,
350350
span_id=SpanId,
351351
tracestate=TraceState}) when is_integer(TraceId) ,
@@ -365,7 +365,7 @@ link(SpanCtx) ->
365365
link(#span_ctx{trace_id=TraceId,
366366
span_id=SpanId,
367367
tracestate=TraceState}, Attributes) ->
368-
?MODULE:link(TraceId, SpanId, otel_span:process_attributes(Attributes), TraceState);
368+
?MODULE:link(TraceId, SpanId, otel_attributes:process_attributes(Attributes), TraceState);
369369
link(_, _) ->
370370
undefined.
371371

@@ -379,7 +379,7 @@ link(TraceId, SpanId, Attributes, TraceState) when is_integer(TraceId),
379379
(is_list(Attributes) orelse is_map(Attributes)) ->
380380
#{trace_id => TraceId,
381381
span_id => SpanId,
382-
attributes => otel_span:process_attributes(Attributes),
382+
attributes => otel_attributes:process_attributes(Attributes),
383383
tracestate => TraceState};
384384
link(_, _, _, _) ->
385385
undefined.
@@ -401,7 +401,7 @@ event(Timestamp, Name, Attributes) when is_integer(Timestamp),
401401
true ->
402402
#{system_time_native => Timestamp,
403403
name => Name,
404-
attributes => otel_span:process_attributes(Attributes)};
404+
attributes => otel_attributes:process_attributes(Attributes)};
405405
false ->
406406
undefined
407407
end;

apps/opentelemetry_api/src/otel_attributes.erl

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@
2121
set/2,
2222
set/3,
2323
dropped/1,
24-
map/1]).
24+
map/1,
25+
is_valid_attribute/2,
26+
process_attributes/1]).
2527

28+
-define(is_allowed_key(Key), (is_atom(Key) orelse (is_binary(Key) andalso Key =/= <<"">>))).
29+
-define(is_allowed_value(Value), (is_atom(Value) orelse
30+
is_boolean(Value) orelse
31+
is_number(Value) orelse
32+
is_binary(Value) orelse
33+
is_list(Value))).
2634
-record(attributes, {
2735
count_limit :: integer(),
2836
value_length_limit :: integer() | infinity,
@@ -106,3 +114,58 @@ maybe_truncate_binary(Value, ValueLengthLimit) ->
106114
false ->
107115
Value
108116
end.
117+
118+
-spec is_valid_attribute(opentelemetry:attribute_key(), opentelemetry:attribute_value()) -> boolean().
119+
is_valid_attribute(Key, Value) when is_tuple(Value) , ?is_allowed_key(Key) ->
120+
is_valid_attribute(Key, tuple_to_list(Value));
121+
%% lists as attribute values must be primitive types and homogeneous
122+
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_binary(Value1) , ?is_allowed_key(Key) ->
123+
lists:all(fun is_binary/1, Values);
124+
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_boolean(Value1) , ?is_allowed_key(Key) ->
125+
lists:all(fun is_boolean/1, Values);
126+
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_atom(Value1) , ?is_allowed_key(Key) ->
127+
lists:all(fun is_valid_atom_value/1, Values);
128+
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_integer(Value1) , ?is_allowed_key(Key) ->
129+
lists:all(fun is_integer/1, Values);
130+
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_float(Value1) , ?is_allowed_key(Key) ->
131+
lists:all(fun is_float/1, Values);
132+
is_valid_attribute(_Key, Value) when is_list(Value) ->
133+
false;
134+
is_valid_attribute(Key, []) when ?is_allowed_key(Key) ->
135+
true;
136+
is_valid_attribute(Key, Value) when ?is_allowed_key(Key) , ?is_allowed_value(Value) ->
137+
true;
138+
is_valid_attribute(_, _) ->
139+
false.
140+
141+
is_valid_atom_value(undefined) ->
142+
false;
143+
is_valid_atom_value(nil) ->
144+
false;
145+
is_valid_atom_value(Value) ->
146+
is_atom(Value) andalso (is_boolean(Value) == false).
147+
148+
-spec process_attributes(eqwalizer:dynamic()) -> opentelemetry:attributes_map().
149+
process_attributes(Attributes) when is_map(Attributes) ->
150+
maps:fold(fun process_attribute/3, #{}, Attributes);
151+
process_attributes([]) -> #{};
152+
process_attributes(Attributes) when is_list(Attributes) ->
153+
process_attributes(maps:from_list(Attributes));
154+
process_attributes(_) ->
155+
#{}.
156+
157+
process_attribute(Key, Value, Map) when is_tuple(Value) ->
158+
List = tuple_to_list(Value),
159+
case is_valid_attribute(Key, List) of
160+
true ->
161+
maps:put(Key, Value, Map);
162+
false ->
163+
Map
164+
end;
165+
process_attribute(Key, Value, Map) ->
166+
case is_valid_attribute(Key, Value) of
167+
true ->
168+
maps:put(Key, Value, Map);
169+
false ->
170+
Map
171+
end.

apps/opentelemetry_api/src/otel_span.erl

Lines changed: 5 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
is_recording/1,
2828
is_valid/1,
2929
is_valid_name/1,
30-
process_attributes/1,
3130
validate_start_opts/1,
3231
set_attribute/3,
3332
set_attributes/2,
@@ -45,12 +44,6 @@
4544
-include_lib("opentelemetry_semantic_conventions/include/trace.hrl").
4645

4746
-define(is_recording(SpanCtx), SpanCtx =/= undefined andalso SpanCtx#span_ctx.is_recording =:= true).
48-
-define(is_allowed_key(Key), is_atom(Key) orelse (is_binary(Key) andalso Key =/= <<"">>)).
49-
-define(is_allowed_value(Value), is_atom(Value) orelse
50-
is_boolean(Value) orelse
51-
is_number(Value) orelse
52-
is_binary(Value) orelse
53-
is_list(Value)).
5447

5548
-type start_opts() :: #{attributes := opentelemetry:attributes_map(),
5649
links := [opentelemetry:link()],
@@ -68,7 +61,7 @@ validate_start_opts(Opts) when is_map(Opts) ->
6861
StartTime = maps:get(start_time, Opts, opentelemetry:timestamp()),
6962
IsRecording = maps:get(is_recording, Opts, true),
7063
#{
71-
attributes => process_attributes(Attributes),
64+
attributes => otel_attributes:process_attributes(Attributes),
7265
links => Links,
7366
kind => Kind,
7467
start_time => StartTime,
@@ -89,60 +82,6 @@ is_valid(#span_ctx{trace_id=TraceId,
8982
is_valid(_) ->
9083
false.
9184

92-
-spec is_valid_attribute(opentelemetry:attribute_key(), opentelemetry:attribute_value()) -> boolean().
93-
is_valid_attribute(Key, Value) when is_tuple(Value) , ?is_allowed_key(Key) ->
94-
is_valid_attribute(Key, tuple_to_list(Value));
95-
%% lists as attribute values must be primitive types and homogeneous
96-
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_binary(Value1) , ?is_allowed_key(Key) ->
97-
lists:all(fun is_binary/1, Values);
98-
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_boolean(Value1) , ?is_allowed_key(Key) ->
99-
lists:all(fun is_boolean/1, Values);
100-
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_atom(Value1) , ?is_allowed_key(Key) ->
101-
lists:all(fun is_valid_atom_value/1, Values);
102-
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_integer(Value1) , ?is_allowed_key(Key) ->
103-
lists:all(fun is_integer/1, Values);
104-
is_valid_attribute(Key, [Value1 | _Rest] = Values) when is_float(Value1) , ?is_allowed_key(Key) ->
105-
lists:all(fun is_float/1, Values);
106-
is_valid_attribute(_Key, Value) when is_list(Value) ->
107-
false;
108-
is_valid_attribute(Key, []) when ?is_allowed_key(Key) ->
109-
true;
110-
is_valid_attribute(Key, Value) when ?is_allowed_key(Key) , ?is_allowed_value(Value) ->
111-
true;
112-
is_valid_attribute(_, _) ->
113-
false.
114-
115-
is_valid_atom_value(undefined) ->
116-
false;
117-
is_valid_atom_value(nil) ->
118-
false;
119-
is_valid_atom_value(Value) ->
120-
is_atom(Value) andalso (is_boolean(Value) == false).
121-
122-
-spec process_attributes(eqwalizer:dynamic()) -> opentelemetry:attributes_map().
123-
process_attributes(Attributes) when is_map(Attributes) ->
124-
maps:fold(fun process_attribute/3, #{}, Attributes);
125-
process_attributes([]) -> #{};
126-
process_attributes(Attributes) when is_list(Attributes) ->
127-
process_attributes(maps:from_list(Attributes));
128-
process_attributes(_) ->
129-
#{}.
130-
131-
process_attribute(Key, Value, Map) when is_tuple(Value) ->
132-
List = tuple_to_list(Value),
133-
case is_valid_attribute(Key, List) of
134-
true ->
135-
maps:put(Key, Value, Map);
136-
false ->
137-
Map
138-
end;
139-
process_attribute(Key, Value, Map) ->
140-
case is_valid_attribute(Key, Value) of
141-
true ->
142-
maps:put(Key, Value, Map);
143-
false ->
144-
Map
145-
end.
14685
-spec is_valid_name(any()) -> boolean().
14786
is_valid_name(undefined) ->
14887
false;
@@ -203,14 +142,14 @@ tracestate(_) ->
203142
SpanCtx :: opentelemetry:span_ctx().
204143
set_attribute(SpanCtx=#span_ctx{span_sdk={Module, _}}, Key, Value) when ?is_recording(SpanCtx) , is_tuple(Value) ->
205144
List = tuple_to_list(Value),
206-
case is_valid_attribute(Key, List) of
145+
case otel_attributes:is_valid_attribute(Key, List) of
207146
true ->
208147
Module:set_attribute(SpanCtx, Key, List);
209148
false ->
210149
false
211150
end;
212151
set_attribute(SpanCtx=#span_ctx{span_sdk={Module, _}}, Key, Value) when ?is_recording(SpanCtx) ->
213-
case is_valid_attribute(Key, Value) of
152+
case otel_attributes:is_valid_attribute(Key, Value) of
214153
true ->
215154
Module:set_attribute(SpanCtx, Key, Value);
216155
false ->
@@ -224,7 +163,7 @@ set_attribute(_, _, _) ->
224163
SpanCtx :: opentelemetry:span_ctx().
225164
set_attributes(SpanCtx=#span_ctx{span_sdk={Module, _}}, Attributes) when ?is_recording(SpanCtx),
226165
(is_list(Attributes) orelse is_map(Attributes)) ->
227-
Module:set_attributes(SpanCtx, process_attributes(Attributes));
166+
Module:set_attributes(SpanCtx, otel_attributes:process_attributes(Attributes));
228167
set_attributes(_, _) ->
229168
false.
230169

@@ -237,7 +176,7 @@ add_event(SpanCtx=#span_ctx{span_sdk={Module, _}}, Name, Attributes)
237176
(is_list(Attributes) orelse is_map(Attributes)) ->
238177
case is_valid_name(Name) of
239178
true ->
240-
Module:add_event(SpanCtx, Name, process_attributes(Attributes));
179+
Module:add_event(SpanCtx, Name, otel_attributes:process_attributes(Attributes));
241180
false ->
242181
false
243182
end;

apps/opentelemetry_api/test/opentelemetry_api_SUITE.erl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ can_create_link_from_span(_Config) ->
7676

7777
validations(_Config) ->
7878
InvalidAttributesArg = undefined,
79-
?assertMatch(#{}, otel_span:process_attributes(InvalidAttributesArg)),
79+
?assertMatch(#{}, otel_attributes:process_attributes(InvalidAttributesArg)),
8080

8181
Attributes = [
8282
{<<"key-1">>, <<"value-1">>},
@@ -102,7 +102,7 @@ validations(_Config) ->
102102
{untimed_event, Attributes},
103103
{<<"">>, Attributes},
104104
{123, Attributes}],
105-
ProcessedAttributes = otel_span:process_attributes(Attributes),
105+
ProcessedAttributes = otel_attributes:process_attributes(Attributes),
106106

107107
?assertMatch(#{key2 := 1,
108108
key3 := true,

0 commit comments

Comments
 (0)