Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions deps/rabbitmq_prometheus/priv/schema/rabbitmq_prometheus.schema
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,23 @@ end}.
%% Authentication options ========================================================
{mapping, "prometheus.authentication.enabled", "rabbitmq_prometheus.authentication.enabled",
[{datatype, boolean}]}.

%% Endpoint disable options ========================================================
{mapping, "prometheus.disable_memory_breakdown_endpoint", "rabbitmq_prometheus.disable_memory_breakdown_endpoint",
[{datatype, {enum, [true, false]}}]}.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With Cuttlefish 3.9.x, you can use the boolean type.


{mapping, "prometheus.disable_per_object_endpoint", "rabbitmq_prometheus.disable_per_object_endpoint",
[{datatype, {enum, [true, false]}}]}.

{mapping, "prometheus.disable_detailed_endpoint", "rabbitmq_prometheus.disable_detailed_endpoint",
[{datatype, {enum, [true, false]}}]}.

%% Metric blocklist options ========================================================
{mapping, "prometheus.disabled_metrics.$metric", "rabbitmq_prometheus.disabled_metrics",
[{datatype, atom}]}.

{translation, "rabbitmq_prometheus.disabled_metrics",
fun(Conf) ->
Settings = cuttlefish_variable:filter_by_prefix("prometheus.disabled_metrics", Conf),
[V || {_, V} <- Settings]
end}.
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ add_metric_family({Name, Type, Help, Metrics}, Callback) ->
Callback(create_mf(MN, Help, Type, Metrics)).

mf(Callback, Prefix, Contents, Data) ->
DisabledMetrics = rabbit_prometheus_util:normalize_disabled_metrics(application:get_env(rabbitmq_prometheus, disabled_metrics, [])),
_ = [begin
Fun = case Conversion of
undefined ->
Expand All @@ -493,7 +494,7 @@ mf(Callback, Prefix, Contents, Data) ->
{Type, Fun, Data}
)
)
end || {Index, Conversion, Name, Type, Help} <- Contents],
end || {Index, Conversion, Name, Type, Help} <- Contents, not lists:member(Name, DisabledMetrics)],
[begin
Fun = case Conversion of
undefined ->
Expand All @@ -510,7 +511,7 @@ mf(Callback, Prefix, Contents, Data) ->
{Type, Fun, Data}
)
)
end || {Index, Conversion, Name, Type, Help, Key} <- Contents].
end || {Index, Conversion, Name, Type, Help, Key} <- Contents, not lists:member(Name, DisabledMetrics)].

mf_totals(Callback, Name, Type, Help, Size) ->
Callback(
Expand Down
30 changes: 21 additions & 9 deletions deps/rabbitmq_prometheus/src/rabbit_prometheus_dispatcher.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,27 @@ build_dispatcher() ->
true -> PerObjectCollectors
end
),
prometheus_registry:register_collectors('per-object',
CoreCollectors ++ PerObjectCollectors),
prometheus_registry:register_collectors('detailed', [
prometheus_rabbitmq_core_metrics_collector,
prometheus_rabbitmq_raft_metrics_collector
]),
prometheus_registry:register_collectors('memory-breakdown', [
prometheus_rabbitmq_core_metrics_collector
]),
case application:get_env(rabbitmq_prometheus, disable_per_object_endpoint, true) of
true -> ok;
false ->
prometheus_registry:register_collectors('per-object',
CoreCollectors ++ PerObjectCollectors)
end,
case application:get_env(rabbitmq_prometheus, disable_detailed_endpoint, false) of
true -> ok;
false ->
prometheus_registry:register_collectors('detailed', [
prometheus_rabbitmq_core_metrics_collector,
prometheus_rabbitmq_raft_metrics_collector
])
end,
case application:get_env(rabbitmq_prometheus, disable_memory_breakdown_endpoint, false) of
true -> ok;
false ->
prometheus_registry:register_collectors('memory-breakdown', [
prometheus_rabbitmq_core_metrics_collector
])
end,
rabbit_prometheus_handler:setup(),
cowboy_router:compile([{'_', dispatcher()}]).

Expand Down
15 changes: 12 additions & 3 deletions deps/rabbitmq_prometheus/src/rabbit_prometheus_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,18 @@ is_authorized(ReqData, Context) ->

setup() ->
setup_metrics(telemetry_registry()),
setup_metrics('per-object'),
setup_metrics('memory-breakdown'),
setup_metrics('detailed').
case application:get_env(rabbitmq_prometheus, disable_per_object_endpoint, true) of
true -> ok;
false -> setup_metrics('per-object')
end,
case application:get_env(rabbitmq_prometheus, disable_memory_breakdown_endpoint, false) of
true -> ok;
false -> setup_metrics('memory-breakdown')
end,
case application:get_env(rabbitmq_prometheus, disable_detailed_endpoint, false) of
true -> ok;
false -> setup_metrics('detailed')
end.

