This module contains client functions to the generic Log Control services in the EVA application. There are two services available; log monitoring and log transfer. The logs are controlled by a log server, and each log may be transfered with FTP to a remote host.
The log server has a list of all active logs in the system.
An application that wants to make a log controllable with this
functionality, must register the log in the log server.
Each log is implemented as a disk_log
log. The
application stores its log records using the ordinary functions
in disk_log
. The following picture illustrates the idea:
+------+ tell +-------+ | Appl | --------> | log | +------+ | server| | _ +-------+ |open, / |log*, /control |close / | +---------+ +--->| disk_log| +---------+
First, the application opens the log. Thenit registers the log in the log server, which makes the log server control the log. The application can store log records in the log, until it eventually closes the log, and tells the log server about it.
Each log has an administrative and an operational status, that
both can be either up
or down
. The administrative
status is configurable, and reflects the desired operational
status. Normally they are both the same. If the administrative
status is set to up
, the operational status will be
up
as well. However, if the log for some reason does
not work, for example if the disk partition is full, the operational
status will be down
. When the operational status is
down, no records are stored in the log.
Two EVA alarms are defined in the log
service,
log_file_error
and log_wrap_too_often
.
log_file_error
. This alarm is generated if
there is a file error when an item should be logged.
Default severity is critical
. The cause for this
alarm can be any Reason
as returned from
file:write
in case of error (it returns {error,
Reason}
). The alarm is cleared if the file system
starts working again.
log_wrap_too_often
. This alarm is generated
when the log wraps more often than the wrap time. Default
severity is major
. The cause for this alarm is
undefined. The alarm is cleared if the log wraps within the
wrap time, the next time it wraps.
Name = string()
Use this function to remove a log from the log server.
Log = #log
Returns all logs known to log_server
. The record
#log
is defined in the file log.hrl
.
Name = string()
Type = term()
WrapTime = integer()
Makes log_server
aware of the log Name
. The log
must be an open disk_log
log.
The type argument is there for information to a manager.
If the log is a wrap log, log_server
generates the
log_wrap_too_often
alarm if the log wraps more often
than WrapTime
seconds. In this context, wraps means
that disk_log
switches to a previously used file, and
some log items are lost.
set_admin_status(Name, AdminStatus) -> OperStatus |
{error, Reason}
Name = string()
AdminStatus = OperStatus = up | down
Reason = {error, {no_such_log, Name}}
Sets the desired state of the log. Returns the new
operational status of the log. If the administrative status
is set to up
, and the operational status is
down
, there is some error with the logging
mechanism, for example if the disk partition is full.
If the operational status of the log is down
, no log
records will be stored in the log. This function uses the
functions disk_log:block/unblock
to change the
operational status.
transfer(Host,User,Passwd,DestFile,SearchFunc) -> ok |
{error, Reason}
Host = ip_address()
User = string()
Passwd = string()
DestFile = string()
SearchFunc = {M,F,A}
Reason = ftp_bad_address | ftp_login_error |
ftp_write_error | ftp_tranfer_error | {bad_search_result, term()}
ip_address() = string() | {int(), int(), int(), int()}
M = F = atom()
A = list()
M:F(Continuation | A) -> SearchResult
SearchResult = eof | {NewContinuation, Bytes} | {error,
R}
Continuation = start | cont()
NewContinuation = cont()
Bytes = binary()
R = term()
This function is used to transfer a log with FTP to a
remote host, for example a mangement station. It could be
triggered from for example SNMP or from a web interface to the
system. This log is received as one contiguous file,
although it is stored as several files in the underlying
disk_log
log. It is possible to filter the log for
certain log records, and to format the log records. Thus,
log records can be efficiently stored by not formatting them
when they are written, but later when the log is actually
needed. Of course, to further improve performance, the log
records can be transferred unformatted as well, and later
formatted off-line at the management station.
The Host
argument is either a string or a four-tuple
representing the IP address of the host. The string can be
the name of the host, or the IP address in dotted decimal
notation, for example "150.236.14.136".
The SearchFunc
argument specifies a function that
will be called by the transfer session to get a chunk of log
records to transfer. At the first call, the atom
start
is used as an initial continuation. Each time
the function is called, it is supposed to return a new
continuation and a binary that contains the bytes to be
transferred (the formatted log records). When the end of
the log is reached, eof
is returned by the function.
The return values of the SearchFunc
is chosen to
match those of disk_log:chunk/2
. The extra arguments
(A
) to the functions can be used to pass filtering
information to the search function. An example of a search
function:
-module(my_log). f(Cont, Time) -> case disk_log:chunk("my_log", Cont) of eof -> eof; {error, R} -> {error, R}; {NCont, ListOfTerms} -> List = lists:map(fun(Term) -> format(Term, Time) end, ListOfTerms), Bin = list_to_binary(List), {NCont, Bin} end. %% Each log record is a tuple: {LogTime, LogData} format({LogTime, LogData}, Time) when LogTime > Time -> io_lib:format("time: ~p data: ~p~n", [LogTime, LogData]); format(_LogRecord, _Time) -> [].
This function can be used as follows to transfer all log records stored after 1997-11-01:
log:transfer("cave.ericsson.se", "mbj", "secret!", "my_log.txt", {my_log, f, [{1997,11,01}]}
disk_log(3), eva(3), file(3)