emqx_alarm_handler.erl 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2019-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_alarm_handler).
  17. -behaviour(gen_event).
  18. -include("emqx.hrl").
  19. -include("logger.hrl").
  20. -include_lib("lc/include/lc.hrl").
  21. %% gen_event callbacks
  22. -export([
  23. init/1,
  24. handle_event/2,
  25. handle_call/2,
  26. handle_info/2,
  27. terminate/2
  28. ]).
  29. -export([
  30. load/0,
  31. unload/0
  32. ]).
  33. %%--------------------------------------------------------------------
  34. %% API
  35. %%--------------------------------------------------------------------
  36. load() ->
  37. gen_event:swap_handler(alarm_handler, {alarm_handler, swap}, {?MODULE, []}).
  38. %% on the way shutting down, give it back to OTP
  39. unload() ->
  40. gen_event:swap_handler(alarm_handler, {?MODULE, swap}, {alarm_handler, []}).
  41. %%--------------------------------------------------------------------
  42. %% gen_event callbacks
  43. %%--------------------------------------------------------------------
  44. init({_Args, {alarm_handler, _ExistingAlarms}}) ->
  45. {ok, []};
  46. init(_) ->
  47. {ok, []}.
  48. handle_event({set_alarm, {process_memory_high_watermark, Pid}}, State) ->
  49. HighWatermark = emqx_os_mon:get_procmem_high_watermark(),
  50. Message = to_bin("Process memory usage is higher than ~p%", [HighWatermark]),
  51. emqx_alarm:activate(
  52. high_process_memory_usage,
  53. #{
  54. pid => list_to_binary(pid_to_list(Pid)),
  55. high_watermark => HighWatermark
  56. },
  57. Message
  58. ),
  59. {ok, State};
  60. handle_event({clear_alarm, process_memory_high_watermark}, State) ->
  61. emqx_alarm:ensure_deactivated(high_process_memory_usage),
  62. {ok, State};
  63. handle_event({set_alarm, {?LC_ALARM_ID_RUNQ, Info}}, State) ->
  64. #{node := Node, runq_length := Len} = Info,
  65. Message = to_bin("VM is overloaded on node: ~p: ~p", [Node, Len]),
  66. emqx_alarm:activate(runq_overload, Info, Message),
  67. {ok, State};
  68. handle_event({clear_alarm, ?LC_ALARM_ID_RUNQ}, State) ->
  69. emqx_alarm:ensure_deactivated(runq_overload),
  70. {ok, State};
  71. handle_event(_, State) ->
  72. {ok, State}.
  73. handle_info(_, State) ->
  74. {ok, State}.
  75. handle_call(_Query, State) ->
  76. {ok, {error, bad_query}, State}.
  77. terminate(swap, _State) ->
  78. {emqx_alarm_handler, []};
  79. terminate(_, _) ->
  80. ok.
  81. to_bin(Format, Args) ->
  82. io_lib:format(Format, Args).