104104% % Type: gauge.<br/>
105105% % The maximum number of simultaneously existing atom at the local node.
106106% % </li>
107+ % % <li>
108+ % % `erlang_vm_allocators'<br/>
109+ % % Type: gauge.<br/>
110+ % % Allocated (carriers_size) and used (blocks_size) memory
111+ % % for the different allocators in the VM. See erts_alloc(3).
112+ % % </li>
107113% % </ul>
108114% %
109115% % ==Configuration==
165171% % <li>
166172% % `atom_limit' for `erlang_vm_atom_limit'.
167173% % </li>
174+ % % <li>
175+ % % `allocators' for `erlang_vm_allocators'.
176+ % % </li>
168177% % </ul>
169178% %
170179% % By default all metrics are enabled.
@@ -264,9 +273,15 @@ metrics() ->
264273 " at the local node." },
265274 {atom_limit , gauge ,
266275 " The maximum number of simultaneously existing "
267- " atom at the local node." }
276+ " atom at the local node." },
277+ {allocators , gauge ,
278+ " Allocated (carriers_size) and used (blocks_size) "
279+ " memory for the different allocators in the VM. "
280+ " See erts_alloc(3)." }
268281 ].
269282
283+ collect_metrics (allocators ) ->
284+ collect_allocator_metrics ();
270285collect_metrics (Name ) ->
271286 try
272287 case erlang :system_info (Name ) of
@@ -282,3 +297,28 @@ enabled_metrics() ->
282297
283298metric_enabled (Name , Metrics ) ->
284299 Metrics =:= all orelse lists :member (Name , Metrics ).
300+
301+ collect_allocator_metrics () ->
302+ Metrics = lists :flatten ([begin
303+ [
304+ [
305+ allocator_metric (Alloc , Instance , Kind , Key , KindInfo )
306+ || Key <- [blocks , blocks_size , carriers , carriers_size ]]
307+ || {Kind , KindInfo } <- Info , (Kind =:= mbcs ) orelse (Kind =:= mbcs_pool ) orelse (Kind =:= sbcs )]
308+ end || {{Alloc , Instance }, Info } <- allocators ()]),
309+ prometheus_model_helpers :gauge_metrics (Metrics ).
310+
311+ allocator_metric (Alloc , Instance , Kind , Key , Values ) ->
312+ {[{alloc , Alloc }, {instance , Instance }, {kind , Kind }, {usage , Key }],
313+ element (2 , lists :keyfind (Key , 1 , Values ))}.
314+
315+ % % Originally copied from recon_alloc.
316+ allocators () ->
317+ Allocators = erlang :system_info (alloc_util_allocators ),
318+ % % versions is deleted in order to allow the use of the orddict api,
319+ % % and never really having come across a case where it was useful to know.
320+ [{{A , N }, lists :sort (proplists :delete (versions , Props ))} ||
321+ A <- Allocators ,
322+ Allocs <- [erlang :system_info ({allocator , A })],
323+ Allocs =/= false ,
324+ {_ , N , Props } <- Allocs ].
0 commit comments