@@ -301,14 +301,25 @@ register() ->
301301deregister_cleanup (_ ) -> ok .
302302
303303collect_mf ('detailed' , Callback ) ->
304- collect (true , ? DETAILED_METRIC_NAME_PREFIX , vhosts_filter_from_pdict (), enabled_mfs_from_pdict (? METRICS_RAW ), Callback ),
304+ IncludedMFs = enabled_mfs_from_pdict (? METRICS_RAW ),
305+ collect (true , ? DETAILED_METRIC_NAME_PREFIX , vhosts_filter_from_pdict (), IncludedMFs , Callback ),
305306 collect (true , ? CLUSTER_METRIC_NAME_PREFIX , vhosts_filter_from_pdict (), enabled_mfs_from_pdict (? METRICS_CLUSTER ), Callback ),
307+ % % the detailed endpoint should emit queue_info only if queue metrics were requested
308+ MFs = proplists :get_keys (IncludedMFs ),
309+ case lists :member (queue_coarse_metrics , MFs ) orelse
310+ lists :member (queue_consumer_count , MFs ) orelse
311+ lists :member (queue_metrics , MFs ) of
312+ true ->
313+ emit_queue_info (? DETAILED_METRIC_NAME_PREFIX , Callback );
314+ false -> ok
315+ end ,
306316 % % identity is here to enable filtering on a cluster name (as already happens in existing dashboards)
307317 emit_identity_info (<<" detailed" >>, Callback ),
308318 ok ;
309319collect_mf ('per-object' , Callback ) ->
310320 collect (true , ? METRIC_NAME_PREFIX , false , ? METRICS_RAW , Callback ),
311321 totals (Callback ),
322+ emit_queue_info (? METRIC_NAME_PREFIX , Callback ),
312323 emit_identity_info (<<" per-object" >>, Callback ),
313324 ok ;
314325collect_mf ('memory-breakdown' , Callback ) ->
@@ -406,6 +417,63 @@ identity_info(Endpoint) ->
406417 }]
407418 }.
408419
420+ emit_queue_info (Prefix , Callback ) ->
421+ Help = <<" A metric with a constant '1' value and labels that provide some queue details" >>,
422+
423+ QInfos = lists :foldl (
424+ fun (Q , Acc ) ->
425+ # resource {virtual_host = Vhost , name = Name } = QName = amqqueue :get_name (Q ),
426+ QInfo0 = [{vhost , Vhost }, {queue , Name }],
427+ case amqqueue :get_type (Q ) of
428+ rabbit_classic_queue = T ->
429+ case amqqueue :qnode (Q ) =:= node () of
430+ true ->
431+ QInfo = [{queue_type , T } | QInfo0 ],
432+ [{QInfo , 1 }|Acc ];
433+ false ->
434+ % % skip non-local queues
435+ Acc
436+ end ;
437+ rabbit_quorum_queue = T ->
438+ case rabbit_quorum_queue :infos (QName , [local_state ]) of
439+ [{local_state , not_member }] ->
440+ % % skip quorum queues with no local member
441+ Acc ;
442+ [{local_state , State }] ->
443+ QInfo = [{queue_type , T }, {membership , State } | QInfo0 ],
444+ [{QInfo , 1 }|Acc ];
445+ State ->
446+ rabbit_log :warning (" Unexpected quorum queue state: ~p " , [State ]),
447+ Acc
448+ end ;
449+ rabbit_stream_queue = T ->
450+ case rabbit_stream_queue :info (Q , [leader ,members ]) of
451+ [{leader , L }, {members , _ }] when L =:= node () ->
452+ QInfo = [{queue_type , T }, {membership , leader } | QInfo0 ],
453+ [{QInfo , 1 }|Acc ];
454+ [{leader , _ }, {members , Members }] ->
455+ case lists :member (node (), Members ) of
456+ true ->
457+ QInfo = [{queue_type , stream }, {membership , follower } | QInfo0 ],
458+ [{QInfo , 1 }|Acc ];
459+ false ->
460+ % % skip stream queues with no local member
461+ Acc
462+ end
463+ end ;
464+ T ->
465+ case amqqueue :qnode (Q ) =:= node () of
466+ true ->
467+ QInfo = [{queue_type , T } | QInfo0 ],
468+ [{QInfo , 1 }|Acc ];
469+ false ->
470+ % % skip non-local queues
471+ Acc
472+ end
473+ end
474+ end , [], rabbit_amqqueue :list ()),
475+ Callback (prometheus_model_helpers :create_mf (<<Prefix /binary , " queue_info" >>, Help , gauge , QInfos )).
476+
409477add_metric_family ({Name , Type , Help , Metrics }, Callback ) ->
410478 MN = <<? METRIC_NAME_PREFIX /binary , (prometheus_model_helpers :metric_name (Name ))/binary >>,
411479 Callback (create_mf (MN , Help , Type , Metrics )).
0 commit comments