setup_metrics(Registry) ->
ScrapeDuration = [{name, ?SCRAPE_DURATION},
Expand Down
24 changes: 24 additions & 0 deletions deps/rabbitmq_prometheus/src/rabbit_prometheus_util.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
%% This Source Code Form is subject to the terms of the Mozilla Public
%% License, v. 2.0. If a copy of the MPL was not distributed with this
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
%%
%% Copyright (c) 2007-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%

-module(rabbit_prometheus_util).

-export([normalize_disabled_metrics/1,
normalize_metric_name/1]).

-spec normalize_disabled_metrics([atom()]) -> [atom()].
normalize_disabled_metrics(Metrics) ->
[normalize_metric_name(M) || M <- Metrics].

-spec normalize_metric_name(atom()) -> atom().
normalize_metric_name(Metric) when is_atom(Metric) ->
case atom_to_list(Metric) of
"rabbitmq_detailed_" ++ Rest -> list_to_atom(Rest);
"rabbitmq_cluster_" ++ Rest -> list_to_atom(Rest);
"rabbitmq_" ++ Rest -> list_to_atom(Rest);
_ -> Metric
end.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%% License, v. 2.0. If a copy of the MPL was not distributed with this
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
%%
%% Copyright (c) 2007-2025 Broadcom. All Rights Reserved. The term Broadcom refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%% Copyright (c) 2007-2026 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%

[
Expand Down Expand Up @@ -343,6 +343,51 @@
], [rabbitmq_prometheus]
},

%%
%% Endpoint disable options
%%

{disable_memory_breakdown_endpoint,
"prometheus.disable_memory_breakdown_endpoint = true",
[
{rabbitmq_prometheus, [
{disable_memory_breakdown_endpoint, true}
]}
], [rabbitmq_prometheus]
},

{disable_per_object_endpoint,
"prometheus.disable_per_object_endpoint = true",
[
{rabbitmq_prometheus, [
{disable_per_object_endpoint, true}
]}
], [rabbitmq_prometheus]
},

{disable_detailed_endpoint,
"prometheus.disable_detailed_endpoint = true",
[
{rabbitmq_prometheus, [
{disable_detailed_endpoint, true}
]}
], [rabbitmq_prometheus]
},

%%
%% Metric blocklist options
%%

{disabled_metrics,
"prometheus.disabled_metrics.1 = queue_messages
prometheus.disabled_metrics.2 = connection_incoming_bytes_total",
[
{rabbitmq_prometheus, [
{disabled_metrics, [queue_messages, connection_incoming_bytes_total]}
]}
], [rabbitmq_prometheus]
},

