Current section

Files

Jump to
prometheus src collectors vm prometheus_vm_memory_collector.erl
Raw

src/collectors/vm/prometheus_vm_memory_collector.erl

-module(prometheus_vm_memory_collector).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC("""
Collects information about memory dynamically allocated by the Erlang emulator using
`erlang:memory/0`, also provides basic (D)ETS statistics.
### Exported metrics
* `erlang_vm_memory_atom_bytes{usage=\"free|used\"}`
Type: gauge.
The total amount of memory currently allocated for atoms.
This memory is part of the memory presented as system memory.
* `erlang_vm_memory_bytes{kind=\"system|processes\"}`
Type: gauge.
The total amount of memory currently allocated.
This is the same as the sum of the memory size for processes and system.
* `erlang_vm_memory_dets_tables`
Type: gauge.
Erlang VM DETS Tables count.
* `erlang_vm_memory_ets_tables`
Type: gauge.
Erlang VM ETS Tables count.
* `erlang_vm_memory_processes_bytes{usage=\"free|used\"}`
Type: gauge.
The total amount of memory currently allocated for the Erlang processes.
* `erlang_vm_memory_system_bytes{usage=\"atom|binary|code|ets|other\"}`
Type: gauge.
The total amount of memory currently allocated for the emulator that is not directly related
to any Erlang process. Memory presented as processes is not included in this memory.
### Configuration
Metrics exported by this collector can be configured via `vm_memory_collector_metrics` key
of the `prometheus` app environment.
Available options:
* `atom_bytes` for `erlang_vm_memory_atom_bytes`.
* `bytes` for `erlang_vm_memory_bytes`.
* `dets_tables` for `erlang_vm_dets_tables`.
* `ets_tables` for `erlang_vm_ets_tables`.
* `processes_bytes` for `erlang_vm_memory_processes_bytes`.
* `system_bytes` for `erlang_vm_memory_system_bytes`.
By default all metrics are enabled.
""").
-export([deregister_cleanup/1, collect_mf/2]).
-include("prometheus.hrl").
-behaviour(prometheus_collector).
-define(METRIC_NAME_PREFIX, "erlang_vm_memory_").
?DOC(false).
-spec deregister_cleanup(prometheus_registry:registry()) -> ok.
deregister_cleanup(_) ->
ok.
?DOC(false).
-spec collect_mf(_Registry, Callback) -> ok when
_Registry :: prometheus_registry:registry(),
Callback :: prometheus_collector:collect_mf_callback().
collect_mf(_Registry, Callback) ->
Metrics = prometheus_collectors_compat:pre_promtool_compat(metrics()),
EnabledMetrics = enabled_metrics(),
[
add_metric_family(Metric, Callback)
|| {Name, _, _, _} = Metric <- Metrics, metric_enabled(Name, EnabledMetrics)
],
ok.
add_metric_family({Name, Type, Help, Metrics}, Callback) ->
Callback(prometheus_model_helpers:create_mf(?METRIC_NAME(Name), Help, Type, Metrics)).
%%====================================================================
%% Private Parts
%%====================================================================
metrics() ->
Data = erlang:memory(),
[
{atom_bytes, gauge,
"The total amount of memory currently allocated "
"for atoms. This memory is part of the memory "
"presented as system memory.", [
{[{usage, used}], proplists:get_value(atom_used, Data)},
{
[{usage, free}],
proplists:get_value(atom, Data) - proplists:get_value(atom_used, Data)
}
]},
{bytes, gauge,
"The total amount of memory currently allocated. "
"This is the same as the sum of the memory size "
"for processes and system.", [
{[{kind, system}], proplists:get_value(system, Data)},
{[{kind, processes}], proplists:get_value(processes, Data)}
]},
{dets_tables, gauge, "Erlang VM DETS Tables count.", length(dets:all())},
{ets_tables, gauge, "Erlang VM ETS Tables count.", length(ets:all())},
{processes_bytes, gauge,
"The total amount of memory currently allocated "
"for the Erlang processes.", [
{[{usage, used}], proplists:get_value(processes_used, Data)},
{
[{usage, free}],
proplists:get_value(processes, Data) - proplists:get_value(processes_used, Data)
}
]},
{system_bytes, gauge,
"The total amount of memory currently allocated "
"for the emulator that is not directly related "
"to any Erlang process. Memory presented as processes "
"is not included in this memory.", [
{[{usage, atom}], proplists:get_value(atom, Data)},
{[{usage, binary}], proplists:get_value(binary, Data)},
{[{usage, code}], proplists:get_value(code, Data)},
{[{usage, ets}], proplists:get_value(ets, Data)},
{[{usage, other}], memory_other(Data)}
]}
].
memory_other(Data) ->
proplists:get_value(system, Data) -
proplists:get_value(atom, Data) -
proplists:get_value(binary, Data) -
proplists:get_value(code, Data) -
proplists:get_value(ets, Data).
enabled_metrics() ->
application:get_env(prometheus, vm_memory_collector_metrics, all).
metric_enabled(Name, Metrics) ->
Metrics =:= all orelse lists:member(Name, Metrics).