9 Error Logging
The Erlang system has a process with the registered name
error_logger
. This process receives all error messages from the Erlang runtime system and error messages sent by the error reporting functions in the moduleerror_logger
.This section describes the following topics:
- error types
- error message handling
- the standard error logger
- customized error report handlers.
9.1 Types of Errors
Errors are divided into the following three categories:
- predicted, recoverable errors
- predicted, unrecoverable errors
- unpredicted errors.
The system designer has to decide if a process can recover from predicted errors.
The last two categories of errors cause an abnormal termination of the process.
9.2 Error Message Handling
Errors can be reported by propagating an EXIT signal, by producing an error report, or both of these methods. The following table summarizes how the three categories of errors can be reported.
Category EXIT reason Error report Predicted and recoverable - yes Predicted and unrecoverable yes yes Not predicted yes - Error Message Reporting Recoverable errors are not reported by EXIT signals because the process does not terminate. Unpredicted errors are only reported by EXIT signals because the program does not take care of these errors.
The recovery from predicted errors is interpreted as an internal process error recovery. A process restart, issued by the layer above in the supervision tree, can also be used to recover from errors.
An unrecoverable, but predicted error can provide meaningful error descriptions, not only in an error report but also through an informative EXIT reason. It is recommended that the EXIT reason is composed as
{Reason,{Mod,Fun,Args}}
where:
Reason
is an informative error descriptor, for example an atom or{atom, Value}
.{Mod,Fun,Args}
is theMod
:Fun
(Args
) function where the error is detected.9.3 The Standard Error Logger
The
error_logger
process receives and handles the following types of errors:
- all errors generated by the Erlang runtime system (the
emulator
)- errors reported through the
error_logger
module interface functionserror_msg/1
,error_msg/2
,info_msg/1
,info_msg/2
,format/2
,error_report/1
, andinfo_report/1
.When the
error_logger
process receives an error, it is sent to the theerror_logger
on the node which is the group leader process for the process which caused the error.During system start-up, errors are kept in a buffer and they are also written unformatted to
standard out
, because error message handling is determined by the start-up process. The standarderror_logger
provides two possibilities:
- write to
standard_out
- write to a specified file.
All buffered errors are written again when the intended handler is installed. Initially errors are written in the format
{error_logger,Time,Arg1,Arg2}
, where:
Time
is a tuple which contains date and time informationArg1
andArg2
are the arguments given to a report function.When a standard handler is installed, errors are written in the following format:
=ERROR REPORT=== Time ==== Formatted error
Formatted error
error messages, which are reported through theformat
orerror_msg
functions calls, are produced fromFormat
andArgs
in the same way as in the functionio:format/2
. If the error was reported through the suppliederror_report(Report)
function, theReport
argument is interpreted and written as follows:
[{Tag,Info}]
, whereTag
andInfo
is any term. Each{Tag,Info}
tuple is written on a separate line:Tag: InfoOther
is written asio_lib:format("~p~n",[Other])
.It is also possible to use the
info_report(Report)
function to formatReport
aserror_report/1
in the above example, but with the heading:=INFO REPORT=== Time ====9.4 Adding A Customized Report Handler
It is possible to add customized error report handlers to the
error_logger
process. This may be desirable in order to satisfy one of the following purposes:
- to perform additional processing of standard error messages
- to override the standard behaviour (the standard handlers must be deleted)
- to handle new types of error messages.
The following two functions are used to add and delete handlers:
add_report_handler
to add a handlerdelete_report_handler
to delete a handler.
It is strongly recommended that the standard error reporting functions be used. Customized handlers should only be added if they are really needed.
The
error_logger
is implemented with thegen_event
behaviour. This means that an event callback module has to be implemented in order to add an associated error logger handler .All handlers installed within the
error_logger
are notified about errors that are received by theerror_logger
. This notification is done by callinghandle_event/2
in each callback module. This means that several actions can be performed when specific events occur. For example, the standarderror_logger
behaviour can be accompanied by an SNMP trap which is triggered when a pre-determined level of error messages have been received.New types of error message can be reported with the
error_report/2
andinfo_report/2
functions. Errors which are reported this way are ignored by the standard error logger handlers and would be lost unless an associated handler has been installed.The event generated by calling
error_logger:error_report(Type, Report)
, and which has to be handled by the added error report handler, is the term:
{error_report, Gleader, {Type, Pid, Report}}
where:
Gleader
is the group leader process of the process which executes the function call.Type
is a term which identifies the type of the error report.Pid
is the process identity of the process that issued the error report. ThePid
can be used to determine at which node the report was generated.Report
is a term which describes the error. This term must be recognized by the customized error report handler.Substitute
info_report
in place oferror_report
when calling theerror_logger:info_report(Type, Report)
function.
No standard error_logger messages are described here.
The following example illustrates how an error report handler for
my_error
type of error messages can be implemented:-module(my_error_logger_h). -copyright('Copyright (c) 1991-97 Ericsson Telecom AB'). -vsn('$Revision: /main/release/2 $'). -behaviour(gen_event). -export([start/0, stop/0, init/1, handle_event/2, handle_info/2, handle_call/2, terminate/2, report/1]). start() -> error_logger:add_report_handler(my_error_logger_h). stop() -> error_logger:delete_report_handler(my_error_logger_h). report(My_error) -> error_logger:error_report(my_error, My_error). init(_) -> {ok, []}. handle_event({error_report, Gleader, {my_error, Pid, My_error}}, State) -> handle_my_error(Gleader, Pid, My_error), {ok, State}; handle_event(_, State) -> % Ignore all other error messages. {ok, State}. handle_info(_, State) -> {ok, State}. handle_call(_, State) -> {error, bad_query}. terminate(_, _) -> ok. handle_my_error(Gleader, Pid, My_error) when node(Gleader) == node() -> %% do handle the error ok; handle_my_error(_, _, _) -> % Ignore error if Gleader at another node. ok.The purpose of the
error_logger
is to log or write errors. If some other type of event handler is needed it must be implemented as a customized process with another registered name. Refer to the section Events for further information.