Packages
prometheus
3.0.0-alpha4
6.1.3
6.1.2
6.1.1
6.1.0
6.0.3
6.0.2
6.0.1
6.0.0
5.1.1
5.1.0
5.0.0
4.13.0
retired
4.12.0
4.11.0
4.10.0
4.9.1
4.9.0
4.8.2
4.8.1
4.8.0
4.6.0
4.5.0
4.4.1
4.4.0
4.3.0
4.2.2
4.2.0
4.1.0
4.0.1
4.0.0
3.5.1
3.5.0
3.4.6
3.4.5
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.2
3.3.1
3.3.0
3.2.3
3.2.2
3.2.1
3.1.1
3.1.0
3.0.1
3.0.0
3.0.0-rc1
3.0.0-alpha9
3.0.0-alpha8
3.0.0-alpha7
3.0.0-alpha6
3.0.0-alpha5
3.0.0-alpha4
3.0.0-alpha3
3.0.0-alpha2
3.0.0-alpha10
3.0.0-alpha1
2.2.0
2.1.0
2.0.0
1.7.0
1.6.0
1.5.0
1.0.2
1.0.1
1.0.0
0.2.0
0.1.3
0.1.2
0.1.1
0.1.0
Prometheus.io client in Erlang
Current section
Files
Jump to
Current section
Files
src/model/prometheus_model_helpers.erl
%% @doc
%% Helpers for working with Prometheus data model. For advanced users.
%% Probably will be used with {@link prometheus_collector}.
%% @end
-module(prometheus_model_helpers).
-export([create_mf/5,
gauge_metrics/1,
gauge_metric/1,
gauge_metric/2,
counter_metrics/1,
counter_metric/1,
counter_metric/2,
summary_metrics/1,
summary_metric/1,
summary_metric/2,
summary_metric/3,
histogram_metrics/1,
histogram_metric/1,
histogram_metric/3,
histogram_metric/4,
label_pairs/1,
label_pair/1]).
-ifdef(TEST).
-export([filter_undefined_metrics/1,
ensure_mf_type/1,
ensure_binary_or_string/1]).
-endif.
-include("prometheus_model.hrl").
%%%===================================================================
%%% Types
%%%===================================================================
-type label_name() :: term().
-type label_value() :: term().
-type label() :: {label_name(), label_value()}.
%%%===================================================================
%%% Public API
%%%===================================================================
-spec create_mf(Name, Help, Type, Collector, CollectorData) -> MetricFamily when
Name :: prometheus_metric:name(),
Help :: prometheus_metric:help(),
Type :: atom(),
Collector :: prometheus_collector:collector(),
CollectorData :: prometheus_collector:data(),
MetricFamily :: prometheus_model:'MetricFamily'().
create_mf(Name, Help, Type, Collector, CollectorData) ->
Metrics = ensure_list(Collector:collect_metrics(Name, CollectorData)),
#'MetricFamily'{name = ensure_binary_or_string(Name),
help = ensure_binary_or_string(Help),
type = ensure_mf_type(Type),
metric = filter_undefined_metrics(Metrics)}.
%% @doc Equivalent to
%% {@link gauge_metric/1. `lists:map(fun gauge_metric/1, Values)'}.
gauge_metrics(Values) -> lists:map(fun gauge_metric/1, Values).
-spec gauge_metric(Value) -> prometheus_model:'Metric'() when
Value :: integer().
gauge_metric({Labels, Value}) -> gauge_metric(Labels, Value);
gauge_metric({Value}) -> gauge_metric([], Value);
gauge_metric(Value) -> gauge_metric([], Value).
-spec gauge_metric(Labels, Value) -> prometheus_model:'Metric'() when
Labels :: [label()],
Value :: non_neg_integer().
gauge_metric(Labels, Value) ->
#'Metric'{label = label_pairs(Labels),
gauge = #'Gauge'{value = Value}}.
%% @doc Equivalent to
%% {@link counter_metric/1. `lists:map(fun counter_metric/1, Specs)'}.
counter_metrics(Specs) -> lists:map(fun counter_metric/1, Specs).
-spec counter_metric(Value) -> prometheus_model:'Metric'() when
Value :: {Labels, Val} | {Val} | Val,
Labels :: [label()],
Val :: non_neg_integer().
counter_metric({Labels, Value}) -> counter_metric(Labels, Value);
counter_metric({Value}) -> counter_metric([], Value);
counter_metric(Value) -> counter_metric([], Value).
-spec counter_metric(Labels, Value) -> prometheus_model:'Metric'() when
Labels :: [label()],
Value :: non_neg_integer().
counter_metric(Labels, Value) ->
#'Metric'{label = label_pairs(Labels),
counter = #'Counter'{value = Value}}.
%% @doc Equivalent to
%% {@link summary_metric/1. `lists:map(fun summary_metric/1, Specs)'}.
summary_metrics(Specs) -> lists:map(fun summary_metric/1, Specs).
-spec summary_metric(Spec) -> prometheus_model:'Metric'() when
Spec :: {Labels, Count, Sum} | {Count, Sum},
Labels :: [label()],
Count :: non_neg_integer(),
Sum :: non_neg_integer().
summary_metric({Labels, Count, Sum}) -> summary_metric(Labels, Count, Sum);
summary_metric({Count, Sum}) -> summary_metric([], Count, Sum).
%% @equiv summary_metric([], Count, Sum)
summary_metric(Count, Sum) -> summary_metric([], Count, Sum).
-spec summary_metric(Labels, Count, Sum) -> prometheus_model:'Metric'() when
Labels :: [label()],
Count :: non_neg_integer(),
Sum :: non_neg_integer().
summary_metric(Labels, Count, Sum) ->
#'Metric'{label = label_pairs(Labels),
summary = #'Summary'{sample_count = Count,
sample_sum = Sum}}.
%% @doc Equivalent to
%% {@link histogram_metric/1. `lists:map(fun histogram_metric/1, Specs)'}.
histogram_metrics(Specs) -> lists:map(fun histogram_metric/1, Specs).
%% FIXME: add spec
histogram_metric({Labels, Buckets, Count, Sum}) ->
histogram_metric(Labels, Buckets, Count, Sum);
histogram_metric({Buckets, Count, Sum}) ->
histogram_metric([], Buckets, Count, Sum).
%% @equiv histogram_metric([], Buckets, Count, Sum)
histogram_metric(Buckets, Count, Sum) ->
histogram_metric([], Buckets, Count, Sum).
-spec histogram_metric(Labels, Buckets, Count, Sum) -> Metric when
Labels :: [label()],
Buckets :: [{Bound, Count}],
Bound :: prometheus_buckets:bucket_bound(),
Count :: non_neg_integer(),
Sum :: non_neg_integer(),
Metric :: prometheus_model:'Metric'().
histogram_metric(Labels, Buckets, Count, Sum) ->
Label = label_pairs(Labels),
Bucket = histogram_buckets(Buckets),
#'Metric'{label = Label,
histogram = #'Histogram'{sample_count = Count,
sample_sum = Sum,
bucket = Bucket}}.
%% @doc Equivalent to
%% {@link label_pair/1. `lists:map(fun label_pair/1, Labels)'}.
label_pairs(Labels) -> lists:map(fun label_pair/1, Labels).
-spec label_pair(label()) -> prometheus_model:'LabelPair'().
label_pair({Name, Value}) ->
#'LabelPair'{name = ensure_binary_or_string(Name),
value = ensure_binary_or_string(Value)}.
%%%===================================================================
%%% Private Parts
%%%===================================================================
%% @doc Equivalent to
%% {@link histogram_bucket/1. `lists:map(fun histogram_bucket/1, Specs)'}.
histogram_buckets(Specs) -> lists:map(fun histogram_bucket/1, Specs).
-spec histogram_bucket({Bound, Count}) -> Buckets when
Bound :: prometheus_buckets:bucket_bound(),
Count :: non_neg_integer(),
Buckets :: prometheus_model:'Bucket'().
histogram_bucket({Bound, Count}) ->
#'Bucket'{upper_bound = Bound,
cumulative_count = Count}.
-spec ensure_list(Val :: term()) -> list().
ensure_list(Val) when is_list(Val) -> Val;
ensure_list(Val) -> [Val].
filter_undefined_metrics(Metrics) -> lists:filter(fun not_undefined/1, Metrics).
not_undefined(undefined) -> false;
not_undefined(_) -> true.
-spec ensure_binary_or_string(Val :: term()) -> binary() | string().
ensure_binary_or_string(Val) when is_atom(Val) -> atom_to_binary(Val, utf8);
ensure_binary_or_string(Val) when is_list(Val) -> Val; %% FIXME: validate utf8
ensure_binary_or_string(Val) when is_binary(Val) -> Val;
ensure_binary_or_string(Val) ->
io_lib:format("~p", [Val]).
-spec ensure_mf_type(atom()) -> atom().
ensure_mf_type(gauge) -> 'GAUGE';
ensure_mf_type(counter) -> 'COUNTER';
ensure_mf_type(summary) -> 'SUMMARY';
ensure_mf_type(histogram) -> 'HISTOGRAM';
ensure_mf_type(untyped) -> 'UNTYPED';
ensure_mf_type(Type) -> erlang:error({invalid_metric_type, Type}).