summaryrefslogtreecommitdiff
path: root/deps/rabbitmq_prometheus/src/rabbit_prometheus_app.erl
diff options
context:
space:
mode:
Diffstat (limited to 'deps/rabbitmq_prometheus/src/rabbit_prometheus_app.erl')
-rw-r--r--deps/rabbitmq_prometheus/src/rabbit_prometheus_app.erl134
1 files changed, 134 insertions, 0 deletions
diff --git a/deps/rabbitmq_prometheus/src/rabbit_prometheus_app.erl b/deps/rabbitmq_prometheus/src/rabbit_prometheus_app.erl
new file mode 100644
index 0000000000..4aa2934b7e
--- /dev/null
+++ b/deps/rabbitmq_prometheus/src/rabbit_prometheus_app.erl
@@ -0,0 +1,134 @@
+%% 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-2020 VMware, Inc. or its affiliates. All rights reserved.
+%%
+
+-module(rabbit_prometheus_app).
+
+-behaviour(application).
+-export([start/2, stop/1]).
+
+-behaviour(supervisor).
+-export([init/1]).
+
+-define(TCP_CONTEXT, rabbitmq_prometheus_tcp).
+-define(TLS_CONTEXT, rabbitmq_prometheus_tls).
+-define(DEFAULT_PORT, 15692).
+-define(DEFAULT_TLS_PORT, 15691).
+
+start(_Type, _StartArgs) ->
+ %% TCP listener uses prometheus.tcp.*.
+ %% TLS listener uses prometheus.ssl.*
+ start_configured_listener(),
+ supervisor:start_link({local,?MODULE},?MODULE,[]).
+
+stop(_State) ->
+ unregister_all_contexts(),
+ ok.
+
+init(_) ->
+ {ok, {{one_for_one, 3, 10}, []}}.
+
+-spec start_configured_listener() -> ok.
+start_configured_listener() ->
+ Listeners0 = case {has_configured_tcp_listener(),
+ has_configured_tls_listener()} of
+ {false, false} ->
+ %% nothing is configured
+ [get_tcp_listener()];
+ {false, true} ->
+ [get_tls_listener()];
+ {true, false} ->
+ [get_tcp_listener()];
+ {true, true} ->
+ [get_tcp_listener(),
+ get_tls_listener()]
+ end,
+ Listeners1 = maybe_disable_sendfile(Listeners0),
+ [start_listener(Listener) || Listener <- Listeners1].
+
+maybe_disable_sendfile(Listeners) ->
+ DisableSendfile = #{sendfile => false},
+ F = fun(L0) ->
+ CowboyOptsL0 = proplists:get_value(cowboy_opts, L0, []),
+ CowboyOptsM0 = maps:from_list(CowboyOptsL0),
+ CowboyOptsM1 = maps:merge(DisableSendfile, CowboyOptsM0),
+ CowboyOptsL1 = maps:to_list(CowboyOptsM1),
+ L1 = lists:keydelete(cowboy_opts, 1, L0),
+ [{cowboy_opts, CowboyOptsL1}|L1]
+ end,
+ lists:map(F, Listeners).
+
+has_configured_tcp_listener() ->
+ has_configured_listener(tcp_config).
+
+has_configured_tls_listener() ->
+ has_configured_listener(ssl_config).
+
+has_configured_listener(Key) ->
+ case application:get_env(rabbitmq_prometheus, Key, undefined) of
+ undefined -> false;
+ _ -> true
+ end.
+
+get_tls_listener() ->
+ {ok, Listener0} = application:get_env(rabbitmq_prometheus, ssl_config),
+ case proplists:get_value(cowboy_opts, Listener0) of
+ undefined ->
+ [{ssl, true}, {ssl_opts, Listener0}];
+ CowboyOpts ->
+ Listener1 = lists:keydelete(cowboy_opts, 1, Listener0),
+ [{ssl, true}, {ssl_opts, Listener1}, {cowboy_opts, CowboyOpts}]
+ end.
+
+get_tcp_listener() ->
+ application:get_env(rabbitmq_prometheus, tcp_config, []).
+
+start_listener(Listener0) ->
+ {Type, ContextName, Protocol} = case is_tls(Listener0) of
+ true -> {tls, ?TLS_CONTEXT, 'https/prometheus'};
+ false -> {tcp, ?TCP_CONTEXT, 'http/prometheus'}
+ end,
+ {ok, Listener1} = ensure_port_and_protocol(Type, Protocol, Listener0),
+ {ok, _} = register_context(ContextName, Listener1),
+ log_startup(Type, Listener1).
+
+register_context(ContextName, Listener) ->
+ Dispatcher = rabbit_prometheus_dispatcher:build_dispatcher(),
+ rabbit_web_dispatch:register_context_handler(
+ ContextName, Listener, "",
+ Dispatcher, "RabbitMQ Prometheus").
+
+unregister_all_contexts() ->
+ rabbit_web_dispatch:unregister_context(?TCP_CONTEXT),
+ rabbit_web_dispatch:unregister_context(?TLS_CONTEXT).
+
+ensure_port_and_protocol(tls, Protocol, Listener) ->
+ do_ensure_port_and_protocol(?DEFAULT_TLS_PORT, Protocol, Listener);
+ensure_port_and_protocol(tcp, Protocol, Listener) ->
+ do_ensure_port_and_protocol(?DEFAULT_PORT, Protocol, Listener).
+
+do_ensure_port_and_protocol(Port, Protocol, Listener) ->
+ %% include default port if it's not provided in the config
+ %% as Cowboy won't start if the port is missing
+ M0 = maps:from_list(Listener),
+ M1 = maps:merge(#{port => Port, protocol => Protocol}, M0),
+ {ok, maps:to_list(M1)}.
+
+log_startup(tcp, Listener) ->
+ rabbit_log:info("Prometheus metrics: HTTP (non-TLS) listener started on port ~w", [port(Listener)]);
+log_startup(tls, Listener) ->
+ rabbit_log:info("Prometheus metrics: HTTPS listener started on port ~w", [port(Listener)]).
+
+
+port(Listener) ->
+ proplists:get_value(port, Listener, ?DEFAULT_PORT).
+
+is_tls(Listener) ->
+ case proplists:get_value(ssl, Listener) of
+ undefined -> false;
+ false -> false;
+ _ -> true
+ end.