1%% This Source Code Form is subject to the terms of the Mozilla Public
2%% License, v. 2.0. If a copy of the MPL was not distributed with this
3%% file, You can obtain one at https://mozilla.org/MPL/2.0/.
4%%
5%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates.  All rights reserved.
6%%
7-module(rabbit_health_check).
8
9%% External API
10-export([node/1, node/2]).
11
12%% Internal API
13-export([local/0]).
14
15%%----------------------------------------------------------------------------
16%% External functions
17%%----------------------------------------------------------------------------
18
19node(Node) ->
20    %% same default as in CLI
21    node(Node, 70000).
22
23-spec node(node(), timeout()) -> ok | {badrpc, term()} | {error_string, string()}.
24
25node(Node, Timeout) ->
26    rabbit_misc:rpc_call(Node, rabbit_health_check, local, [], Timeout).
27
28-spec local() -> ok | {error_string, string()}.
29
30local() ->
31    rabbit_log:warning("rabbitmqctl node_health_check and its HTTP API counterpart are DEPRECATED. "
32                       "See https://www.rabbitmq.com/monitoring.html#health-checks for replacement options."),
33    run_checks([list_channels, list_queues, alarms, rabbit_node_monitor]).
34
35%%----------------------------------------------------------------------------
36%% Internal functions
37%%----------------------------------------------------------------------------
38run_checks([]) ->
39    ok;
40run_checks([C|Cs]) ->
41    case node_health_check(C) of
42        ok ->
43            run_checks(Cs);
44        Error ->
45            Error
46    end.
47
48node_health_check(list_channels) ->
49    case rabbit_channel:info_local([pid]) of
50        L when is_list(L) ->
51            ok
52    end;
53
54node_health_check(list_queues) ->
55    health_check_queues(rabbit_vhost:list_names());
56
57node_health_check(rabbit_node_monitor) ->
58    case rabbit_node_monitor:partitions() of
59        [] ->
60            ok;
61        L when is_list(L), length(L) > 0 ->
62            ErrorMsg = io_lib:format("cluster partition in effect: ~p", [L]),
63            {error_string, ErrorMsg}
64    end;
65
66node_health_check(alarms) ->
67    case proplists:get_value(alarms, rabbit:status()) of
68        [] ->
69            ok;
70        Alarms ->
71            ErrorMsg = io_lib:format("resource alarm(s) in effect:~p", [Alarms]),
72            {error_string, ErrorMsg}
73    end.
74
75health_check_queues([]) ->
76    ok;
77health_check_queues([VHost|RestVHosts]) ->
78    case rabbit_amqqueue:info_local(VHost) of
79        L when is_list(L) ->
80            health_check_queues(RestVHosts)
81    end.
82