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
7defmodule RabbitMQ.CLI.Diagnostics.Commands.AlarmsCommand do
8  @moduledoc """
9  Displays all alarms reported by the target node.
10
11  Returns a code of 0 unless there were connectivity and authentication
12  errors. This command is not meant to be used in health checks.
13  """
14  import RabbitMQ.CLI.Core.Platform, only: [line_separator: 0]
15  import RabbitMQ.CLI.Core.Alarms
16
17  @behaviour RabbitMQ.CLI.CommandBehaviour
18
19  use RabbitMQ.CLI.Core.AcceptsDefaultSwitchesAndTimeout
20  use RabbitMQ.CLI.Core.MergesNoDefaults
21  use RabbitMQ.CLI.Core.AcceptsNoPositionalArguments
22  use RabbitMQ.CLI.Core.RequiresRabbitAppRunning
23
24  def run([], %{node: node_name, timeout: timeout}) do
25    # Example response when there are alarms:
26    #
27    # [
28    #  file_descriptor_limit,
29    #  {{resource_limit,disk,hare@warp10},[]},
30    #  {{resource_limit,memory,hare@warp10},[]},
31    #  {{resource_limit,disk,rabbit@warp10},[]},
32    #  {{resource_limit,memory,rabbit@warp10},[]}
33    # ]
34    #
35    # The topmost file_descriptor_limit alarm is node-local.
36    :rabbit_misc.rpc_call(node_name, :rabbit_alarm, :get_alarms, [], timeout)
37  end
38
39  def output([], %{node: node_name, formatter: "json"}) do
40    {:ok, %{"result" => "ok", "node" => node_name, "alarms" => []}}
41  end
42
43  def output([], %{node: node_name}) do
44    {:ok, "Node #{node_name} reported no alarms, local or clusterwide"}
45  end
46
47  def output(alarms, %{node: node_name, formatter: "json"}) do
48    local = local_alarms(alarms, node_name)
49    global = clusterwide_alarms(alarms, node_name)
50
51    {:ok,
52     %{
53       "result" => "ok",
54       "local" => alarm_lines(local, node_name),
55       "global" => alarm_lines(global, node_name),
56       "message" => "Node #{node_name} reported alarms"
57     }}
58  end
59
60  def output(alarms, %{node: node_name}) do
61    lines = alarm_lines(alarms, node_name)
62
63    {:ok, Enum.join(lines, line_separator())}
64  end
65
66  use RabbitMQ.CLI.DefaultOutput
67
68  def help_section(), do: :observability_and_health_checks
69
70  def description(), do: "Lists resource alarms (local or cluster-wide) in effect on the target node"
71
72  def usage, do: "alarms"
73
74  def banner([], %{node: node_name}) do
75    "Asking node #{node_name} to report any known resource alarms ..."
76  end
77end
78