Packages
prometheus
1.7.0
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/prometheus_metric.erl
-module(prometheus_metric).
-export([insert_new_mf/5,
insert_new_mf/6,
insert_mf/5,
insert_mf/6,
deregister_mf/2,
check_mf_exists/4,
mf_data/1,
metrics/2,
extract_common_params/1,
extract_key_or_default/3,
extract_key_or_raise_missing/2]).
-ifdef(TEST).
-export([validate_metric_name/1,
validate_metric_label_names/1,
validate_metric_help/1]).
-endif.
-include("prometheus.hrl").
-callback new(Info :: list()) -> ok.
-callback new(Info :: list(), Registry :: atom) -> ok.
-callback declare(Info :: list()) -> boolean().
-callback declare(Info :: list(), Registry :: atom) -> boolean().
-callback reset(Name :: atom) -> ok.
-callback reset(Name :: atom, LValues :: list()) -> ok.
-callback reset(Registry :: atom, Name :: atom, LValues :: list()) -> ok.
-callback value(Name :: atom) -> ok.
-callback value(Name :: atom, LValues :: list()) -> ok.
-callback value(Registry :: atom, Name :: atom, LValues :: list()) -> ok.
insert_new_mf(Table, Registry, Name, Labels, Help) ->
insert_new_mf(Table, Registry, Name, Labels, Help, undefined).
insert_new_mf(Table, Registry, Name, Labels, Help, Data) ->
case insert_mf(Table, Registry, Name, Labels, Help, Data) of
true ->
true;
false ->
erlang:error({mf_already_exists, {Registry, Name}, "maybe you could try declare?"})
end.
insert_mf(Table, Registry, Name, Labels, Help) ->
insert_mf(Table, Registry, Name, Labels, Help, undefined).
insert_mf(Table, Registry, Name, Labels, Help, Data) ->
ets:insert_new(Table, {{Registry, mf, Name}, Labels, Help, Data}).
deregister_mf(Table, Registry) ->
ets:match_delete(Table, {{Registry, mf, '_'}, '_', '_', '_'}).
check_mf_exists(Table, Registry, Name, LabelValues) ->
case ets:lookup(Table, {Registry, mf, Name}) of
[] ->
erlang:error({unknown_metric, Registry, Name});
[{_, Labels, _, _} = MF] ->
LVLength = length(LabelValues),
case length(Labels) of
LVLength ->
MF;
LabelsLength ->
erlang:error({invalid_metric_arity}, LabelsLength, LabelValues)
end
end.
mf_data(MF) ->
element(4, MF).
metrics(Table, Registry) ->
ets:match(Table, {{Registry, mf, '$1'}, '$2', '$3', '$4'}).
extract_common_params(Spec) ->
RawName = extract_key_or_raise_missing(name, Spec),
Name = validate_metric_name(RawName),
RawLabels = extract_key_or_default(labels, Spec, []),
Labels = validate_metric_label_names(RawLabels),
RawHelp = extract_key_or_raise_missing(help, Spec),
Help = validate_metric_help(RawHelp),
{Name, Labels, Help}.
extract_key_or_raise_missing(Key, Spec) ->
case proplists:get_value(Key, Spec) of
undefined ->
erlang:error({missing_metric_spec_key, Key, Spec});
RawValue ->
RawValue
end.
extract_key_or_default(Key, Spec, Default) ->
proplists:get_value(Key, Spec, Default).
validate_metric_name(RawName) when is_atom(RawName) ->
validate_metric_name(RawName, atom_to_list(RawName));
validate_metric_name(RawName) when is_binary(RawName) ->
validate_metric_name(RawName, binary_to_list(RawName));
validate_metric_name(RawName) when is_list(RawName) ->
validate_metric_name(RawName, RawName);
validate_metric_name(RawName) ->
erlang:error({invalid_metric_name, RawName, "metric name is not a string"}).
validate_metric_name(RawName, ListName) ->
case io_lib:printable_unicode_list(ListName) of
true ->
case re:run(ListName, "^[a-zA-Z_:][a-zA-Z0-9_:]*$") of
{match, _} -> RawName;
nomatch -> erlang:error({invalid_metric_name, RawName, "metric name doesn't match regex [a-zA-Z_:][a-zA-Z0-9_:]*"})
end;
false ->
erlang:error({invalid_metric_name, RawName, "metric name is invalid string"})
end.
validate_metric_label_names(RawLabels) when is_list(RawLabels) ->
lists:map(fun validate_metric_label_name/1, RawLabels);
validate_metric_label_names(RawLabels) ->
erlang:error({invalid_metric_labels, RawLabels, "not list"}).
validate_metric_label_name(RawName) when is_atom(RawName) ->
validate_metric_label_name(atom_to_list(RawName));
validate_metric_label_name(RawName) when is_binary(RawName) ->
validate_metric_label_name(binary_to_list(RawName));
validate_metric_label_name(RawName) when is_list(RawName) ->
case io_lib:printable_unicode_list(RawName) of
true ->
validate_metric_label_name_content(RawName);
false ->
erlang:error({invalid_metric_label_name, RawName, "metric label is invalid string"})
end;
validate_metric_label_name(RawName) ->
erlang:error({invalid_metric_label_name, RawName, "metric label is not a string"}).
validate_metric_label_name_content("__" ++ _Rest = RawName) ->
erlang:error({invalid_metric_label_name, RawName, "metric label can't start with __"});
validate_metric_label_name_content(RawName) ->
case re:run(RawName, "^[a-zA-Z_][a-zA-Z0-9_]*$") of
{match, _} -> RawName;
nomatch -> erlang:error({invalid_metric_label_name, RawName, "metric label doesn't match regex [a-zA-Z_][a-zA-Z0-9_]*"})
end.
validate_metric_help(RawHelp) when is_binary(RawHelp) ->
validate_metric_help(binary_to_list(RawHelp));
validate_metric_help(RawHelp) when is_list(RawHelp) ->
case io_lib:printable_unicode_list(RawHelp) of
true ->
RawHelp;
false ->
erlang:error({invalid_metric_help, RawHelp, "metric help is invalid string"})
end;
validate_metric_help(RawHelp) ->
erlang:error({invalid_metric_help, RawHelp, "metric help is not a string"}).