_site/cover/mcd_stat.COVER.html

1 %% Copyright (c) 2022 Peter Morgan <peter.james.morgan@gmail.com>
2 %%
3 %% Licensed under the Apache License, Version 2.0 (the "License");
4 %% you may not use this file except in compliance with the License.
5 %% You may obtain a copy of the License at
6 %%
7 %% http://www.apache.org/licenses/LICENSE-2.0
8 %%
9 %% Unless required by applicable law or agreed to in writing, software
10 %% distributed under the License is distributed on an "AS IS" BASIS,
11 %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 %% See the License for the specific language governing permissions and
13 %% limitations under the License.
14
15
16 -module(mcd_stat).
17
18
19 -export([all/0]).
20 -export([callback_mode/0]).
21 -export([gauge/1]).
22 -export([init/1]).
23 -export([start_link/0]).
24 -export([start_link/1]).
25 -include("mcd.hrl").
26 -include_lib("kernel/include/inet.hrl").
27 -include_lib("kernel/include/logger.hrl").
28
29
30 start_link() ->
31 11 ?FUNCTION_NAME(#{}).
32
33
34 start_link(Arg) ->
35 11 gen_statem:start_link(?MODULE, [Arg], envy_gen:options(?MODULE)).
36
37
38 all() ->
39
:-(
ets:foldl(
40 fun
41 ({Name, #{counter := Counter}}, A) ->
42
:-(
[{Name, counters:get(Counter, 1)} | A]
43 end,
44 [],
45 ?MODULE).
46
47
48 gauge(#{name := _, delta := Value} = Arg) ->
49 405 observation(
50 Arg#{type => ?FUNCTION_NAME,
51 op => delta(#{ix => 1, value => Value})});
52
53 gauge(#{name := _} = Arg) ->
54
:-(
?FUNCTION_NAME(Arg#{delta => 1});
55
56 gauge(Name) when is_atom(Name) ->
57 2 ?FUNCTION_NAME(#{name => Name, delta => 1}).
58
59
60 init([Arg]) ->
61 11 process_flag(trap_exit, true),
62 11 ets:insert_new(
63 ets:new(?MODULE, [public, named_table]),
64 lists:map(
65 fun
66 (Name) ->
67 33 {Name,
68 #{type => gauge, counter => counters:new(1, [])}}
69 end,
70 gauges())),
71 11 {ok, ready, #{arg => Arg}}.
72
73
74 gauges() ->
75 11 [cmd_flush,
76 bytes_read,
77 bytes_written].
78
79
80 callback_mode() ->
81 11 handle_event_function.
82
83
84 observation(#{name := Name, type := Type, op := Op} = Arg) ->
85 405 case ets:lookup(?MODULE, Name) of
86 [{_, #{type := Type, counter := Counter}}] ->
87 405 ok = Op(Counter);
88
89 [{_, _}] ->
90
:-(
error(badarg, [Arg]);
91
92 [] ->
93
:-(
Counter = counters:new(1, []),
94
:-(
ok = Op(Counter),
95
:-(
case ets:insert_new(
96 ?MODULE,
97 {Name, #{type => Type, counter => Counter}}) of
98
99 true ->
100
:-(
ok;
101
102 false ->
103
:-(
?FUNCTION_NAME(Arg)
104 end
105 end.
106
107
108 delta(#{value := Value} = Arg) when Value > 0 ->
109 401 add(Arg);
110
111 delta(#{value := Value} = Arg) ->
112 4 sub(Arg#{value := abs(Value)}).
113
114
115 add(#{ix := Ix, value := Value}) ->
116 401 fun
117 (Counter) ->
118 401 counters:add(Counter, Ix, Value)
119 end.
120
121
122 sub(#{ix := Ix, value := Value}) ->
123 4 fun
124 (Counter) ->
125 4 counters:sub(Counter, Ix, Value)
126 end.
Line Hits Source