{tls_listener_password_plain,
"prometheus.ssl.password = t0p$3cr3t",
[{rabbitmq_prometheus,[
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
%% This Source Code Form is subject to the terms of the Mozilla Public
%% License, v. 2.0. If a copy of the MPL was not distributed with this
%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
%%
%% Copyright (c) 2007-2026 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%%

-module(rabbit_prometheus_disabled_metrics_SUITE).

-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("rabbitmq_ct_helpers/include/rabbit_mgmt_test.hrl").

-compile([export_all, nowarn_export_all]).

all() ->
[
{group, default_settings},
{group, disabled_endpoints},
{group, disabled_metrics}
].

groups() ->
[
{default_settings, [], [
per_object_endpoint_disabled_by_default_test
]},
{disabled_endpoints, [], [
disable_per_object_endpoint_test,
disable_detailed_endpoint_test,
disable_memory_breakdown_endpoint_test
]},
{disabled_metrics, [], [
disable_single_metric_test,
disable_multiple_metrics_test,
normalize_metric_name_test
]}
].

init_per_group(default_settings, Config) ->
init_group(Config);
init_per_group(disabled_endpoints, Config) ->
EndpointConfig = {rabbitmq_prometheus, [
{disable_per_object_endpoint, true},
{disable_detailed_endpoint, true},
{disable_memory_breakdown_endpoint, true}
]},
Config1 = rabbit_ct_helpers:merge_app_env(Config, EndpointConfig),
init_group(Config1);
init_per_group(disabled_metrics, Config) ->
MetricsConfig = {rabbitmq_prometheus, [
{disabled_metrics, [queue_messages, connection_incoming_bytes_total]}
]},
Config1 = rabbit_ct_helpers:merge_app_env(Config, MetricsConfig),
init_group(Config1).

init_group(Config) ->
rabbit_ct_helpers:log_environment(),
inets:start(),
rabbit_ct_helpers:run_setup_steps(Config,
rabbit_ct_broker_helpers:setup_steps() ++
rabbit_ct_client_helpers:setup_steps()).

end_per_group(_, Config) ->
inets:stop(),
rabbit_ct_helpers:run_teardown_steps(Config,
rabbit_ct_client_helpers:teardown_steps() ++
rabbit_ct_broker_helpers:teardown_steps()).

init_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_started(Config, Testcase).

end_per_testcase(Testcase, Config) ->
rabbit_ct_helpers:testcase_finished(Config, Testcase).

%% Tests

disable_per_object_endpoint_test(Config) ->
Port = rabbit_mgmt_test_util:config_port(Config, tcp_port_prometheus),
URI = lists:flatten(io_lib:format("http://localhost:~tp/metrics/per-object", [Port])),
{ok, {{_, Code, _}, _, _}} = httpc:request(get, {URI, []}, ?HTTPC_OPTS, []),
?assertEqual(404, Code).

disable_detailed_endpoint_test(Config) ->
Port = rabbit_mgmt_test_util:config_port(Config, tcp_port_prometheus),
URI = lists:flatten(io_lib:format("http://localhost:~tp/metrics/detailed", [Port])),
{ok, {{_, Code, _}, _, _}} = httpc:request(get, {URI, []}, ?HTTPC_OPTS, []),
?assertEqual(404, Code).

disable_memory_breakdown_endpoint_test(Config) ->
Port = rabbit_mgmt_test_util:config_port(Config, tcp_port_prometheus),
URI = lists:flatten(io_lib:format("http://localhost:~tp/metrics/memory-breakdown", [Port])),
{ok, {{_, Code, _}, _, _}} = httpc:request(get, {URI, []}, ?HTTPC_OPTS, []),
?assertEqual(404, Code).

per_object_endpoint_disabled_by_default_test(Config) ->
Port = rabbit_mgmt_test_util:config_port(Config, tcp_port_prometheus),
URI = lists:flatten(io_lib:format("http://localhost:~tp/metrics/per-object", [Port])),
{ok, {{_, Code, _}, _, _}} = httpc:request(get, {URI, []}, ?HTTPC_OPTS, []),
?assertEqual(404, Code).

disable_single_metric_test(Config) ->
{_, Body} = http_get(Config, [], 200),
?assertEqual(nomatch, re:run(Body, "^rabbitmq_queue_messages ", [{capture, none}, multiline])),
?assertEqual(match, re:run(Body, "^rabbitmq_connections ", [{capture, none}, multiline])).

disable_multiple_metrics_test(Config) ->
{_, Body} = http_get(Config, [], 200),
?assertEqual(nomatch, re:run(Body, "^rabbitmq_queue_messages ", [{capture, none}, multiline])),
?assertEqual(nomatch, re:run(Body, "^rabbitmq_connection_incoming_bytes_total ", [{capture, none}, multiline])).

normalize_metric_name_test(_Config) ->
?assertEqual(queue_messages, rabbit_prometheus_util:normalize_metric_name(rabbitmq_queue_messages)),
?assertEqual(queue_messages, rabbit_prometheus_util:normalize_metric_name(rabbitmq_detailed_queue_messages)),
?assertEqual(vhost_status, rabbit_prometheus_util:normalize_metric_name(rabbitmq_cluster_vhost_status)),
?assertEqual(other_metric, rabbit_prometheus_util:normalize_metric_name(other_metric)).

%% Helpers

http_get(Config, ReqHeaders, CodeExp) ->
Port = rabbit_mgmt_test_util:config_port(Config, tcp_port_prometheus),
URI = lists:flatten(io_lib:format("http://localhost:~tp/metrics", [Port])),
{ok, {{_, CodeAct, _}, Headers, Body}} =
httpc:request(get, {URI, ReqHeaders}, ?HTTPC_OPTS, []),
?assertMatch(CodeExp, CodeAct),
{Headers, Body}.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ init_per_group(per_object_metrics, Config0) ->
init_aggregated_metrics(per_object_metrics, Config1);
init_per_group(per_object_endpoint_metrics, Config0) ->
PathConfig = {rabbitmq_prometheus, [
{return_per_object_metrics, false}
{return_per_object_metrics, false},
{disable_per_object_endpoint, false}
]},
Config1 = rabbit_ct_helpers:merge_app_env(Config0, PathConfig),
init_aggregated_metrics(per_object_endpoint_metrics, Config1);
Expand Down Expand Up @@ -259,7 +260,11 @@ init_per_group(memory_breakdown_endpoint_metrics, Config) ->
init_aggregated_metrics(Group, Config0) ->
Config1 = rabbit_ct_helpers:merge_app_env(
Config0,
[{rabbit, [{collect_statistics, coarse}, {collect_statistics_interval, 100}]}]
[{rabbit, [{collect_statistics, coarse}, {collect_statistics_interval, 100}]},
%% Enable the per-object endpoint so the readiness probe below can
%% confirm queue stats have been collected. Per-object is opt-in by
%% default, but tests in these groups depend on it.
{rabbitmq_prometheus, [{disable_per_object_endpoint, false}]}]
),
Config2 = init_per_group(Group, Config1, []),

Expand Down
Loading