23.3警报管理

  1. 警报器管理

我们编写的应用程序只需要一个警报,这个警报会在CPU因为计算超大质数而开始熔化时抛出(别忘了我们正在建设一家销售质数的公司)。这次将使用真正的OTP警报处理器(而不是在本章开头看到的简单版)。这个警报处理器是OTPgen_event行为的回调模块,它的代码如下。

%%%-------------------------------------------------------------------
%%% @author ZhengNan
%%% @copyright (C) 2024, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 13. 9月 2024 23:22
%%%-------------------------------------------------------------------
-module(my_alarm_handler).
-author("ZhengNan").
%%%=======================EXPORT=======================
-export([init/1, handler_event/2, handler_call/2, handler_info/2, terminate/2, code_change/3]).
%%%=======================INCLUDE======================
%%%=======================RECORD=======================
%%%=======================DEFINE=======================
%%%=======================TYPE=========================
%%%=================EXPORTED FUNCTIONS=================
%% ----------------------------------------------------
%% Description:
%% ----------------------------------------------------
init(Args) ->
	io:format("init my_alarm_handler by:~p~n ", [Args]),
	{ok, 0}.

handler_event({set_alarm, too_hot}, N) ->
	error_logger:error_msg("Tell the engineer to turn on the aircondition~n"),
	{ok, N + 1};
handler_event({clear_alarm, too_hot}, N) ->
	error_logger:error_msg("Danger over. Turn off the aircondition~n"),
	{ok, N};
handler_event(Event, N) ->
	io:format("unmatch event:~p~n", [Event]),
	{ok, N}.

handler_call(_Request, N) ->
	Reply = N, {ok, Reply, N}.
handler_info(_Info, N) ->
	{ok, N}.
terminate(_Reason, _N) ->
	ok.
code_change(_OlderVsn, State, _Extra) ->
	{ok, State}.
%%%===================LOCAL FUNCTIONS==================
%% ----------------------------------------------------
%% Description:
%% ----------------------------------------------------


现在来找点乐子:启动系统,生成一个警报,安装警报处理器,再生成一个警报……

PS C:\CodeProjects\ErlangProjects\erlang_learning\src\otp> erl -boot start_sasl -config .cfg/erlog
Eshell V9.3  (abort with ^G)
1> alarm_handler:set_alarm(too_hot).
ok

=INFO REPORT==== 18-Sep-2024::23:04:56 ===
    alarm_handler: {set,too_hot}
2> gen_event:swap_handler(alarm_handler,{alarm_handler,swap},{my_alarm_handler,zhengnan}). %%这里我们将警报器换成了上述我们自己编写的警报器
init my_alarm_handler by:{zhengnan,{alarm_handler,[too_hot]}}
 ok
3> alarm_handler:set_alarm(too_hot).
ok
4>
=ERROR REPORT==== 18-Sep-2024::23:06:36 ===
** gen_event handler my_alarm_handler crashed. %% 这里报错显示handle_event这个方法未导出
** Was installed in alarm_handler			   %% 我就应该仔细去看方法名称是否写错了
** Last event was: {set_alarm,too_hot}
** When handler state == 0
** Reason == {'function not exported',
                 [{my_alarm_handler,handle_event,[{set_alarm,too_hot},0],[]},
                  {gen_event,server_update,4,
                      [{file,"gen_event.erl"},{line,574}]},
                  {gen_event,server_notify,4,
                      [{file,"gen_event.erl"},{line,556}]},
                  {gen_event,handle_msg,6,[{file,"gen_event.erl"},{line,297}]},
                  {proc_lib,init_p_do_apply,3,
                      [{file,"proc_lib.erl"},{line,247}]}]}
4> c(my_alarm_handler).
{ok,my_alarm_handler}

但是这里报错了,为什么呢,我来会比对发现,我粗心这里把handle_event方法写成了handler_event,还有如果我们把这行代码添加上,就算下次写错了,idea也会提示我们存在没有实现的方法需要我们编写,这样一眼就能看出错误了

