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/metrics/prometheus_gauge.erl
%% @doc
%% Gauge metric, to report instantaneous values.
%%
%% Gauge is a metric that represents a single numerical value that can
%% arbitrarily go up and down.
%%
%% A Gauge is typically used for measured values like temperatures or current
%% memory usage, but also "counts" that can go up and down, like the number of
%% running processes.
%%
%% Example use cases for Gauges:
%% <ul>
%% <li>Inprogress requests</li>
%% <li>Number of items in a queue</li>
%% <li>Free memory</li>
%% <li>Total memory</li>
%% <li>Temperature</li>
%% </ul>
%% @end
-module(prometheus_gauge).
%%% metric
-export([new/1,
new/2,
declare/1,
declare/2,
set/2,
set/3,
set/4,
set_to_current_time/1,
set_to_current_time/2,
set_to_current_time/3,
track_inprogress/2,
track_inprogress/3,
track_inprogress/4,
reset/1,
reset/2,
reset/3,
value/1,
value/2,
value/3]).
%%% collector
-export([deregister_cleanup/1,
collect_mf/2,
collect_metrics/2]).
-import(prometheus_model_helpers, [create_mf/5,
gauge_metrics/1,
gauge_metric/1,
gauge_metric/2,
counter_metric/1,
counter_metric/2]).
-include("prometheus.hrl").
-behaviour(prometheus_metric).
-behaviour(prometheus_collector).
%%====================================================================
%% Macros
%%====================================================================
-define(TABLE, ?PROMETHEUS_GAUGE_TABLE).
-define(GAUGE_POS, 2).
%%====================================================================
%% Metric API
%%====================================================================
new(Spec) ->
{Registry, Name, Labels, Help} =
prometheus_metric:extract_common_params(Spec),
prometheus_registry:register_collector(Registry, ?MODULE),
prometheus_metric:insert_new_mf(?TABLE, Registry, Name, Labels, Help).
%% @deprecated Please use {@link new/1} with registry
%% key instead.
new(Spec, Registry) ->
?DEPRECATED("prometheus_gauge:new/2", "prometheus_gauge:new/1"
" with registry key"),
new([{registry, Registry} | Spec]).
declare(Spec) ->
{Registry, Name, Labels, Help} =
prometheus_metric:extract_common_params(Spec),
prometheus_registry:register_collector(Registry, ?MODULE),
prometheus_metric:insert_mf(?TABLE, Registry, Name, Labels, Help).
%% @deprecated Please use {@link declare/1} with registry
%% key instead.
declare(Spec, Registry) ->
?DEPRECATED("prometheus_gauge:declare/2", "prometheus_gauge:declare/1"
" with registry key"),
declare([{registry, Registry} | Spec]).
%% @equiv set(default, Name, [], Value)
set(Name, Value) ->
set(default, Name, [], Value).
%% @equiv set(default, Name, LabelValues, Value)
set(Name, LabelValues, Value) ->
set(default, Name, LabelValues, Value).
set(Registry, Name, LabelValues, Value) when is_number(Value) orelse
Value == undefined ->
case ets:update_element(?TABLE, {Registry, Name, LabelValues},
{?GAUGE_POS, Value}) of
false ->
insert_metric(Registry, Name, LabelValues, Value, fun set/4);
true ->
ok
end,
ok;
set(_Registry, _Name, _LabelValues, Value) ->
erlang:error({invalid_value, Value, "set accepts only numbers"}).
%% @equiv set_to_current_time(default, Name, [])
set_to_current_time(Name) ->
set_to_current_time(default, Name, []).
%% @equiv set_to_current_time(default, Name, LabelValues)
set_to_current_time(Name, LabelValues) ->
set_to_current_time(default, Name, LabelValues).
set_to_current_time(Registry, Name, LabelValues) ->
set(Registry, Name, LabelValues, os:system_time(seconds)).
%% @equiv track_inprogress(default, Name, [], Fun)
track_inprogress(Name, Fun) ->
track_inprogress(default, Name, [], Fun).
%% @equiv track_inprogress(default, Name, LabelValues, Fun)
track_inprogress(Name, LabelValues, Fun) ->
track_inprogress(default, Name, LabelValues, Fun).
track_inprogress(Registry, Name, LabelValues, Fun) when is_function(Fun) ->
inc(Registry, Name, LabelValues),
try
Fun()
after
dec(Registry, Name, LabelValues)
end;
track_inprogress(_Registry, _Name, _LabelValues, Fun) ->
erlang:error({invalid_value, Fun, "track_inprogress accepts only functions"}).
%% @equiv reset(default, Name, [])
reset(Name) ->
reset(default, Name, []).
%% @equiv reset(default, Name, LabelValues)
reset(Name, LabelValues) ->
reset(default, Name, LabelValues).
reset(Registry, Name, LabelValues) ->
prometheus_metric:check_mf_exists(?TABLE, Registry, Name, LabelValues),
ets:update_element(?TABLE, {Registry, Name, LabelValues}, {?GAUGE_POS, 0}).
%% @equiv value(default, Name, [])
value(Name) ->
value(default, Name, []).
%% @equiv value(default, Name, LabelValues)
value(Name, LabelValues) ->
value(default, Name, LabelValues).
value(Registry, Name, LabelValues) ->
prometheus_metric:check_mf_exists(?TABLE, Registry, Name, LabelValues),
case ets:lookup(?TABLE, {Registry, Name, LabelValues}) of
[{_Key, Value}] -> Value;
[] -> undefined
end.
%%====================================================================
%% Collector API
%%====================================================================
deregister_cleanup(Registry) ->
prometheus_metric:deregister_mf(?TABLE, Registry),
true = ets:match_delete(?TABLE, {{Registry, '_', '_'}, '_'}),
ok.
collect_mf(Registry, Callback) ->
[Callback(create_gauge(Name, Help, {Labels, Registry})) ||
[Name, Labels, Help, _] <- prometheus_metric:metrics(?TABLE, Registry)],
ok.
collect_metrics(Name, {Labels, Registry}) ->
[gauge_metric(lists:zip(Labels, LabelValues), Value) ||
[LabelValues, Value] <- ets:match(?TABLE, {{Registry, Name, '$1'}, '$2'})].
%%====================================================================
%% Private Parts
%%====================================================================
inc(Registry, Name, LabelValues) ->
inc(Registry, Name, LabelValues, 1).
inc(Registry, Name, LabelValues, Inc) ->
try
ets:update_counter(?TABLE, {Registry, Name, LabelValues},
{?GAUGE_POS, Inc})
catch error:badarg ->
insert_metric(Registry, Name, LabelValues, Inc, fun inc/4)
end,
ok.
dec(Registry, Name, LabelValues) ->
inc(Registry, Name, LabelValues, -1).
insert_metric(Registry, Name, LabelValues, Value, ConflictCB) ->
prometheus_metric:check_mf_exists(?TABLE, Registry, Name, LabelValues),
case ets:insert_new(?TABLE, {{Registry, Name, LabelValues}, Value}) of
false -> %% some sneaky process already inserted
ConflictCB(Registry, Name, LabelValues, Value);
true ->
ok
end.
create_gauge(Name, Help, Data) ->
prometheus_model_helpers:create_mf(Name, Help, gauge, ?MODULE, Data).