./ct_report/coverage/mongoose_instrument_prometheus.COVER.html

1 -module(mongoose_instrument_prometheus).
2
3 -behaviour(mongoose_instrument).
4
5 -export([set_up/3, handle_event/4]).
6
7 %% Define Prometheus metric-related types, because the library has no type specs
8 -type spec() :: proplists:proplist().
9 -type name() :: string().
10 -type help() :: string().
11
12 -spec set_up(mongoose_instrument:event_name(), mongoose_instrument:labels(),
13 mongoose_instrument:config()) -> boolean().
14 set_up(EventName, Labels, #{metrics := Metrics}) ->
15 1518 maps:foreach(fun(MetricName, MetricType) ->
16 2404 set_up_metric(EventName, Labels, MetricName, MetricType)
17 end, Metrics),
18 1518 true;
19 set_up(_EventName, _Labels, #{}) ->
20
:-(
false.
21
22 -spec handle_event(mongoose_instrument:event_name(), mongoose_instrument:labels(),
23 mongoose_instrument:config(), mongoose_instrument:measurements()) -> ok.
24 handle_event(EventName, Labels, #{metrics := Metrics}, Measurements) ->
25 15031 LabelValues = labels_to_values(Labels),
26 15031 maps:foreach(fun(MetricName, MetricType) ->
27 32621 handle_metric_event(EventName, LabelValues, MetricName, MetricType, Measurements)
28 end, Metrics).
29
30 -spec set_up_metric(mongoose_instrument:event_name(), mongoose_instrument:labels(),
31 mongoose_instrument:metric_name(), mongoose_instrument:metric_type()) ->
32 ok.
33 set_up_metric(EventName, Labels, MetricName, MetricType) ->
34 2404 LabelKeys = labels_to_keys(Labels),
35 2404 LabelValues = labels_to_values(Labels),
36 2404 MetricSpec = metric_spec(EventName, LabelKeys, MetricName),
37 2404 case declare_metric(MetricSpec, MetricType) of
38 27 true -> ok;
39 2377 false -> reset_metric(proplists:get_value(name, MetricSpec), LabelValues, MetricType)
40 end.
41
42 -spec declare_metric(proplists:proplist(), mongoose_instrument:metric_type()) -> boolean().
43 declare_metric(MetricSpec, spiral) ->
44 1656 prometheus_counter:declare(MetricSpec);
45 declare_metric(MetricSpec, histogram) ->
46 748 prometheus_histogram:declare([{buckets, histogram_buckets()} | MetricSpec]).
47
48 -spec reset_metric(name(), [mongoose_instrument:label_value()],
49 mongoose_instrument:metric_type()) -> ok.
50 reset_metric(Name, LabelValues, spiral) ->
51 1639 prometheus_counter:reset(Name, LabelValues),
52 1639 prometheus_counter:inc(Name, LabelValues, 0);
53 reset_metric(Name, LabelValues, histogram) ->
54 738 prometheus_histogram:reset(Name, LabelValues),
55 738 ok.
56
57 -spec metric_spec(mongoose_instrument:event_name(), [mongoose_instrument:label_key()],
58 mongoose_instrument:metric_name()) -> spec().
59 metric_spec(EventName, LabelKeys, MetricName) ->
60 2404 [{name, full_metric_name(EventName, MetricName)},
61 {help, metric_help(EventName, MetricName)},
62 {labels, LabelKeys}].
63
64 -spec histogram_buckets() -> [integer()].
65 histogram_buckets() ->
66 748 histogram_buckets([], 1 bsl 30). % ~1.07 * 10^9
67
68 histogram_buckets(AccBuckets, Val) when Val > 0 ->
69 23188 histogram_buckets([Val | AccBuckets], Val bsr 1);
70 histogram_buckets(AccBuckets, _Val) ->
71 748 AccBuckets.
72
73 -spec handle_metric_event(mongoose_instrument:event_name(), [mongoose_instrument:label_value()],
74 mongoose_instrument:metric_name(), mongoose_instrument:metric_type(),
75 mongoose_instrument:measurements()) -> ok.
76 handle_metric_event(EventName, LabelValues, MetricName, MetricType, Measurements) ->
77 32621 case Measurements of
78 #{MetricName := MetricValue} ->
79 31637 FullName = full_metric_name(EventName, MetricName),
80 31637 update_metric(FullName, LabelValues, MetricType, MetricValue);
81 #{} ->
82 984 ok
83 end.
84
85 -spec metric_help(mongoose_instrument:event_name(), mongoose_instrument:metric_name()) -> help().
86 metric_help(EventName, MetricName) ->
87 2404 lists:flatten(io_lib:format("Event: ~p, Metric: ~p", [EventName, MetricName])).
88
89 -spec full_metric_name(mongoose_instrument:event_name(), mongoose_instrument:metric_name()) ->
90 name().
91 full_metric_name(EventName, MetricName) ->
92 34041 atom_to_list(EventName) ++ "_" ++ atom_to_list(MetricName).
93
94 -spec labels_to_keys(mongoose_instrument:labels()) -> [mongoose_instrument:label_key()].
95 labels_to_keys(Labels) ->
96 2404 lists:sort(maps:keys(Labels)).
97
98 -spec labels_to_values(mongoose_instrument:labels()) -> [mongoose_instrument:label_value()].
99 labels_to_values(Labels) ->
100 17435 [V || {_K, V} <- lists:keysort(1, maps:to_list(Labels))].
101
102 -spec update_metric(name(), [mongoose_instrument:label_value()],
103 mongoose_instrument:metric_type(), integer()) -> ok.
104 update_metric(Name, Labels, spiral, Value) when is_integer(Value), Value >= 0 ->
105 15180 ok = prometheus_counter:inc(Name, Labels, Value);
106 update_metric(Name, Labels, histogram, Value) when is_integer(Value) ->
107 16457 ok = prometheus_histogram:observe(Name, Labels, Value).
Line Hits Source