Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/formats/prometheus_text_format.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ http_request_duration_milliseconds_sum{method=\"post\"} 4350
-include("prometheus_model.hrl").

-behaviour(prometheus_format).
-compile({inline, [render_label_pair/1]}).
-compile({inline, [render_label_pair/1, render_series/4, render_value/2]}).

?DOC("""
Returns content type of the latest \[text format](https://bit.ly/2cxSuJP).
Expand Down
8 changes: 5 additions & 3 deletions src/metrics/prometheus_boolean.erl
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,16 @@ deregister_cleanup(Registry) ->
-spec collect_mf(prometheus_registry:registry(), prometheus_collector:collect_mf_callback()) -> ok.
collect_mf(Registry, Callback) ->
[
Callback(create_boolean(Name, Help, {CLabels, Labels, Registry}))
|| [Name, {Labels, Help}, CLabels, _, _] <- prometheus_metric:metrics(?TABLE, Registry)
Callback(create_boolean(NameBin, HelpBin, {CLabels, Labels, Registry, Name}))
|| [Name, {Labels, HelpBin, NameBin}, CLabels, _, _] <- prometheus_metric:metrics(
?TABLE, Registry
)
],
ok.

?DOC(false).
-spec collect_metrics(prometheus_metric:name(), tuple()) -> [prometheus_model:'Metric'()].
collect_metrics(Name, {CLabels, Labels, Registry}) ->
collect_metrics(_NameBin, {CLabels, Labels, Registry, Name}) ->
[
prometheus_model_helpers:boolean_metric(
CLabels ++ lists:zip(Labels, LabelValues), Value
Expand Down
8 changes: 5 additions & 3 deletions src/metrics/prometheus_counter.erl
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,17 @@ deregister_cleanup(Registry) ->
-spec collect_mf(prometheus_registry:registry(), prometheus_collector:collect_mf_callback()) -> ok.
collect_mf(Registry, Callback) ->
[
Callback(create_counter(Name, Help, {CLabels, Labels, Registry}))
|| [Name, {Labels, Help}, CLabels, _, _] <- prometheus_metric:metrics(?TABLE, Registry)
Callback(create_counter(NameBin, HelpBin, {CLabels, Labels, Registry, Name}))
|| [Name, {Labels, HelpBin, NameBin}, CLabels, _, _] <- prometheus_metric:metrics(
?TABLE, Registry
)
],
ok.

?DOC(false).
-spec collect_metrics(prometheus_metric:name(), tuple()) ->
[prometheus_model:'Metric'()].
collect_metrics(Name, {CLabels, Labels, Registry}) ->
collect_metrics(_NameBin, {CLabels, Labels, Registry, Name}) ->
MFValues = load_all_values(Registry, Name),
LabelValues = reduce_label_values(MFValues),
Fun = fun(VLabels, Value) ->
Expand Down
8 changes: 5 additions & 3 deletions src/metrics/prometheus_gauge.erl
Original file line number Diff line number Diff line change
Expand Up @@ -529,15 +529,17 @@ deregister_cleanup(Registry) ->
-spec collect_mf(prometheus_registry:registry(), prometheus_collector:collect_mf_callback()) -> ok.
collect_mf(Registry, Callback) ->
[
Callback(create_gauge(Name, Help, {CLabels, Labels, Registry, DU}))
|| [Name, {Labels, Help}, CLabels, DU, _] <- prometheus_metric:metrics(?TABLE, Registry)
Callback(create_gauge(NameBin, HelpBin, {CLabels, Labels, Registry, DU, Name}))
|| [Name, {Labels, HelpBin, NameBin}, CLabels, DU, _] <- prometheus_metric:metrics(
?TABLE, Registry
)
],
ok.

?DOC(false).
-spec collect_metrics(prometheus_metric:name(), tuple()) ->
[prometheus_model:'Metric'()].
collect_metrics(Name, {CLabels, Labels, Registry, DU}) ->
collect_metrics(_NameBin, {CLabels, Labels, Registry, DU, Name}) ->
[
prometheus_model_helpers:gauge_metric(
CLabels ++ lists:zip(Labels, LabelValues),
Expand Down
8 changes: 5 additions & 3 deletions src/metrics/prometheus_histogram.erl
Original file line number Diff line number Diff line change
Expand Up @@ -495,15 +495,17 @@ deregister_cleanup(Registry) ->
-spec collect_mf(prometheus_registry:registry(), prometheus_collector:collect_mf_callback()) -> ok.
collect_mf(Registry, Callback) ->
[
Callback(create_histogram(Name, Help, {CLabels, Labels, Registry, DU, Buckets}))
|| [Name, {Labels, Help}, CLabels, DU, Buckets] <- prometheus_metric:metrics(?TABLE, Registry)
Callback(create_histogram(NameBin, HelpBin, {CLabels, Labels, Registry, DU, Buckets, Name}))
|| [Name, {Labels, HelpBin, NameBin}, CLabels, DU, Buckets] <- prometheus_metric:metrics(
?TABLE, Registry
)
],
ok.

?DOC(false).
-spec collect_metrics(prometheus_metric:name(), tuple()) ->
[prometheus_model:'Metric'()].
collect_metrics(Name, {CLabels, Labels, Registry, DU, Bounds}) ->
collect_metrics(_NameBin, {CLabels, Labels, Registry, DU, Bounds, Name}) ->
MFValues = load_all_values(Registry, Name, Bounds),
LabelValuesMap = reduce_label_values(MFValues),
Fun = fun(LabelValues, Stat, L) ->
Expand Down
6 changes: 3 additions & 3 deletions src/metrics/prometheus_quantile_summary.erl
Original file line number Diff line number Diff line change
Expand Up @@ -381,15 +381,15 @@ deregister_cleanup(Registry) ->
collect_mf(Registry, Callback) ->
Metrics = prometheus_metric:metrics(?TABLE, Registry),
[
Callback(create_summary(Name, Help, {CLabels, Labels, Registry, DU, Data}))
|| [Name, {Labels, Help}, CLabels, DU, Data] <- Metrics
Callback(create_summary(NameBin, HelpBin, {CLabels, Labels, Registry, DU, Data, Name}))
|| [Name, {Labels, HelpBin, NameBin}, CLabels, DU, Data] <- Metrics
],
ok.

?DOC(false).
-spec collect_metrics(prometheus_metric:name(), tuple()) ->
[prometheus_model:'Metric'()].
collect_metrics(Name, {CLabels, Labels, Registry, _DU, _Configuration}) ->
collect_metrics(_NameBin, {CLabels, Labels, Registry, _DU, _Configuration, Name}) ->
Fun = fun model_summary_metric/6,
loop_through_keys(Name, Fun, CLabels, Labels, Registry).

Expand Down
8 changes: 5 additions & 3 deletions src/metrics/prometheus_summary.erl
Original file line number Diff line number Diff line change
Expand Up @@ -376,15 +376,17 @@ deregister_cleanup(Registry) ->
-spec collect_mf(prometheus_registry:registry(), prometheus_collector:collect_mf_callback()) -> ok.
collect_mf(Registry, Callback) ->
[
Callback(create_summary(Name, Help, {CLabels, Labels, Registry, DU}))
|| [Name, {Labels, Help}, CLabels, DU, _] <- prometheus_metric:metrics(?TABLE, Registry)
Callback(create_summary(NameBin, HelpBin, {CLabels, Labels, Registry, DU, Name}))
|| [Name, {Labels, HelpBin, NameBin}, CLabels, DU, _] <- prometheus_metric:metrics(
?TABLE, Registry
)
],
ok.

?DOC(false).
-spec collect_metrics(prometheus_metric:name(), tuple()) ->
[prometheus_model:'Metric'()].
collect_metrics(Name, {CLabels, Labels, Registry, DU}) ->
collect_metrics(_NameBin, {CLabels, Labels, Registry, DU, Name}) ->
MFValues = load_all_values(Registry, Name),
ReducedMap = lists:foldl(
fun([L, C, IS, FS], ResAcc) ->
Expand Down
35 changes: 20 additions & 15 deletions src/model/prometheus_model_helpers.erl
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,15 @@ Probably will be used with `m:prometheus_collector`.

-ifdef(TEST).
-export([
filter_undefined_metrics/1,
ensure_mf_type/1,
ensure_binary_or_string/1
]).
-endif.

-include("prometheus_model.hrl").

-compile({inline, [label_pair/1, label_pair/2, gauge_metric/2, counter_metric/2]}).

%%%===================================================================
%%% Public API
%%%===================================================================
Expand Down Expand Up @@ -100,6 +101,16 @@ Create Metric Family of `Type`, `Name` and `Help`.
MetricFamily :: prometheus_model:'MetricFamily'().
create_mf(Name, Help, Type, Metrics) when is_map(Metrics) ->
create_mf(Name, Help, Type, maps:to_list(Metrics));
create_mf(Name, Help, Type, [First | _] = Metrics0) when
is_list(Metrics0), is_record(First, 'Metric')
->
%% Fast path: metrics are already #'Metric'() records, skip metrics_from_tuples
#'MetricFamily'{
name = ensure_binary_or_string(Name),
help = ensure_binary_or_string(Help),
type = ensure_mf_type(Type),
metric = [M || M <- Metrics0, M =/= undefined]
};
create_mf(Name, Help, Type, Metrics0) ->
Metrics = metrics_from_tuples(Type, Metrics0),
#'MetricFamily'{
Expand Down Expand Up @@ -340,15 +351,18 @@ fail with an error.
label_pairs(B) when is_binary(B) ->
B;
label_pairs(Labels) when is_list(Labels) ->
lists:map(fun label_pair/1, Labels);
[label_pair(L) || L <- Labels];
label_pairs(Labels) when is_map(Labels) ->
lists:map(fun label_pair/1, maps:to_list(Labels)).
[label_pair(Name, Value) || Name := Value <- Labels].

?DOC("""
Creates `prometheus_model:`LabelPair'()' from \{Name, Value\} tuple.
""").
-spec label_pair(prometheus:label()) -> prometheus_model:'LabelPair'().
label_pair({Name, Value}) ->
label_pair(Name, Value).

label_pair(Name, Value) ->
#'LabelPair'{
name = ensure_binary_or_string(Name),
value = ensure_binary_or_string(Value)
Expand All @@ -373,10 +387,7 @@ histogram_bucket({Bound, Count}) ->
}.

metrics_from_tuples(Type, Metrics) ->
[
metric_from_tuple(Type, Metric)
|| Metric <- filter_undefined_metrics(ensure_list(Metrics))
].
[metric_from_tuple(Type, M) || M <- ensure_list(Metrics), M =/= undefined].

metric_from_tuple(_, Metric) when is_record(Metric, 'Metric') ->
Metric;
Expand All @@ -397,20 +408,14 @@ metric_from_tuple(untyped, Metric) ->
ensure_list(Val) when is_list(Val) -> Val;
ensure_list(Val) -> [Val].

?DOC(false).
-spec filter_undefined_metrics([undefined | T]) -> [T].
filter_undefined_metrics(Metrics) ->
lists:filter(fun not_undefined/1, Metrics).

not_undefined(undefined) -> false;
not_undefined(_) -> true.

?DOC(false).
-spec ensure_binary_or_string(Val :: term()) -> binary() | string().
ensure_binary_or_string(Val) when is_atom(Val) -> atom_to_binary(Val, utf8);
%% FIXME: validate utf8
ensure_binary_or_string(Val) when is_list(Val) -> Val;
ensure_binary_or_string(Val) when is_binary(Val) -> Val;
ensure_binary_or_string(Val) when is_integer(Val) -> integer_to_binary(Val);
ensure_binary_or_string(Val) when is_float(Val) -> float_to_binary(Val, [short]);
ensure_binary_or_string(Val) -> io_lib:format("~p", [Val]).

?DOC(false).
Expand Down
2 changes: 1 addition & 1 deletion src/prometheus_collector.erl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ collect_mf(_Registry, Callback) ->
Memory)),
ok.

collect_metrics(erlang_vm_bytes_total, Memory) ->
collect_metrics(_Name, Memory) ->
prometheus_model_helpers:gauge_metrics(
[
{[{kind, system}], proplists:get_value(system, Memory)},
Expand Down
28 changes: 22 additions & 6 deletions src/prometheus_metric.erl
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,10 @@ insert_new_mf(Table, Module, Spec) ->
Module :: atom(),
Spec :: spec().
insert_mf(Table, Module, Spec) ->
{Registry, Name, Labels, Help, CLabels, DurationUnit, Data} =
{Registry, Name, Labels, _Help, CLabels, DurationUnit, Data, NameBin, HelpBin} =
prometheus_metric_spec:extract_common_params(Spec),
prometheus_registry:register_collector(Registry, Module),
Tuple = {{Registry, mf, Name}, {Labels, Help}, CLabels, DurationUnit, Data},
Tuple = {{Registry, mf, Name}, {Labels, HelpBin, NameBin}, CLabels, DurationUnit, Data},
case ets:insert_new(Table, Tuple) of
true ->
maybe_set_default(Module, Registry, Name, Labels),
Expand Down Expand Up @@ -189,7 +189,8 @@ check_mf_exists(Table, Registry, Name, LabelValues) ->
case ets:lookup(Table, {Registry, mf, Name}) of
[] ->
erlang:error({unknown_metric, Registry, Name});
[{_, {Labels, _}, _, _, _} = MF] ->
[{_, E2, _, _, _} = MF] ->
Labels = element(1, E2),
LVLength = length(LabelValues),
case length(Labels) of
LVLength ->
Expand All @@ -215,8 +216,7 @@ check_mf_exists(Table, Registry, Name) ->
?DOC(false).
-spec mf_labels(tuple()) -> dynamic().
mf_labels(MF) ->
{Labels, _} = element(2, MF),
Labels.
element(1, element(2, MF)).

?DOC(false).
-spec mf_constant_labels(tuple()) -> dynamic().
Expand All @@ -236,7 +236,23 @@ mf_data(MF) ->
?DOC(false).
-spec metrics(ets:table(), prometheus_registry:registry()) -> dynamic().
metrics(Table, Registry) ->
ets:match(Table, {{Registry, mf, '$1'}, '$2', '$3', '$4', '$5'}).
Rows = ets:match(Table, {{Registry, mf, '$1'}, '$2', '$3', '$4', '$5'}),
[normalize_mf_row(Row) || Row <- Rows].

normalize_mf_row([Name, {Labels, HelpBin, NameBin}, C, D, Data]) when
is_binary(NameBin), is_binary(HelpBin)
->
[Name, {Labels, HelpBin, NameBin}, C, D, Data];
normalize_mf_row([Name, {Labels, Help}, C, D, Data]) ->
%% Backward compat: old ETS data had 2-tuple; normalize on read
[
Name,
{Labels, prometheus_metric_spec:normalize_to_binary(Help),
prometheus_metric_spec:normalize_to_binary(Name)},
C,
D,
Data
].

%%====================================================================
%% Private Parts
Expand Down
22 changes: 18 additions & 4 deletions src/prometheus_metric_spec.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
help/1,
constant_labels/1,
duration_unit/1,
extract_common_params/1
extract_common_params/1,
normalize_to_binary/1
]).

-ifdef(TEST).
Expand Down Expand Up @@ -95,14 +96,16 @@ duration_unit_from_spec(Spec) ->

?DOC(false).
-spec extract_common_params(Spec :: prometheus_metric:spec()) -> Return when
Return :: {Registry, Name, Labels, Help, CallTimeout, DurationUnit, Data},
Return :: {Registry, Name, Labels, Help, CallTimeout, DurationUnit, Data, NameBin, HelpBin},
Registry :: prometheus_registry:registry(),
Name :: prometheus_metric:name(),
Labels :: prometheus_metric:labels(),
Help :: prometheus_metric:help(),
CallTimeout :: [{atom(), term()}],
DurationUnit :: prometheus_time:maybe_duration_unit(),
Data :: dynamic().
Data :: dynamic(),
NameBin :: binary(),
HelpBin :: binary().
extract_common_params(Spec) ->
Registry = registry(Spec),
Name = name(Spec),
Expand All @@ -111,7 +114,18 @@ extract_common_params(Spec) ->
Data = data(Spec),
CallTimeout = constant_labels(Spec),
DurationUnit = duration_unit(Spec),
{Registry, Name, Labels, Help, CallTimeout, DurationUnit, Data}.
NameBin = normalize_to_binary(Name),
HelpBin = normalize_to_binary(Help),
{Registry, Name, Labels, Help, CallTimeout, DurationUnit, Data, NameBin, HelpBin}.

?DOC(false).
-spec normalize_to_binary(Val :: term()) -> binary().
normalize_to_binary(Val) when is_binary(Val) -> Val;
normalize_to_binary(Val) when is_atom(Val) -> atom_to_binary(Val, utf8);
normalize_to_binary(Val) when is_list(Val) -> iolist_to_binary(Val);
normalize_to_binary(Val) when is_integer(Val) -> integer_to_binary(Val);
normalize_to_binary(Val) when is_float(Val) -> float_to_binary(Val, [short]);
normalize_to_binary(Val) -> iolist_to_binary(io_lib:format("~p", [Val])).

?DOC(false).
?DOC(#{equiv => get_value(Key, Spec, undefined)}).
Expand Down
4 changes: 2 additions & 2 deletions test/eunit/prometheus_metric_spec_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,14 @@ extract_common_params_test() ->
),

?assertEqual(
{default, "qwe", [], "qwe", [], undefined, undefined},
{default, "qwe", [], "qwe", [], undefined, undefined, <<"qwe">>, <<"qwe">>},
prometheus_metric_spec:extract_common_params([
{name, "qwe"},
{help, "qwe"}
])
),
?assertEqual(
{qwe, "qwe", ["qwe"], "qwe", [{qwe, qwa}], undefined, data},
{qwe, "qwe", ["qwe"], "qwe", [{qwe, qwa}], undefined, data, <<"qwe">>, <<"qwe">>},
prometheus_metric_spec:extract_common_params([
{name, "qwe"},
{labels, ["qwe"]},
Expand Down
Loading
Loading