Merge pull request #20 from rbkmoney/ft/ED-204/fix-hay

This commit is contained in:
Sergey Yelin 2021-07-20 14:46:53 +03:00 committed by GitHub
commit 2fd8013420
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 115 deletions

View File

@ -20,8 +20,13 @@ clean:
$(REBAR) clean $(REBAR) clean
distclean: distclean:
$(REBAR) clean -a
rm -rf _build rm -rf _build
#test: run:
# $(REBAR) ct $(REBAR) as run shell
check_format:
$(REBAR) fmt -c
format:
$(REBAR) fmt -w

View File

@ -1,6 +1,5 @@
% Common project erlang options. % Common project erlang options.
{erl_opts, [ {erl_opts, [
% mandatory % mandatory
debug_info, debug_info,
warnings_as_errors, warnings_as_errors,
@ -23,13 +22,12 @@
% bin_opt_info % bin_opt_info
% no_auto_import % no_auto_import
% warn_missing_spec_all % warn_missing_spec_all
]}. ]}.
% Common project dependencies. % Common project dependencies.
{deps, [ {deps, [
{folsom , {git, "https://github.com/folsom-project/folsom.git" , {branch, "master"}}}, {folsom, {git, "https://github.com/folsom-project/folsom.git", {branch, "master"}}},
{cg_mon , {git, "https://github.com/rbkmoney/cg_mon.git" , {branch, "master"}}} {cg_mon, {git, "https://github.com/rbkmoney/cg_mon.git", {branch, "master"}}}
]}. ]}.
{xref_checks, [ {xref_checks, [
@ -53,12 +51,26 @@
]} ]}
]}. ]}.
{shell, [{apps,[how_are_you]}]}. {shell, [{apps, [how_are_you]}]}.
{profiles, [ {profiles, [
{test, [ {test, [
{deps, [ {deps, [
{woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}} {woody, {git, "git@github.com:rbkmoney/woody_erlang.git", {branch, "master"}}}
]} ]}
]},
{run, [
{deps, [
recon
]}
]} ]}
]}. ]}.
{plugins, [
{erlfmt, "0.15.1"}
]}.
{erlfmt, [
{print_width, 120},
{files, ["src/*.{app.src,erl}", "rebar.config"]}
]}.

View File

@ -1,14 +1,16 @@
{"1.1.0", {"1.2.0",
[{<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},1}, [{<<"bear">>,{pkg,<<"bear">>,<<"0.9.0">>},1},
{<<"cg_mon">>, {<<"cg_mon">>,
{git,"https://github.com/rbkmoney/cg_mon.git", {git,"https://github.com/rbkmoney/cg_mon.git",
{ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}}, {ref,"5a87a37694e42b6592d3b4164ae54e0e87e24e18"}},
0}, 0},
{<<"folsom">>, {<<"folsom">>,
{git,"https://github.com/folsom-project/folsom.git", {git,"https://github.com/folsom-project/folsom.git",
{ref,"eeb1cc467eb64bd94075b95b8963e80d8b4df3df"}}, {ref,"62fd0714e6f0b4e7833880afe371a9c882ea0fc2"}},
0}]}. 0}]}.
[ [
{pkg_hash,[ {pkg_hash,[
{<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}]} {<<"bear">>, <<"A31CCF5361791DD5E708F4789D67E2FEF496C4F05935FC59ADC11622F834D128">>}]},
{pkg_hash_ext,[
{<<"bear">>, <<"47F71F098F2E3CD05E124A896C5EC2F155967A2B6FF6731E0D627312CCAB7E28">>}]}
]. ].

View File

@ -71,5 +71,5 @@ gather_metrics(Metrics, KeyPrefix) ->
Data = [{Key, Fun()} || {Key, Fun} <- Metrics], Data = [{Key, Fun()} || {Key, Fun} <- Metrics],
[ [
hay_metrics:construct(gauge, [KeyPrefix, Key], Value) hay_metrics:construct(gauge, [KeyPrefix, Key], Value)
|| {Key, Value} <- Data, Value =/= undefined || {Key, Value} <- Data, Value =/= undefined
]. ].

View File

