1 |
|
-module(mongoose_instrument_exometer). |
2 |
|
|
3 |
|
-behaviour(mongoose_instrument). |
4 |
|
|
5 |
|
-define(PREFIXES, {?MODULE, prefixes}). |
6 |
|
|
7 |
|
-export([config_spec/0, start/0, stop/0, set_up/3, handle_event/4]). |
8 |
|
|
9 |
|
-include("mongoose.hrl"). |
10 |
|
-include("mongoose_config_spec.hrl"). |
11 |
|
|
12 |
|
-spec config_spec() -> mongoose_config_spec:config_section(). |
13 |
|
config_spec() -> |
14 |
33 |
#section{items = #{<<"all_metrics_are_global">> => #option{type = boolean}}, |
15 |
|
defaults = #{<<"all_metrics_are_global">> => false}}. |
16 |
|
|
17 |
|
-spec start() -> ok. |
18 |
|
start() -> |
19 |
33 |
AllGlobal = mongoose_config:get_opt([instrumentation, exometer, all_metrics_are_global]), |
20 |
33 |
Prefixes = [{HostType, make_host_type_prefix(HostType, AllGlobal)} |
21 |
33 |
|| HostType <- ?ALL_HOST_TYPES], |
22 |
33 |
persistent_term:put(?PREFIXES, maps:from_list(Prefixes)). |
23 |
|
|
24 |
|
-spec stop() -> ok. |
25 |
|
stop() -> |
26 |
1 |
persistent_term:erase(?PREFIXES), |
27 |
1 |
ok. |
28 |
|
|
29 |
|
-spec set_up(mongoose_instrument:event_name(), mongoose_instrument:labels(), |
30 |
|
mongoose_instrument:config()) -> boolean(). |
31 |
|
set_up(EventName, Labels, #{metrics := Metrics}) -> |
32 |
1400 |
maps:foreach(fun(MetricName, MetricType) -> |
33 |
2122 |
set_up_metric(EventName, Labels, MetricName, MetricType) |
34 |
|
end, Metrics), |
35 |
1400 |
true; |
36 |
|
set_up(_EventName, _Labels, #{}) -> |
37 |
:-( |
false. |
38 |
|
|
39 |
|
-spec handle_event(mongoose_instrument:event_name(), mongoose_instrument:labels(), |
40 |
|
mongoose_instrument:config(), mongoose_instrument:measurements()) -> ok. |
41 |
|
handle_event(EventName, Labels, #{metrics := Metrics}, Measurements) -> |
42 |
11862 |
maps:foreach(fun(MetricName, MetricType) -> |
43 |
25710 |
handle_metric_event(EventName, Labels, MetricName, MetricType, Measurements) |
44 |
|
end, Metrics). |
45 |
|
|
46 |
|
-spec set_up_metric(mongoose_instrument:event_name(), mongoose_instrument:labels(), |
47 |
|
mongoose_instrument:metric_name(), mongoose_instrument:metric_type()) -> |
48 |
|
ok. |
49 |
|
set_up_metric(EventName, Labels, MetricName, MetricType) -> |
50 |
2122 |
Name = exometer_metric_name(EventName, Labels, MetricName), |
51 |
2122 |
try exometer:new(Name, MetricType) |
52 |
|
catch |
53 |
1965 |
error:exists -> ok = exometer:reset(Name) |
54 |
|
end. |
55 |
|
|
56 |
|
-spec handle_metric_event(mongoose_instrument:event_name(), mongoose_instrument:labels(), |
57 |
|
mongoose_instrument:metric_name(), mongoose_instrument:metric_type(), |
58 |
|
mongoose_instrument:measurements()) -> ok. |
59 |
|
handle_metric_event(EventName, Labels, MetricName, MetricType, Measurements) -> |
60 |
25710 |
case Measurements of |
61 |
|
#{MetricName := MetricValue} -> |
62 |
24980 |
Name = exometer_metric_name(EventName, Labels, MetricName), |
63 |
24980 |
update_metric(Name, MetricType, MetricValue); |
64 |
|
#{} -> |
65 |
730 |
ok |
66 |
|
end. |
67 |
|
|
68 |
|
-spec update_metric(exometer:name(), spiral | histogram, integer()) -> ok. |
69 |
|
update_metric(Name, gauge, Value) when is_integer(Value) -> |
70 |
124 |
ok = exometer:update(Name, Value); |
71 |
|
update_metric(Name, spiral, Value) when is_integer(Value), Value >= 0 -> |
72 |
11857 |
ok = exometer:update(Name, Value); |
73 |
|
update_metric(Name, histogram, Value) when is_integer(Value) -> |
74 |
12999 |
ok = exometer:update(Name, Value). |
75 |
|
|
76 |
|
%% This logic will need extending if we add more labels |
77 |
|
-spec exometer_metric_name(mongoose_instrument:event_name(), mongoose_instrument:labels(), |
78 |
|
mongoose_instrument:metric_name()) -> exometer:name(). |
79 |
|
exometer_metric_name(EventName, #{host_type := HostType}, MetricName) -> |
80 |
27102 |
[get_host_type_prefix(HostType), EventName, MetricName]. |
81 |
|
|
82 |
|
-spec get_host_type_prefix(mongooseim:host_type()) -> global | binary(). |
83 |
|
get_host_type_prefix(HostType) -> |
84 |
27102 |
#{HostType := Prefix} = persistent_term:get(?PREFIXES), |
85 |
27102 |
Prefix. |
86 |
|
|
87 |
|
-spec make_host_type_prefix(mongooseim:host_type(), boolean()) -> global | binary(). |
88 |
|
make_host_type_prefix(_HostType, true) -> |
89 |
:-( |
global; |
90 |
|
make_host_type_prefix(HostType, false) -> |
91 |
184 |
binary:replace(HostType, <<" ">>, <<"_">>, [global]). |