Skip to content

Commit

Permalink
use handle continue for heavy lifting, copied from deadtrickster#150
Browse files Browse the repository at this point in the history
  • Loading branch information
Victor authored and Victor committed Jun 4, 2024
1 parent d1aad4a commit c952ec5
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 89 deletions.
7 changes: 4 additions & 3 deletions elvis.config
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
#{ignore => [
prometheus_misc,
prometheus_registry,
prometheus_sup,
prometheus_startup,
prometheus_instrumenter
]}},
{elvis_style, god_modules, #{limit => 54}},
{elvis_style, dont_repeat_yourself, #{min_complexity => 50}}
{elvis_style, dont_repeat_yourself, #{min_complexity => 50}},
{elvis_style, state_record_and_type, #{ignore => [prometheus_startup]}}
],
ruleset => erl_files
},
Expand Down Expand Up @@ -80,4 +81,4 @@
}
]
}
].
].
107 changes: 107 additions & 0 deletions src/prometheus_startup.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
-module(prometheus_startup).

-behaviour(gen_server).

-include("prometheus.hrl").

-export([start_link/0]).
-export([init/1, handle_continue/2, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([register_metrics/1]).

start_link() ->
gen_server:start_link(?MODULE, [], []).

%%% Server functions
init([]) ->
create_tables(),
{ok, [], {continue, []}}.

handle_continue(_Continue, _State) ->
register_collectors(),
register_metrics(),
setup_instrumenters(),
{noreply, []}.

%% Gen Server boilerplate

handle_call(_Request, _From, State) ->
{reply, ignored, State}.

handle_cast(_Msg, State) ->
{noreply, State}.

handle_info(_Info, State) ->
{noreply, State}.

terminate(_Reason, _State) ->
ok.

code_change(_OldVsn, State, _Extra) ->
{ok, State}.

%%% Private functions

create_tables() ->
Tables =
[{?PROMETHEUS_REGISTRY_TABLE, {bag, read_concurrency}},
{?PROMETHEUS_COUNTER_TABLE, write_concurrency},
{?PROMETHEUS_GAUGE_TABLE, write_concurrency},
{?PROMETHEUS_SUMMARY_TABLE, write_concurrency},
{?PROMETHEUS_QUANTILE_SUMMARY_TABLE, write_concurrency},
{?PROMETHEUS_HISTOGRAM_TABLE, write_concurrency},
{?PROMETHEUS_BOOLEAN_TABLE, write_concurrency}],
[maybe_create_table(Name, Concurrency) || {Name, Concurrency} <- Tables],
ok.

register_collectors() ->
Collectors = prometheus_collector:enabled_collectors(),
prometheus_registry:register_collectors(Collectors).

register_metrics() ->
[declare_metric(Decl) || Decl <- default_metrics()].

register_metrics(Metrics) ->
DefaultMetrics0 = default_metrics(),
DefaultMetrics1 = lists:usort(DefaultMetrics0 ++ Metrics),
application:set_env(prometheus, default_metrics, DefaultMetrics1),
[declare_metric(Decl) || Decl <- Metrics].

setup_instrumenters() ->
[prometheus_instrumenter:setup(Instrumenter)
|| Instrumenter <- prometheus_instrumenter:enabled_instrumenters()].

default_metrics() ->
application:get_env(prometheus, default_metrics, []).

maybe_create_table(Name, {Type, Concurrency}) ->
case ets:info(Name) of
undefined ->
ets:new(Name, [Type, named_table, public, {Concurrency, true}]);
_ ->
ok
end;
maybe_create_table(Name, Concurrency) ->
maybe_create_table(Name, {set, Concurrency}).

declare_metric({Metric, Spec}) ->
declare_metric(Metric, Spec);
declare_metric({Registry, Metric, Spec}) ->
declare_metric(Metric, [{registry, Registry}] ++ Spec).

declare_metric(Metric, Spec) ->
Module = type_to_module(Metric),
Module:declare(Spec).

type_to_module(counter) ->
prometheus_counter;
type_to_module(gauge) ->
prometheus_gauge;
type_to_module(summary) ->
prometheus_summary;
type_to_module(histogram) ->
prometheus_histogram;
type_to_module(boolean) ->
prometheus_boolean;
type_to_module(Type) ->
Type.
85 changes: 8 additions & 77 deletions src/prometheus_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
-export([register_metrics/1]).

-behaviour(supervisor).

-include("prometheus.hrl").

%%====================================================================
%% Macros
%%====================================================================
Expand All @@ -34,77 +31,11 @@ start_link() ->

%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
init([]) ->
create_tables(),
register_collectors(),
register_metrics(),
setup_instrumenters(),
{ok, {{one_for_one, 5, 1}, []}}.

%%====================================================================
%% Private Parts
%%====================================================================

create_tables() ->
Tables = [
{?PROMETHEUS_REGISTRY_TABLE, {bag, read_concurrency}},
{?PROMETHEUS_COUNTER_TABLE, write_concurrency},
{?PROMETHEUS_GAUGE_TABLE, write_concurrency},
{?PROMETHEUS_SUMMARY_TABLE, write_concurrency},
{?PROMETHEUS_QUANTILE_SUMMARY_TABLE, write_concurrency},
{?PROMETHEUS_HISTOGRAM_TABLE, write_concurrency},
{?PROMETHEUS_BOOLEAN_TABLE, write_concurrency}
],
[maybe_create_table(Name, Concurrency) || {Name, Concurrency} <- Tables],
ok.

register_collectors() ->
Collectors = prometheus_collector:enabled_collectors(),
prometheus_registry:register_collectors(Collectors).

register_metrics() ->
[declare_metric(Decl) || Decl <- default_metrics()].

register_metrics(Metrics) ->
DefaultMetrics0 = default_metrics(),
DefaultMetrics1 = lists:usort(DefaultMetrics0 ++ Metrics),
application:set_env(prometheus, default_metrics, DefaultMetrics1),
[declare_metric(Decl) || Decl <- Metrics].

setup_instrumenters() ->
[prometheus_instrumenter:setup(Instrumenter) ||
Instrumenter <- prometheus_instrumenter:enabled_instrumenters()].

default_metrics() ->
application:get_env(prometheus, default_metrics, []).

maybe_create_table(Name, {Type, Concurrency}) ->
case ets:info(Name) of
undefined ->
ets:new(Name, [Type, named_table, public, {Concurrency, true}]);
_ ->
ok
end;
maybe_create_table(Name, Concurrency) ->
maybe_create_table(Name, {set, Concurrency}).

declare_metric({Metric, Spec}) ->
declare_metric(Metric, Spec);
declare_metric({Registry, Metric, Spec}) ->
declare_metric(Metric, [{registry, Registry}] ++ Spec).

declare_metric(Metric, Spec) ->
Module = type_to_module(Metric),
Module:declare(Spec).

type_to_module(counter) ->
prometheus_counter;
type_to_module(gauge) ->
prometheus_gauge;
type_to_module(summary) ->
prometheus_summary;
type_to_module(histogram) ->
prometheus_histogram;
type_to_module(boolean) ->
prometheus_boolean;
type_to_module(Type) ->
Type.
ChildSpec =
[{prometheus_startup_server,
{prometheus_startup, start_link, []},
permanent,
1000,
worker,
[prometheus_startup]}],
{ok, {{one_for_one, 5, 1}, ChildSpec}}.
15 changes: 6 additions & 9 deletions test/eunit/prometheus_default_metrics_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,24 @@
default_metric_test() ->
try
Name = metric_name,
Spec = [{name, Name},
{help, ""},
{registry, qwe},
{buckets, [1, 2, 3]}],
Spec1 = [{name, Name},
{help, ""},
{buckets, [1, 2, 3]}],
Spec = [{name, Name}, {help, ""}, {registry, qwe}, {buckets, [1, 2, 3]}],
Spec1 = [{name, Name}, {help, ""}, {buckets, [1, 2, 3]}],

application:stop(prometheus),
application:set_env(prometheus, default_metrics,
application:set_env(prometheus,
default_metrics,
[{counter, Spec},
{gauge, Spec},
{qwe, summary, Spec1},
{prometheus_histogram, Spec},
{boolean, Spec}]),
application:start(prometheus),
timer:sleep(1000),
?assertEqual(false, prometheus_counter:declare(Spec)),
?assertEqual(false, prometheus_gauge:declare(Spec)),
?assertEqual(false, prometheus_summary:declare([{registry, qwe}] ++ Spec)),
?assertEqual(false, prometheus_histogram:declare(Spec)),
?assertEqual(false, prometheus_boolean:declare(Spec))
after
application:unset_env(prometheus, default_metrics)
end.
end.

0 comments on commit c952ec5

Please sign in to comment.