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.CheckLocalAlarmsCommand do 8 @moduledoc """ 9 Exits with a non-zero code if the target node reports any local alarms. 10 11 This command is meant to be used in health checks. 12 """ 13 14 import RabbitMQ.CLI.Core.Alarms 15 import RabbitMQ.CLI.Core.Platform, only: [line_separator: 0] 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 case :rabbit_misc.rpc_call(node_name, :rabbit_alarm, :get_alarms, [], timeout) do 37 [] -> [] 38 xs when is_list(xs) -> local_alarms(xs, node_name) 39 other -> other 40 end 41 end 42 43 def output([], %{formatter: "json"}) do 44 {:ok, %{"result" => "ok"}} 45 end 46 47 def output([], %{silent: true}) do 48 {:ok, :check_passed} 49 end 50 51 def output([], %{node: node_name}) do 52 {:ok, "Node #{node_name} reported no local alarms"} 53 end 54 55 def output(alarms, %{node: node_name, formatter: "json"}) do 56 {:error, :check_failed, 57 %{ 58 "result" => "error", 59 "local" => alarm_lines(alarms, node_name), 60 "message" => "Node #{node_name} reported local alarms" 61 }} 62 end 63 64 def output(_alarms, %{silent: true}) do 65 {:error, :check_failed} 66 end 67 68 def output(alarms, %{node: node_name}) do 69 lines = alarm_lines(alarms, node_name) 70 71 {:error, Enum.join(lines, line_separator())} 72 end 73 74 use RabbitMQ.CLI.DefaultOutput 75 76 def help_section(), do: :observability_and_health_checks 77 78 def description(), do: "Health check that exits with a non-zero code if the target node reports any local alarms" 79 80 def usage, do: "check_local_alarms" 81 82 def banner([], %{node: node_name}) do 83 "Asking node #{node_name} to report any local resource alarms ..." 84 end 85end 86