Packages
prometheus
0.2.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_mf/5,
insert_mf/6,
deregister_mf/2,
check_mf_exists/4,
mf_data/1,
metrics/2,
extract_common_params/1,
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 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_mf(Table, Registry, Name, Labels, Help) ->
insert_mf(Table, Registry, Name, Labels, Help, undefined).
insert_mf(Table, Registry, Name, Labels, Help, Data) ->
true = 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(atom_to_list(RawName));
validate_metric_name(RawName) when is_binary(RawName) ->
validate_metric_name(binary_to_list(RawName));
validate_metric_name(RawName) when is_list(RawName) ->
case io_lib:printable_unicode_list(RawName) of
true ->
case re:run(RawName, "^[a-zA-Z_:][a-zA-Z0-9_:]*$") of
{match, _} -> list_to_atom(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_name(RawName) ->
erlang:error({invalid_metric_name, RawName, "metric name is not a string"}).
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"}).