Skip to content

Commit 2c45b1b

Browse files
author
Tristan Sloughter
authored
Merge pull request #624 from albertored/wildcard-view
Allow wildcard for view instrument name
2 parents bfa5a52 + abe5fa0 commit 2c45b1b

13 files changed

+136
-89
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4040
- [Validate instrument name](https://github.com/open-telemetry/opentelemetry-erlang/pull/604)
4141
- [Handle `explict_bucket_boundaries` advisory parameter](https://github.com/open-telemetry/opentelemetry-erlang/pull/628)
4242
- [Rename `boundaries` to `explict_bucket_boundaries` in histogram explicit aggregation options](https://github.com/open-telemetry/opentelemetry-erlang/pull/628)
43+
- [Allow creating wildcard views](https://github.com/open-telemetry/opentelemetry-erlang/pull/624)
4344

4445
### Changes
4546

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-ifndef(MATCH_SPEC_TYPES_DEFINED).
2+
3+
-type match_var() :: '_' | '$1' | '$2' | '$3' | '$4' | '$5' | '$6' | '$7' | '$8' | '$9'.
4+
-type match_spec(A) :: A | match_var() | {const, A}.
5+
6+
-define(MATCH_SPEC_TYPES_DEFINED, true).
7+
8+
-endif.

apps/opentelemetry_api_experimental/include/otel_metrics.hrl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
-record(instrument, {module :: module(),
2-
meter :: otel_meter:t(),
3-
name :: otel_instrument:name(),
4-
description :: otel_instrument:description() | undefined,
5-
kind :: otel_instrument:kind(),
6-
unit :: otel_instrument:unit() | undefined,
7-
temporality :: otel_instrument:temporality(),
8-
callback :: otel_instrument:callback() | undefined,
9-
callback_args :: otel_instrument:callback_args() | undefined,
10-
advisory_params :: otel_instrument:advisory_params() | undefined}).
1+
-include_lib("match_spec.hrl").
2+
3+
-record(instrument, {module :: match_spec(module()),
4+
meter :: match_spec(otel_meter:t()),
5+
name :: match_spec(otel_instrument:name()),
6+
description :: match_spec(otel_instrument:description()) | undefined,
7+
kind :: match_spec(otel_instrument:kind()),
8+
unit :: match_spec(otel_instrument:unit()) | undefined,
9+
temporality :: match_spec(otel_instrument:temporality()),
10+
callback :: match_spec(otel_instrument:callback()) | undefined,
11+
callback_args :: match_spec(otel_instrument:callback_args()) | undefined,
12+
advisory_params :: match_spec(otel_instrument:advisory_params() | undefined)}).
1113

1214
-define(TEMPORALITY_DELTA, temporality_delta).
1315
-define(TEMPORALITY_CUMULATIVE, temporality_cumulative).

apps/opentelemetry_experimental/include/otel_metrics.hrl

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
-include_lib("opentelemetry_api_experimental/include/match_spec.hrl").
2+
13
-define(DEFAULT_METER_PROVIDER, otel_meter_provider_default).
24

3-
-type match_var() :: '_' | '$1' | '$2' | '$3' | '$4' | '$5' | '$6' | '$7' | '$8' | '$9'.
4-
-type match_expr(A) :: undefined | match_var() | {const, A}.
5-
-type match_spec(A) :: match_expr(A).
5+
-type key_inner_match_spec() :: {match_spec(atom()), match_spec(opentelemetry:attributes_map()), match_spec(reference())}.
6+
-type key_match_spec() :: match_spec(otel_aggregation:key()) | key_inner_match_spec() | {key_inner_match_spec()}.
67

78
-record(meter,
89
{
@@ -26,49 +27,49 @@
2627
-record(sum_aggregation,
2728
{
2829
%% TODO: attributes should be a tuple of just the values, sorted by attribute name
29-
key :: otel_aggregation:key() | otel_aggregation:key_match_spec() | {element, 2, '$_'},
30-
start_time_unix_nano :: integer() | match_spec(integer()),
31-
last_start_time_unix_nano :: integer() | match_spec(integer()),
32-
checkpoint :: number() | match_spec(number()) | {'+', '$2', '$3'} | {'+', '$3', '$4'},
33-
previous_checkpoint :: number() | match_spec(number()) | {'+', '$5', '$6'},
34-
int_value :: number() | match_spec(number()) | {'+', '$3', {const, number()}},
35-
float_value :: number() | match_spec(number()) | {'+', '$4', {const, number()}}
30+
key :: key_match_spec() | undefined | {element, 2, '$_'},
31+
start_time_unix_nano :: match_spec(integer()) | undefined,
32+
last_start_time_unix_nano :: match_spec(integer()) | undefined,
33+
checkpoint :: match_spec(number()) | undefined | {'+', '$2', '$3'} | {'+', '$3', '$4'},
34+
previous_checkpoint :: match_spec(number()) | undefined | {'+', '$5', '$6'},
35+
int_value :: match_spec(number()) | undefined | {'+', '$3', {const, number()}},
36+
float_value :: match_spec(number()) | undefined | {'+', '$4', {const, number()}}
3637
}).
3738

3839
-record(last_value_aggregation,
3940
{
4041
%% TODO: attributes should be a tuple of just the values, sorted by attribute name
41-
key :: otel_aggregation:key() | otel_aggregation:key_match_spec(),
42-
checkpoint :: number() | match_spec(number()),
43-
value :: number() | match_spec(number()),
44-
start_time_unix_nano :: integer() | match_spec(integer()),
45-
last_start_time_unix_nano :: integer() | match_spec(integer())
42+
key :: key_match_spec() | undefined,
43+
checkpoint :: match_spec(number()) | undefined,
44+
value :: match_spec(number()) | undefined,
45+
start_time_unix_nano :: match_spec(integer()) | undefined,
46+
last_start_time_unix_nano :: match_spec(integer()) | undefined
4647
}).
4748

4849

4950
-record(explicit_histogram_checkpoint,
5051
{
51-
bucket_counts :: counters:counters_ref() | match_spec(counters:counters_ref()),
52-
min :: number() | match_spec(number()),
53-
max :: number() | match_spec(number()),
54-
sum :: number() | match_spec(number()),
55-
start_time_unix_nano :: integer() | match_spec(number())
52+
bucket_counts :: match_spec(counters:counters_ref()) | undefined,
53+
min :: match_spec(number()) | undefined,
54+
max :: match_spec(number()) | undefined,
55+
sum :: match_spec(number()) | undefined,
56+
start_time_unix_nano :: match_spec(number()) | undefined
5657
}).
5758

5859
-record(explicit_histogram_aggregation,
5960
{
6061
%% TODO: attributes should be a tuple of just the values, sorted by attribute name
61-
key :: otel_aggregation:key() | otel_aggregation:key_match_spec(),
62-
start_time_unix_nano :: integer() | {const, eqwalizer:dynamic()} | '$9' | '$2' | undefined,
62+
key :: key_match_spec() | undefined,
63+
start_time_unix_nano :: match_spec(integer()) | undefined,
6364
%% instrument_temporality :: otel_aggregation:temporality(),
6465
%% default: [0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0]
65-
explicit_bucket_boundaries :: [float()] | match_spec([float()]),
66-
record_min_max :: boolean() | match_spec(boolean()),
67-
checkpoint :: #explicit_histogram_checkpoint{} | match_spec(#explicit_histogram_checkpoint{}) | {#explicit_histogram_checkpoint{}},
66+
explicit_bucket_boundaries :: match_spec([float()]) | undefined,
67+
record_min_max :: match_spec(boolean()) | undefined,
68+
checkpoint :: match_spec(#explicit_histogram_checkpoint{}) | {#explicit_histogram_checkpoint{}} | undefined,
6869
bucket_counts :: counters:counters_ref() | match_spec(undefined),
69-
min :: number() | infinity | match_spec(number()),
70-
max :: number() | match_spec(number()),
71-
sum :: number() | match_spec(number())
70+
min :: infinity | match_spec(number()) | undefined,
71+
max :: match_spec(number()) | undefined,
72+
sum :: match_spec(number()) | undefined
7273
}).
7374

7475
-record(datapoint,
@@ -96,16 +97,16 @@
9697
-record(histogram_datapoint,
9798
{
9899
attributes :: opentelemetry:attributes_map(),
99-
start_time_unix_nano :: integer() | match_spec(integer()) | {const, eqwalizer:dynamic()},
100+
start_time_unix_nano :: match_spec(integer()) | {const, eqwalizer:dynamic()} | undefined,
100101
time_unix_nano :: integer(),
101102
count :: number(),
102-
sum :: float() | match_spec(integer()),
103+
sum :: float() | match_spec(integer()) | undefined,
103104
bucket_counts :: list(),
104-
explicit_bounds :: [float()] | match_spec([float()]),
105+
explicit_bounds :: match_spec([float()]) | undefined,
105106
exemplars :: list(),
106107
flags :: integer(),
107-
min :: integer() | infinity | match_spec(integer()),
108-
max :: integer() | match_spec(integer())
108+
min :: infinity | match_spec(integer()) | undefined,
109+
max :: match_spec(integer()) | undefined
109110
}).
110111

111112
-record(histogram,

apps/opentelemetry_experimental/src/otel_aggregation.erl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@
1212
otel_aggregation_last_value:t() | otel_aggregation_histogram_explicit:t().
1313

1414
-type key() :: {atom(), opentelemetry:attributes_map(), reference()}.
15-
-type key_match_spec() :: match_spec(otel_aggregation:key()) | {match_spec(atom()), match_spec(opentelemetry:attributes_map()), match_spec(reference())}.
1615

1716
-type options() :: map().
1817

1918
-export_type([t/0,
2019
key/0,
21-
key_match_spec/0,
2220
options/0]).
2321

2422
%% Returns the aggregation's record as it is seen and updated by

apps/opentelemetry_experimental/src/otel_aggregation_histogram_explicit.erl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ aggregate(Table, #view_aggregation{name=Name,
175175
false
176176
end.
177177

178-
-dialyzer({nowarn_function, checkpoint/3}).
179178
checkpoint(Tab, #view_aggregation{name=Name,
180179
reader=ReaderId,
181180
temporality=?TEMPORALITY_DELTA}, CollectionStartNano) ->

apps/opentelemetry_experimental/src/otel_aggregation_last_value.erl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ aggregate(Tab, ViewAggregation=#view_aggregation{name=Name,
5353
ets:insert(Tab, ?assert_type((?assert_type(Metric, #last_value_aggregation{}))#last_value_aggregation{value=Value}, tuple()))
5454
end.
5555

56-
-dialyzer({nowarn_function, checkpoint/3}).
5756
checkpoint(Tab, #view_aggregation{name=Name,
5857
reader=ReaderId,
5958
temporality=?TEMPORALITY_DELTA}, CollectionStartNano) ->

apps/opentelemetry_experimental/src/otel_aggregation_sum.erl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ aggregate(_Tab, #view_aggregation{name=_Name,
8989
is_monotonic=_IsMonotonic}, _Value, _) ->
9090
false.
9191

92-
-dialyzer({nowarn_function, checkpoint/3}).
9392
checkpoint(Tab, #view_aggregation{name=Name,
9493
reader=ReaderId,
9594
temporality=?TEMPORALITY_DELTA}, CollectionStartNano) ->

apps/opentelemetry_experimental/src/otel_meter_server.erl

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,7 @@ init([Name, RegName, Resource, Config]) ->
177177
%% TODO: don't do this if its already set?
178178
opentelemetry_experimental:set_default_meter(Name, {otel_meter_default, Meter}),
179179

180-
%% TODO: drop View if Criteria is a wildcard instrument name and View
181-
%% name is not undefined
182-
Views = [new_view(V) || V <- maps:get(views, Config, [])],
180+
Views = lists:filtermap(fun new_view/1, maps:get(views, Config, [])),
183181

184182
{ok, #state{shared_meter=Meter,
185183
instruments_tab=InstrumentsTab,
@@ -235,10 +233,7 @@ handle_call({add_view, Name, Criteria, Config}, _From, State=#state{views=Views,
235233
callbacks_tab=CallbacksTab,
236234
view_aggregations_tab=ViewAggregationsTab,
237235
readers=Readers}) ->
238-
%% TODO: drop View if Criteria is a wildcard instrument name and View name is not undefined
239-
NewView = otel_view:new(Name, Criteria, Config),
240-
_ = update_view_aggregations(InstrumentsTab, CallbacksTab, ViewAggregationsTab, [NewView], Readers),
241-
{reply, true, State#state{views=[NewView | Views]}};
236+
add_view_(Name, Criteria, Config, InstrumentsTab, CallbacksTab, ViewAggregationsTab, Readers, Views, State);
242237
handle_call(force_flush, _From, State=#state{readers=Readers}) ->
243238
[otel_metric_reader:collect(Pid) || #reader{pid=Pid} <- Readers],
244239
{reply, ok, State}.
@@ -258,6 +253,15 @@ code_change(State) ->
258253

259254
%%
260255

256+
add_view_(Name, Criteria, Config, InstrumentsTab, CallbacksTab, ViewAggregationsTab, Readers, Views, State) ->
257+
case otel_view:new(Name, Criteria, Config) of
258+
{ok, NewView} ->
259+
_ = update_view_aggregations(InstrumentsTab, CallbacksTab, ViewAggregationsTab, [NewView], Readers),
260+
{reply, true, State#state{views=[NewView | Views]}};
261+
{error, named_wildcard_view} ->
262+
{reply, false, State}
263+
end.
264+
261265
instruments_tab(Name) ->
262266
ets:new(list_to_atom(lists:concat([instruments, "_", Name])), [set,
263267
named_table,
@@ -282,19 +286,21 @@ metrics_tab(Name) ->
282286
{keypos, 2},
283287
public]).
284288

285-
-dialyzer({nowarn_function,new_view/1}).
286289
new_view(ViewConfig) ->
287290
Name = maps:get(name, ViewConfig, undefined),
288291
Description = maps:get(description, ViewConfig, undefined),
289292
Selector = maps:get(selector, ViewConfig, undefined),
290293
AttributeKeys = maps:get(attribute_keys, ViewConfig, undefined),
291294
AggregationModule = maps:get(aggregation_module, ViewConfig, undefined),
292295
AggregationOptions = maps:get(aggregation_options, ViewConfig, #{}),
293-
otel_view:new(Name, Selector, #{description => Description,
296+
case otel_view:new(Name, Selector, #{description => Description,
294297
attribute_keys => AttributeKeys,
295298
aggregation_module => AggregationModule,
296299
aggregation_options => AggregationOptions
297-
}).
300+
}) of
301+
{ok, View} -> {true, View};
302+
{error, named_wildcard_view} -> false
303+
end.
298304

299305
%% Match the Instrument to views and then store a per-Reader aggregation for the View
300306
add_instrument_(InstrumentsTab, CallbacksTab, ViewAggregationsTab, Instrument=#instrument{meter=Meter,

apps/opentelemetry_experimental/src/otel_meter_server_sup.erl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
start_link(Name, Resource, Opts) ->
3030
supervisor:start_link(?MODULE, [Name, Resource, Opts]).
3131

32-
-dialyzer({nowarn_function, provider_pid/1}).
3332
-spec provider_pid(supervisor:sup_ref()) -> pid() | restarting | undefined.
3433
provider_pid(SupPid) ->
3534
Children = supervisor:which_children(SupPid),

0 commit comments

Comments
 (0)