This section is to be read with the
In OTP, an event manager is a named object to which events can be sent. An event can be, for example, an error, an alarm, or some information that is to be logged.
In the event manager, zero, one, or many event handlers are installed. When the event manager is notified about an event, the event is processed by all the installed event handlers. For example, an event manager for handling errors can by default have a handler installed, which writes error messages to the terminal. If the error messages during a certain period is to be saved to a file as well, the user adds another event handler that does this. When logging to the file is no longer necessary, this event handler is deleted.
An event manager is implemented as a process and each event handler is implemented as a callback module.
The event manager essentially maintains a list of
The callback module for the event handler writing error messages to the terminal can look as follows:
-module(terminal_logger).
-behaviour(gen_event).
-export([init/1, handle_event/2, terminate/2]).
init(_Args) ->
{ok, []}.
handle_event(ErrorMsg, State) ->
io:format("***Error*** ~p~n", [ErrorMsg]),
{ok, State}.
terminate(_Args, _State) ->
ok.
The callback module for the event handler writing error messages to a file can look as follows:
-module(file_logger).
-behaviour(gen_event).
-export([init/1, handle_event/2, terminate/2]).
init(File) ->
{ok, Fd} = file:open(File, read),
{ok, Fd}.
handle_event(ErrorMsg, Fd) ->
io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
{ok, Fd}.
terminate(_Args, Fd) ->
file:close(Fd).
The code is explained in the next sections.
To start an event manager for handling errors, as described in the previous example, call the following function:
gen_event:start_link({local, error_man})
This function spawns and links to a new process, an event manager.
The argument,
If the name is omitted, the event manager is not registered.
Instead its pid must be used. The name can also be given
as
The following example shows how to start an event manager and add an event handler to it by using the shell:
1> gen_event:start({local, error_man}). {ok,<0.31.0>} 2> gen_event:add_handler(error_man, terminal_logger, []). ok
This function sends a message to the event manager registered as
init(_Args) ->
{ok, []}.
Here,
init(File) ->
{ok, Fd} = file:open(File, read),
{ok, Fd}.
3> gen_event:notify(error_man, no_reply). ***Error*** no_reply ok
The event is made into a message and sent to the event manager.
When the event is received, the event manager calls
In
handle_event(ErrorMsg, State) ->
io:format("***Error*** ~p~n", [ErrorMsg]),
{ok, State}.
In
handle_event(ErrorMsg, Fd) ->
io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
{ok, Fd}.
4> gen_event:delete_handler(error_man, terminal_logger, []). ok
This function sends a message to the event manager registered as
For
terminate(_Args, _State) ->
ok.
For
terminate(_Args, Fd) ->
file:close(Fd).
When an event manager is stopped, it gives each of
the installed event handlers the chance to clean up by calling
If the event manager is part of a supervision tree, no stop
function is needed. The event manager is automatically
terminated by its supervisor. Exactly how this is done is
defined by a
An event manager can also be stopped by calling:
> gen_event:stop(error_man). ok
If the
handle_info({'EXIT', Pid, Reason}, State) ->
..code to handle exits here..
{ok, NewState}.
The
code_change(OldVsn, State, Extra) ->
..code to convert state (and more) during code change
{ok, NewState}