@ -11,16 +11,16 @@
-export([fold/2]). -export([fold/2]).
-record(metric, { -record(metric, {
type :: metric_type(), type :: metric_type(),
key :: metric_key(), key :: metric_key(),
value :: metric_value() value :: metric_value()
}). }).
-opaque metric() :: #metric{}. -opaque metric() :: #metric{}.
-type metric_type() :: counter | gauge. -type metric_type() :: counter | gauge.
-type metric_key() :: binary(). -type metric_key() :: binary().
-type metric_raw_key() :: -type metric_raw_key() ::
atom() atom()
| integer() | integer()
| binary() | binary()
| maybe_improper_list(metric_raw_key(), metric_raw_key()). | maybe_improper_list(metric_raw_key(), metric_raw_key()).
@ -45,9 +45,9 @@
-spec construct(metric_type(), metric_raw_key(), metric_value()) -> metric(). -spec construct(metric_type(), metric_raw_key(), metric_value()) -> metric().
construct(Type, Key, Val) -> construct(Type, Key, Val) ->
#metric{ #metric{
type = Type, type = Type,
key = construct_key(Key), key = construct_key(Key),
value = Val value = Val
}. }.
-spec type(metric()) -> metric_type(). -spec type(metric()) -> metric_type().

View File

@ -16,7 +16,6 @@
-export([handle_cast/2]). -export([handle_cast/2]).
-export([handle_info/2]). -export([handle_info/2]).
-export([terminate/2]). -export([terminate/2]).
-export([code_change/3]).
-define(SERVER, ?MODULE). -define(SERVER, ?MODULE).
-define(DEFAULT_INTERVAL, 5000). -define(DEFAULT_INTERVAL, 5000).
@ -57,43 +56,38 @@ start_link({Handler, Options}) ->
%% %%
-spec init({handler(), handler_options()}) -> {ok, state()}. -spec init({handler(), handler_options()}) -> {ok, state(), hibernate}.
init({Handler, Options}) -> init({Handler, Options}) ->
{ok, HandlerState} = Handler:init(Options), {ok, HandlerState} = Handler:init(Options),
ok = init_metrics(Handler:gather_metrics(HandlerState)), ok = init_metrics(Handler:gather_metrics(HandlerState)),
{ok, start_timer(#state{handler = Handler, handler_state = HandlerState})}. {ok, start_timer(#state{handler = Handler, handler_state = HandlerState}), hibernate}.
-spec handle_call(term(), {pid(), term()}, state()) -> {noreply, state()}. -spec handle_call(term(), {pid(), term()}, state()) -> {noreply, state(), hibernate}.
handle_call(_Msg, _From, State) -> handle_call(_Msg, _From, State) ->
{noreply, State}. {noreply, State, hibernate}.
-spec handle_cast(term(), state()) -> {noreply, state()}. -spec handle_cast(term(), state()) -> {noreply, state(), hibernate}.
handle_cast(_Msg, State) -> handle_cast(_Msg, State) ->
{noreply, State}. {noreply, State, hibernate}.
-spec handle_info(term(), state()) -> {noreply, state()}. -spec handle_info(term(), state()) -> {noreply, state(), hibernate}.
handle_info(timeout, State0) -> handle_info({timeout, TRef, update}, State0 = #state{timer = TRef}) ->
%% TODO add some sort of monitoring %% TODO add some sort of monitoring
%% to prevent metrics overloading entire system %% to prevent metrics overloading entire system
#state{handler = Handler, handler_state = HandlerState} = State = restart_timer(State0), #state{handler = Handler, handler_state = HandlerState} = State = restart_timer(State0),
ok = push_metrics(Handler:gather_metrics(HandlerState)), ok = push_metrics(Handler:gather_metrics(HandlerState)),
{noreply, State}; {noreply, State, hibernate};
handle_info(_Msg, State) -> handle_info(_Msg, State) ->
{noreply, State}. {noreply, State, hibernate}.
-spec terminate(term(), state()) -> ok. -spec terminate(term(), state()) -> ok.
terminate(_Reason, _State) -> terminate(_Reason, _State) ->
ok. ok.
-spec code_change(term(), state(), term()) -> {error, noimpl}.
code_change(_OldVsn, _State, _Extra) ->
{error, noimpl}.
%% internal %% internal
init_metrics(Metrics) -> init_metrics(Metrics) ->
@ -117,7 +111,6 @@ push_metrics(Metrics) ->
restart_timer(State = #state{timer = undefined}) -> restart_timer(State = #state{timer = undefined}) ->
start_timer(State); start_timer(State);
restart_timer(State = #state{timer = TimerRef}) -> restart_timer(State = #state{timer = TimerRef}) ->
_ = erlang:cancel_timer(TimerRef), _ = erlang:cancel_timer(TimerRef),
start_timer(State#state{timer = undefined}). start_timer(State#state{timer = undefined}).
@ -126,4 +119,4 @@ restart_timer(State = #state{timer = TimerRef}) ->
start_timer(State = #state{timer = undefined, handler = Handler, handler_state = HandlerState}) -> start_timer(State = #state{timer = undefined, handler = Handler, handler_state = HandlerState}) ->
Interval = Handler:get_interval(HandlerState), Interval = Handler:get_interval(HandlerState),
State#state{timer = erlang:send_after(Interval, self(), timeout)}. State#state{timer = erlang:start_timer(Interval, self(), update)}.

View File

@ -17,7 +17,6 @@
-export([handle_cast/2]). -export([handle_cast/2]).
-export([handle_info/2]). -export([handle_info/2]).
-export([terminate/2]). -export([terminate/2]).
-export([code_change/3]).
-define(SERVER, ?MODULE). -define(SERVER, ?MODULE).
-define(DEFAULT_INTERVAL, 5000). -define(DEFAULT_INTERVAL, 5000).
@ -64,49 +63,43 @@ start_link({Handler, Options}) ->
%% %%
-spec init({handler(), handler_options()}) -> {ok, state()}. -spec init({handler(), handler_options()}) -> {ok, state(), hibernate}.
init({Handler, Options}) -> init({Handler, Options}) ->
{ok, HandlerState} = Handler:init(Options), {ok, HandlerState} = Handler:init(Options),
{ok, start_timer(#state{handler = Handler, handler_state = HandlerState})}. {ok, start_timer(#state{handler = Handler, handler_state = HandlerState}), hibernate}.
-spec handle_call(term(), {pid(), term()}, state()) -> {noreply, state()}. -spec handle_call(term(), {pid(), term()}, state()) -> {noreply, state(), hibernate}.
handle_call(_Msg, _From, State) -> handle_call(_Msg, _From, State) ->
{noreply, State}. {noreply, State, hibernate}.
-spec handle_cast(term(), state()) -> {noreply, state()}. -spec handle_cast(term(), state()) -> {noreply, state(), hibernate}.
handle_cast(_Msg, State) -> handle_cast(_Msg, State) ->
{noreply, State}. {noreply, State, hibernate}.
-spec handle_info(term(), state()) -> {noreply, state()}. -spec handle_info(term(), state()) -> {noreply, state(), hibernate}.
handle_info(timeout, State0) -> handle_info({timeout, TRef, publish}, State0 = #state{timer = TRef}) ->
%% TODO add some sort of monitoring %% TODO add some sort of monitoring
%% to prevent metrics overloading entire system %% to prevent metrics overloading entire system
#state{handler = Handler, handler_state = HandlerState} = State = restart_timer(State0), #state{handler = Handler, handler_state = HandlerState} = State = restart_timer(State0),
{ok, NewHandlerState} = Handler:publish_metrics(fun hay_metrics:fold/2, HandlerState), {ok, NewHandlerState} = Handler:publish_metrics(fun hay_metrics:fold/2, HandlerState),
{noreply, State#state{handler_state = NewHandlerState}}; {noreply, State#state{handler_state = NewHandlerState}, hibernate};
handle_info(_Msg, State) -> handle_info(_Msg, State) ->
{noreply, State}. {noreply, State, hibernate}.
-spec terminate(term(), state()) -> ok. -spec terminate(term(), state()) -> ok.
terminate(_Reason, _State) -> terminate(_Reason, _State) ->
ok. ok.
-spec code_change(term(), state(), term()) -> {error, noimpl}.
code_change(_OldVsn, _State, _Extra) ->
{error, noimpl}.
%% internal %% internal
-spec restart_timer(state()) -> state(). -spec restart_timer(state()) -> state().
restart_timer(State = #state{timer = undefined}) -> restart_timer(State = #state{timer = undefined}) ->
start_timer(State); start_timer(State);
restart_timer(State = #state{timer = TimerRef}) -> restart_timer(State = #state{timer = TimerRef}) ->
_ = erlang:cancel_timer(TimerRef), _ = erlang:cancel_timer(TimerRef),
start_timer(State#state{timer = undefined}). start_timer(State#state{timer = undefined}).
@ -115,4 +108,4 @@ restart_timer(State = #state{timer = TimerRef}) ->
start_timer(State = #state{timer = undefined, handler = Handler, handler_state = HandlerState}) -> start_timer(State = #state{timer = undefined, handler = Handler, handler_state = HandlerState}) ->
Interval = Handler:get_interval(HandlerState), Interval = Handler:get_interval(HandlerState),
State#state{timer = erlang:send_after(Interval, self(), timeout)}. State#state{timer = erlang:start_timer(Interval, self(), publish)}.

View File

@ -19,14 +19,14 @@
socket_opts => [gen_udp:option()] socket_opts => [gen_udp:option()]
}. }.
-type socket_opt() :: -type socket_opt() ::
gen_udp:option() | gen_udp:option()
{ip, inet:socket_address()} | | {ip, inet:socket_address()}
{fd, non_neg_integer()} | | {fd, non_neg_integer()}
{ifaddr, inet:socket_address()} | | {ifaddr, inet:socket_address()}
inet:address_family() | | inet:address_family()
{port, inet:port_number()} | | {port, inet:port_number()}
{netns, file:filename_all()} | | {netns, file:filename_all()}
{bind_to_device, binary()}. | {bind_to_device, binary()}.
-export_type([host/0]). -export_type([host/0]).
-export_type([port_number/0]). -export_type([port_number/0]).
@ -70,12 +70,13 @@ get_interval(#state{interval = Interval}) ->
-spec publish_metrics(metric_fold(), state()) -> {ok, state()} | {error, Reason :: term()}. -spec publish_metrics(metric_fold(), state()) -> {ok, state()} | {error, Reason :: term()}.
publish_metrics(Fold, State0) -> publish_metrics(Fold, State0) ->
State = resolve(ensure_socket_exists(State0)), State = resolve(ensure_socket_exists(State0)),
ok = case Fold(fun process_metrics/2, {State, [], 0}) of ok =
{State, Packet, Size} when Size > 0 -> case Fold(fun process_metrics/2, {State, [], 0}) of
ok = send_packet(Packet, State); {State, Packet, Size} when Size > 0 ->
{State, [], 0} -> ok = send_packet(Packet, State);
ok {State, [], 0} ->
end, ok
end,
{ok, State}. {ok, State}.
%% Internals %% Internals

View File

@ -61,7 +61,7 @@ gather_vm_memory() ->
% ] % ]
[ [
hay_metrics:construct(gauge, [<<"vm">>, <<"memory">>, Key], Val) hay_metrics:construct(gauge, [<<"vm">>, <<"memory">>, Key], Val)
|| {Key, Val} <- erlang:memory() || {Key, Val} <- erlang:memory()
]. ].
gather_io_stat() -> gather_io_stat() ->
@ -69,10 +69,9 @@ gather_io_stat() ->
{Input, Output} = erlang:statistics(io), {Input, Output} = erlang:statistics(io),
[ [
hay_metrics:construct(gauge, [<<"vm">>, <<"io">>, Key], Val) hay_metrics:construct(gauge, [<<"vm">>, <<"io">>, Key], Val)
|| {Key, Val} <- [Input, Output] || {Key, Val} <- [Input, Output]
]. ].
%% TODO do we need this? %% TODO do we need this?
%% Probably not cuz it can be monitored through standart tools %% Probably not cuz it can be monitored through standart tools
gather_system_memory() -> gather_system_memory() ->
@ -88,28 +87,27 @@ gather_system_memory() ->
% ] % ]
[ [
hay_metrics:construct(gauge, [<<"system">>, <<"memory">>, Key], Val) hay_metrics:construct(gauge, [<<"system">>, <<"memory">>, Key], Val)
|| {Key, Val} <- memsup:get_system_memory_data() || {Key, Val} <- memsup:get_system_memory_data()
]. ].
gather_load_stats() -> gather_load_stats() ->
Names = gather_load_stat_keys(), Names = gather_load_stat_keys(),
[ [
hay_metrics:construct(gauge, [<<"vm">>, <<"load">>, Name], get_statistics_counter(Name)) hay_metrics:construct(gauge, [<<"vm">>, <<"load">>, Name], get_statistics_counter(Name))
|| Name <- Names || Name <- Names
]. ].
gather_vm_info() -> gather_vm_info() ->
[ [
hay_metrics:construct(gauge, [<<"vm">>, <<"info">>, Name], erlang:system_info(Name)) hay_metrics:construct(gauge, [<<"vm">>, <<"info">>, Name], erlang:system_info(Name))
|| Name <- get_vm_info_keys() || Name <- get_vm_info_keys()
]. ].
-ifdef(OTP_RELEASE).
-if(?OTP_RELEASE >= 21).
gather_load_stat_keys() -> gather_load_stat_keys() ->
[ [
total_run_queue_lengths, total_run_queue_lengths,
total_run_queue_lengths_all, %% With dirty schedulers %% With dirty schedulers
total_run_queue_lengths_all,
total_active_tasks, total_active_tasks,
context_switches, context_switches,
reductions, reductions,
@ -118,32 +116,19 @@ gather_load_stat_keys() ->
]. ].
get_vm_info_keys() -> get_vm_info_keys() ->
[ [
atom_count, atom_limit, atom_count,
ets_count, ets_limit, atom_limit,
port_count, port_limit, ets_count,
process_count, process_limit, ets_limit,
schedulers, schedulers_online, port_count,
port_limit,
process_count,
process_limit,
schedulers,
schedulers_online,
dirty_cpu_schedulers_online, dirty_cpu_schedulers_online,
dirty_io_schedulers dirty_io_schedulers
]. ].
-endif.
-else.
gather_load_stat_keys() ->
[
total_run_queue_lengths,
total_active_tasks,
context_switches,
reductions,
wall_clock,
runtime
].
get_vm_info_keys() ->
[
port_count, port_limit,
process_count, process_limit,
schedulers, schedulers_online
].
-endif.
get_statistics_counter(Key) -> get_statistics_counter(Key) ->
case erlang:statistics(Key) of case erlang:statistics(Key) of
@ -164,4 +149,5 @@ gather_scheduler_utilization() ->
] ]
end, end,
[], [],
NewSwt). NewSwt
).

View File

@ -12,15 +12,18 @@
-spec handle_event(Event, RpcId, Meta, Opts) -> ok when -spec handle_event(Event, RpcId, Meta, Opts) -> ok when
Event :: woody_event_handler:event(), Event :: woody_event_handler:event(),
RpcId :: woody:rpc_id() | undefined, RpcId :: woody:rpc_id() | undefined,
Meta :: woody_event_handler:event_meta(), Meta :: woody_event_handler:event_meta(),
Opts :: woody:options(). Opts :: woody:options().
handle_event( handle_event(
'invoke service handler', _RpcId, 'invoke service handler',
_RpcId,
#{function := Function, service_schema := {Handler, Service}}, #{function := Function, service_schema := {Handler, Service}},
_Opts) -> _Opts
Key = [<<"woody">>, <<"rpc">>, <<"server">>, Handler, Service, Function], ) ->
how_are_you:metric_push( Key = [<<"woody">>, <<"rpc">>, <<"server">>, Handler, Service, Function],
how_are_you:metric_construct(counter, Key, 1)), how_are_you:metric_push(
how_are_you:metric_construct(counter, Key, 1)
),
ok; ok;
handle_event(_Event, _RpcId, _Meta, _Opts) -> handle_event(_Event, _RpcId, _Meta, _Opts) ->
ok. ok.

View File

@ -1,7 +1,5 @@
{application, how_are_you, [ {application, how_are_you, [
{description, {description, "Simple app for collecting and reporting metrics to somewere (statsd for ex.)"},
"Simple app for collecting and reporting metrics to somewere (statsd for ex.)"
},
{vsn, "0.1"}, {vsn, "0.1"},
{registered, []}, {registered, []},
{mod, {how_are_you, []}}, {mod, {how_are_you, []}},