这里是正确的代码

%%%-------------------------------------------------------------------
%%% @author ZhengNan
%%% @copyright (C) 2024, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 13. 9月 2024 23:22
%%%-------------------------------------------------------------------
-module(my_alarm_handler).
-author("ZhengNan").
%%%=======================EXPORT=======================
-export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]).
-behaviour(gen_event).
%%%=======================INCLUDE======================
%%%=======================RECORD=======================
%%%=======================DEFINE=======================
%%%=======================TYPE=========================
%%%=================EXPORTED FUNCTIONS=================
%% ----------------------------------------------------
%% Description:
%% ----------------------------------------------------
init(Args) ->
	io:format("init my_alarm_handler by:~p~n ", [Args]),
	{ok, 0}.

handle_event({set_alarm, too_hot}, N) ->
	error_logger:error_msg("Tell the engineer to turn on the aircondition~n"),
	{ok, N + 1};
handle_event({clear_alarm, too_hot}, N) ->
	error_logger:error_msg("Danger over. Turn off the aircondition~n"),
	{ok, N};
handle_event(Event, N) ->
	io:format("unmatch event:~p~n", [Event]),
	{ok, N}.

handle_call(_Request, N) ->
	Reply = N, {ok, Reply, N}.
handle_info(_Info, N) ->
	{ok, N}.
terminate(_Reason, _N) ->
	ok.
code_change(_OlderVsn, State, _Extra) ->
	{ok, State}.
%%%===================LOCAL FUNCTIONS==================
%% ----------------------------------------------------
%% Description:
%% ----------------------------------------------------

PS C:\CodeProjects\ErlangProjects\erlang_learning\src\otp> erl -boot start_sasl -config .cfg/erlog
Eshell V9.3  (abort with ^G)
1> alarm_handler:set_alarm(too_hot).
ok

=INFO REPORT==== 18-Sep-2024::23:14:31 ===
    alarm_handler: {set,too_hot}
2> gen_event:swap_handler(alarm_handler,{alarm_handler,swap},{my_alarm_handler,zhengnan}).
init my_alarm_handler by:{zhengnan,{alarm_handler,[too_hot]}}
 ok
3> alarm_handler:set_alarm(too_hot).                                                       

=ERROR REPORT==== 18-Sep-2024::23:14:43 ===
Tell the engineer to turn on the aircondition
ok
4> alarm_handler:clear_alarm(too_hot). 

=ERROR REPORT==== 18-Sep-2024::23:20:42 ===
Danger over. Turn off the aircondition
ok
5>
  1. 读取日志

让我们回到错误记录器里去看看发生了什么。

6> rb:start([{max,20}]).                

=ERROR REPORT==== 18-Sep-2024::23:32:10 ===
Danger over. Turn off the aircondition
rb: reading report...done.
{ok,<0.73.0>}
7> rb:list().
  No                Type   Process       Date     Time
  ==                ====   =======       ====     ====
   8            progress  <0.57.0> 2024-09-18 23:31:56
   7            progress  <0.57.0> 2024-09-18 23:31:56
   6            progress  <0.57.0> 2024-09-18 23:31:56
   5            progress  <0.51.0> 2024-09-18 23:31:56
   4         info_report  <0.57.0> 2024-09-18 23:31:59
   3         info_report  <0.57.0> 2024-09-18 23:32:01
   2               error  <0.57.0> 2024-09-18 23:32:07
   1               error  <0.57.0> 2024-09-18 23:32:10
ok
8> rb:show(1).

ERROR REPORT  <0.61.0>                                      2024-09-18 23:32:10
===============================================================================

Danger over. Turn off the aircondition
ok
9> rb:show(2). 

ERROR REPORT  <0.61.0>                                      2024-09-18 23:32:07
===============================================================================

可以看到错误记录机制运行正常。
在实践中,我们会确保错误日志大到足够支持几天或几周的运作。每隔几天(或几周)就会检查错误日志并调查所有错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值