3 EVA adaptations
As the basic EVA support is protocol independent, adaptations are needed for the actual management protocols. Such an adaptation is the manager's interface towards EVA. It may implement strategies for filtering events and alarms to different operators, or it may store more information associated with each event or alarm locally.
An EVA adaptation should be written as a
gen_event
handler module. It should be installed into thealarm_handler
process.An adaptation is free to use the Mnesia tables defined in EVA. The
eventTable
andalarmTable
must be accessed within a Mnesia transaction, while the active alarm list (alarm
) may be accessed dirty. Some functions in the moduleeva
could be useful as well.When an event or alarm is registered or sent, an
gen_event
event is generated asgen_event:notify(alarm_handler, ...)
by EVA, and should be taken care of in thehandle_event
function of the adaptation.3.1 Example
Without going too deep into the details, the following is an example of a very simple adaptation, that prints all events and alarms to standard out, and provides a function to print the active alarm list.
-module(simple_adaptation). -behaviour(gen_event). -include_lib("eva/include/eva.hrl"). -include_lib("mnemosyne/include/mnemosyne.hrl"). %%%----------------------------------------------------------------- %%% Simple EVA adaptation that formats events and alarms to standard %%% out. %%%----------------------------------------------------------------- %% External exports -export([start/0, print_alarms/0]). %% Internal exports -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2]). %%%----------------------------------------------------------------- %%% API %%%----------------------------------------------------------------- start() -> gen_event:add_handler(alarm_handler, ?MODULE, []). print_alarms() -> gen_event:call(alarm_handler, ?MODULE, print_alarms). %%%----------------------------------------------------------------- %%% Call-back functions from gen_event %%%----------------------------------------------------------------- init(_) -> io:format("Initializing simple EVA adaptation...~n"), {ok, []}. handle_event({send_event, #event{name = Name}}, S) -> X = Name, % due to bug in mnemosyne... Handle = query [E.generated || E <- table(eventTable), E.name = Name] end, {atomic, [Generated]} = mnesia:transaction(fun() -> mnemosyne:eval(Handle) end), io:format("** Event: ~w, ~w generated~n", [Name, Generated]), {ok, S}; handle_event({send_alarm, #alarm{name = Name, severity = Severity}}, S) -> X = Name, % due to bug in mnemosyne... Handle = query [E.generated || E <- table(eventTable), E.name = Name] end, {atomic, [Generated]} = mnesia:transaction(fun() -> mnemosyne:eval(Handle) end), Handle2 = query [A.class || A <- table(alarmTable), A.name = Name] end, {atomic, [Class]} = mnesia:transaction(fun() -> mnemosyne:eval(Handle2) end), io:format("** ~w alarm ~w of class ~w, ~w generated~n", [Severity, Name, Class, Generated]), {ok, S}; handle_event(_, S) -> {ok, S}. handle_call(print_alarms, S) -> Handle = query [{A.name, A.sender, A.cause, A.severity, AlarmDef.class} || A <- table(alarm), AlarmDef <- table(alarmTable), A.name = AlarmDef.name] end, {atomic, Alarms} = mnesia:transaction(fun() -> mnemosyne:eval(Handle) end), io:format("** Active alarm list~n"), lists:foreach( fun({Name, Sender, Cause, Severity, Class}) -> io:format("~14w ~10w alarm ~p from ~p, probable cause: ~p~n", [Severity, Class, Name, Sender, Cause]) end, Alarms), {ok, ok, S}. handle_info(_, S) -> {ok, S}. terminate(R, S) -> io:format("Terminating simple EVA adaptation...~n"), ok.