This chapter describes an EVA adaptation for SNMP and an SNMP interface towards the Log Control service. Also included are an SNMP interface towards the logging of event, and an SNMP interface towards the snmp audit trail log.
An application that uses the logs or event generating function does not have to know that the events or alarms are sent as SNMP traps, it just uses the EVA API.
There are four MIBs defined, OTP-EVA-MIB
,
OTP-LOG-MIB
, OTP-EVA-LOG-MIB
and
OTP-SNMPEA-LOG-MIB
. These MIBs can be found in the
mibs
directory in the EVA distribution. They are described
in the following sections.
The EVA SNMP adaptation consists of functionality for translating the EVA events and alarms to SNMP traps, an SNMP MIB for the EVA tables, such as the active alarm list, and an API to be used for the SNMP instrumentation functions.
This MIB implements managed objects for the basic EVA service in OTP. It consists of the Event, Alarm and CurrentAlarms groups.
The Event group consists of the eventTable
.
The eventTable
has one entry for each event the
system may generate. It defines all events in the
system and controls how an event should be treated,
and to whom it should be sent. Note that an alarm is a
special kind of event, so all alarms are defined in this
table as well.
The table has the following attributes:
eventIndex
eventTrapName
eventTreatment
eventCommunity
eventSentTraps
eventOwner
Each event has a unique index, eventIndex
, which
remains constant as long as the system is up and running.
If some events are deleted (e.g. due to a new software
release), the row will disappear.
The eventTrapName
attribute defines which SNMP trap
is associated with an event. This is for the manager to
correlate incoming traps with the events.
The eventTreatment
defines if the event should be
sent as a trap or not, and if the event should be logged or
not. The possible values are none
, log
,
snmpTrap
, logAndTrap
. This attribute is
writable. This makes it possible for the manager to select
which events should be reported as traps at a specific time,
and to effectively make sure that an event will not be
logged in any log. How the events are logged and how to
control the logs is not defined in this MIB. One log
mechanism is defined in the OTP-EVA-LOG-MIB, but others
could be defined instead.
The eventCommunity
defines to which managers the
trap should be sent, if at all. This attribute is writable.
The eventSentTraps
counts the number of times the
event has been sent as an SNMP trap. A manager may poll
this value to see if he has lost an event.
Finally, the eventOwner
is the manager entity that
'owns' the event, and is therefore responsible for its
configuration. This attribute is writable.
The Alarm group consists of the alarmTable
.
alarmTable
is an extension to the eventTable
.
It has one entry for each defined alarm in the system.
The table is indexed by eventIndex
and has the
following attributes:
alarmClass
alarmSeverity
The alarmClass
and alarmSeverity
have the
values defined by EVA. alarmSeverity
is writable.
The CurrentAlarm group consists of two scalar variables,
numberOfCurrentAlarms
, and
currentAlarmLastTimeChanged
, the table
currentAlarmTable
and the event (defined as a trap)
alarmCleared
.
The numberOfCurrentAlarms
is the number of active
alarms in the currentAlarmTable
.
The currentAlarmLastTimeChanged
is a time stamp when
the currentAlarmTable
was changed. The time the
table is changed is sent in each trap. A manager may store
this value internally, and poll the currentAlarmTable
variable regularly. If the internally stored value differs
from the value of this variable, some alarm was lost (or not
sent to the manager). In this case, the manager may
download the entire table.
The currentAlarmTable
is a list of all currently
active alarms in the system. All objects in the table except for
alarmSeverity
, are read-only.
The table has the following attributes:
currentAlarmFaultId
currentAlarmEventIndex
currentAlarmObject
currentAlarmCause
currentAlarmSeverity
currentAlarmTime
currentAlarmInformation
currentAlarmExtra1
currentAlarmExtra2
Each active alarm has a unique index,
currentAlarmFaultId
, which remains constant as long
as the system is up and running. When an alarm is cleared,
the fault id may be reused by another alarm, but only if the
new alarm originates from the same fault. If the system
reboots, the currentAlarmTable
is reset, and all
alarms that are still active are sent as new alarms.
currentAlarmEventIndex
is a pointer into the
eventTable
. It connects the alarm to a certain trap.
currentAlarmObject
defines which object generated
the alarm. It should point to an instance of an accessible
object in the MIB. For example, if the alarm was generated
by interface no 3 in ifTable
, the object should be
{ifIndex 3}
.
currentAlarmCause
describes the cause of the alarm,
if known. This is an OBJECT IDENTIFIER, which means that
the possible causes must be defined in the MIB. If unknown,
this object is {0 0}
.
currentAlarmSeverity
is the perceived severity of
the alarm. The only value that can be written into this
object is clear
. When set to clear
, the
alarm is cleared and removed from the active alarm list.
A clear_alarm
event is generated by EVA. A
management application should use this with care. Normally
the application that generated an alarm is responsible for
clearing the alarm.
currentAlarmTime
is the time the alarm was
generated. This value is written into
currentAlarmLastTimeChanged
when the alarm is sent.
currentAlarmInformation
is a string with extra
information pin-pointing the problem. Use this string with
care, as too complicated strings makes it hard for a
management application to make automated decisions. The
only option may be to display the string to the operator as
is.
currentAlarmExtra1
and currentAlarmExtra2
are
extra parameters used by alarms at their own discretion.
Can be used for example to identify additional objects in
the alarm, or instead of currentAlarmInformation
to
pin-point the problem, if the additional information is
defined in some MIB.
When an alarm is cleared, either by the application itself,
or by an operator, the event alarmCleared
is sent.
In this event, one single variable is sent,
currentAlarmEventIndex
. Note that the
currentAlarmFaultId
is implicit in the instance
OBJECT IDENTIFIER for this variable.
The applications generate events and alarms using the API provided by EVA. They are not aware that the events and alarms are sent as SNMP traps to SNMP managers.
However, each trap that should be sent must be defined in an SNMP MIB, and there must be instrumentation functions that translates the EVA events and alarms into SNMP traps. Normally, each event and alarm in the system is mapped to separate SNMP traps. This mapping is done when the events are registered. The following functions are available for the registration. They could be called e.g. when the corresponding MIB is loaded. They are described in detail in the Reference Manual, eva, the module eva_snmp_adaptation.
register_events([{Name, Trap, EFunc, Treatment,
Community}]
#event
into a trap. It also
defines the default treatment and community.
register_alarms([{Name, Trap, AFunc, Treatment,
Community}]
#alarm
into a trap. It also
defines the default treatment and community.
In these functions, the instrumentation functions should be defined as:
EFunc = fun(#event) -> {ok, SnmpVarbinds} AFunc = fun(#alarm) -> {ok, ObjOID, CauseOID, SnmpVarbinds}
respectively, where SnmpVarbinds
is a list of any extra
SNMP variables included in the trap.
When using this SNMP EVA adaptation, each event and alarm must be defined as an SNMP trap in a MIB. Any SNMP trap may be used as an event since there are no restrictions on these traps. However, for each alarm, there are some objects that must be present in the trap definition. These objects must be the first objects in the trap, and they must be defined in the following order:
currentAlarmTime
currentAlarmSeverity
currentAlarmObject
Note that implicit in each of these objects is the
currentAlarmFaultId
, since this is the index for the
table.
These are the objects that are most important for the manager. Any other object may be retrieved by sending a GET request to the agent.
An example of a correct trap definition using SNMP v1 syntax:
boardFailure TRAP-TYPE ENTERPRISE board VARIABLES { currentAlarmTime, currentAlarmSeverity, currentAlarmObject, boardName } DESCRIPTION "An alarm sent when a board failure is detected." ::= 3
And the same trap using SNMP v2 syntax:
boardFailure NOTIFICATION-TYPE OBJECTS { currentAlarmTime, currentAlarmSeverity, currentAlarmObject } STATUS current DESCRIPTION "An alarm sent when a board failure is detected." ::= { board 0 3 }
The values of these mandatory objects are set by EVA.
Note that after the three mandatory objects, any other objects may be specified.
This section shows an example of how EVA may be used by an
application. The complete code is available in the
example
directory in the distribution.
The example application is an application that controls boards and generates an event when a board is removed or inserted, and an alarm if a board failure is detected.
The following code is the SNMP independent resource code:
%%%----------------------------------------------------------------- %%% Resource code %%%----------------------------------------------------------------- reg() -> eva:register_event(boardRemoved, true), eva:register_event(boardInserted, false), eva:register_alarm(boardFailure, true, equipment, minor). remove_board(No) -> eva:send_event(boardRemoved, {board, No}, []). insert_board(No, BoardName, BoardType) -> eva:send_event(boardInserted, {board, No}, {BoardName, BoardType}). board_on_fire(No) -> FaultId = eva:get_fault_id(), %% Cause = fire, ExtraParams = [] eva:send_alarm(boardFailure, FaultId, {board, No}, fire, []), FaultId.
The function reg/0
is used to register the events and
the alarm in EVA. The boardRemoved
event just
identifies the removed board, but the boardInserted
identifies the board and sends the name and type of the board
as extra parameters in the event.
When this is mapped to SNMP, the following MIB is designed:
BOARD-MIB DEFINITIONS ::= BEGIN IMPORTS DisplayString FROM RFC1213-MIB OBJECT-TYPE FROM RFC-1212 experimental FROM RFC1155-SMI currentAlarmTime, currentAlarmSeverity, currentAlarmObject FROM OTP-EVA-MIB; board OBJECT IDENTIFIER ::= {experimental 1} boardTable OBJECT-TYPE SYNTAX SEQUENCE OF BoardEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "Contains information about the boards in the system." ::= { board 1 } boardEntry OBJECT-TYPE SYNTAX BoardEntry ACCESS not-accessible STATUS mandatory DESCRIPTION "A set of parameters for boards." INDEX { boardIndex } ::= { boardTable 1 } BoardEntry ::= SEQUENCE { boardIndex INTEGER, boardName DisplayString, boardType DisplayString } boardIndex OBJECT-TYPE SYNTAX INTEGER ACCESS not-accessible STATUS mandatory DESCRIPTION "A unique index identifying each board." ::= { boardEntry 1 } boardName OBJECT-TYPE SYNTAX DisplayString ACCESS read-only STATUS mandatory DESCRIPTION "The name of the board." ::= { boardEntry 2 } boardType OBJECT-TYPE SYNTAX DisplayString ACCESS read-only STATUS mandatory DESCRIPTION "The type of the board." ::= { boardEntry 3 } -- Events boardRemoved TRAP-TYPE ENTERPRISE board VARIABLES { boardName } DESCRIPTION "An event sent when a board is removed." ::= 1 boardInserted TRAP-TYPE ENTERPRISE board VARIABLES { boardName, boardType } DESCRIPTION "An event sent when a board is inserted." ::= 2 -- Alarms boardFailure TRAP-TYPE ENTERPRISE board VARIABLES { currentAlarmTime, currentAlarmSeverity, currentAlarmObject, boardName } DESCRIPTION "An alarm sent when a board failure is detected." ::= 3 -- Causes fire OBJECT IDENTIFIER ::= {board 2} -- DESCRIPTION -- "The board is on fire." END
To implement this MIB, instrumentation functions for the managed objects are needed for the SNMP agent. Also, we must write instrumentation functions for the traps for EVA.
%%%----------------------------------------------------------------- %%% SNMP adaptation code %%%----------------------------------------------------------------- mgm_init() -> snmp:load_mibs(snmp_master_agent, ["BOARD-MIB"]), Events = [{boardRemoved, boardRemoved, snmpTrap, "standard trap", {?MODULE, boardRemoved}}, {boardInserted, boardInserted, snmpTrap, "standard trap", {?MODULE, boardInserted}}], Alarms = [{boardFailure, boardFailure, snmpTrap, "standard trap", {?MODULE, boardFailure}}], eva_snmp_adaptation:register_events(Events), eva_snmp_adaptation:register_alarms(Alarms). %%----------------------------------------------------------------- %% instrumentation functions %%----------------------------------------------------------------- % Using default instrumentation %%----------------------------------------------------------------- %% "backwards" instrumentation functions event -> trap %%----------------------------------------------------------------- boardRemoved(#event{sender = {board, Idx}}) -> [#boardTable{name = Name}] = mnesia:dirty_read({boardTable, Idx}), {ok, [{boardName, [Idx], Name}]}. boardInserted(#event{sender = {board, Idx}, extra = {Name, Type}}) -> {ok, [{boardName, [Idx], Name}, {boardType, [Idx], Type}]}. boardFailure(#alarm{sender = {board, Idx}, cause = Cause}) -> [#boardTable{name = Name}] = mnesia:dirty_read({boardTable, Idx}), {value, Oid} = snmp:name_to_oid(boardName), {value, COid} = snmp_cause(Cause), {ok, {Oid ++ [Idx], COid, [{boardName, [Idx], Name}]}}. snmp_cause(fire) -> snmp:name_to_oid(fire); snmp_cause(_) -> [0,0].
The LOG SNMP interface consists of functionality for controlling the logs in the system using SNMP, and an SNMP MIB which also includes functions for tranferring logs to a remote host with FTP.
This MIB implements managed objects for the Log Control service. It consists of the logGroup, logTransferGroup, and the logAlarmsGroup.
The Log group consists of the table logTable
.
The logTable
has one entry for each log in the
system.
Applications can choose to extend this table, for logs of
certain types. This can be used e.g. to specify additional
parameters for what should be logged in a log. The
evaLogDiscriminatorTable
is such an example.
The logTable
has the following attributes:
logIndex
logName
logType
logAdminStatus
logOperStatus
logMaxSize
logNumberOfRecords
logMinWrapTime
logWrapPercentage
logOwner
logRowStatus
Each log is identified by a unique index, logIndex
.
logName
is a string that gives a human readable name
for the log. This attribute is writable at creation time.
The name must be unique.
logType
is an OBJECT IDENTIFIER that specifies what
type of log it is. This attribute is writable at creation
time. If it is an unknown log type, this entry has the
value 0.0
.
logAdminStatus
can be up
or down
.
Specifies the desired logOperStatus
. This attribute
is writable.
logOperStatus
can be up
or down
.
Specifies whether the log is active or not. A log that is
down
discards all log records sent to it.
logMaxSize
defines the maximum size the log may
occupy. When the max size is reached,
logWrapPercentage
of the log space is freed to make
room for more records. This attribute is writable at
creation time. If logTotalMaxSize + logMaxSize >
logTotalMaxAllowedSize
, the creation fails.
logNumberOfRecords
counts the number of records in
the log.
logMinWrapTime
defines the minimum time between two
wrap situations. If the log wraps more often, an
logWrapAlarm
is sent. This attribute is writable at
creation time.
logWrapPercentage
defines how many percent of the
log space is freed when the log reaches its maximum size.
This attribute is writable at creation time.
logOwner
is the manager entity that 'owns' the log,
and is therefore responsible for its contents, including
entries in the logDiscriminatorTable
. Logs created
by the agent system have this object equal to
"local"
, and should not be deleted or otherwise
modified by a manager. This attribute is writable at
creation.
logRowStatus
is used to create and delete logs.
Two alarms are defined, the logWrapAlarm
which is
sent if a log wraps too often and
logMediaErrorAlarm
which is sent if the logging
function detects an error in the storage media for a
log, and cannot log anything more.
There are two probable causes defined for the
logMediaErrorAlarm
. These are logNoSpaceLeft
which is used when there is no space left on the media, and
logMediaBroken
which is used when the storage media
is broken.
The Log Transfer group consists of the table
logTransferTable
.
The logTransferTable
has one entry for each transfer
in the system. When a transfer entry has been created (with
createAndWait
), its
status is notInService
. When it is made
active
, the log transfer begins. When the transfer
is complete, the status is notInService
again. The
outcome of the transfer session is available in the variable
logTransferLastResult
.
Applications can choose to extend this table, for logs of
certain types. This can be used e.g. to specify additional
log specific filtering parameters. The
snmpeaLogTransferTable
is such an example.
The logTransferTable
has the following attributes:
logTransferIndex
logTransferStartTime
logTransferStopTime
logTransferFTPAddress
logTransferFTPUser
logTransferFTPPasswd
logTransferFTPFile
logTransferLastResult
logTransferRowStatus
A log transfer entry refers to a particular log in the
logTable
. There may exist several log transfer
entries for each log. Thus, the logTransferTable
is
indexed by logIndex
and a logTransferIndex
.
logTransferStartTime
is a DateAndTime
variable that specifies that log records generated after
this time should be transferred. This attribute is writable.
logTransferStopTime
is a DateAndTime
variable that specifies that log records generated before
this time should be transferred. This attribute is writable.
logTransferFTPAddress
is the IP address of the
remote host to which the log should be transferred.
This attribute is writable.
logTransferFTPUser
is the user in the FTP session.
This attribute is writable.
logTransferFTPPasswd
is the password for the user in
the FTP session. This attribute is writable. If it is
read, the empty string is returned.
logTransferFTPFile
is a string with the absolute
file name for the log at the remote host. This attribute is
writable.
logTransferLastResult
is an enumerated integer that
contains the result of the last transfer. This attribute is
read-only. The following values are valid:
logTransferRowStatus
controls the creation/deletion
of transfer entries, and controls the transfer of logs. If
set to active
, the transfer begins. If an active
transfer's status is set to notInService
, the
transfer aborts. This attribute is writable.
The system may choose to create local logs, i.e. logs that
cannot be modified by a manager. For example, an alarm log
can be created that always logs all alarms. To create a
local log, the functions in log
should be used.
All logs that log
knows of will be visible in the
logTable
.
This section describes how a manager may use the OTP-LOG-MIB to perform logging.
When a management application wants to create a log, it should perform the following steps.
logIndex
by looping through the
logTable
.
logRowStatus = createAndGo
to the
agent.
logIndex
was occupied, choose a new logIndex
.
When a management application wants to delete a log, it should perform the following steps.
logRowStatus
to destroy
for
the corresponding logIndex
.
Sometimes it can be useful to block a specific log so that no records are stored in the log, but not delete it. To accomplish this a manager should:
logAdminStatus
to down
for
the corresponding logIndex
.
When a log should be transferred to a remote host, the following steps should be followed.
First, create the log transfer entry:
logIndex
of the log that should
be transferred.
logTransferIndex
by looping
through all transfer entries with the same log index as
the selected log.
logTransferStartTime
and
logTransferStopTime
.
logTransferRowStatus = createAndWait
to the
agent.
When the log transfer entry is created, the log will be transferred each time the row is activated:
logTransferRowStatus =
active
to the agent.
logTransferRowStatus
until
it becomes notInService
.
logTransferLastResult
if
the transfer succeeded or not.
If a log transfer takes too long time, the transfer may be aborted in the following way:
logTransferRowStatus =
notInService
to the agent.
logTransferRowStatus
until
it becomes notInService
. The
logTransferLastResult
is now aborted
.
The applications create logs using the API provided by the Log Control service. However, if an application has defined additional managed objects in a MIB, the SNMP adaptation of the generic log service must know of this, in order to use this information when logs are created or trasnferred.
There is just one function needed, and it is
log_snmp:register_type/3
. It registers the type of log
in the SNMP log adaptation. The function is described in
detail in the reference manual.
The EVA-LOG SNMP interface consists of functionality for controlling the logging of events and alarms using SNMP, and an SNMP MIB. This functionality uses the generic log control service described above.
This MIB implements managed objects for the EVA LOG service. It consists of the Eva Log group.
The Eva Log group consists of the table
evaLogDiscriminatorTable
, and the variables
evaLogTotalMaxSize
and
evaLogTotalMaxAllowedSize
.
The evaLogDiscriminatorTable
has the following
attributes:
evaLogDiscrEventIndex
evaLogDiscrRowStatus
Each entry in this table is indexed by logIndex
and
evaLogDiscrEventIndex
. Each row means that the event
with eventIndex
equal to evaLogDiscrEventIndex
should be logged in the log with logIndex
. The
evaLogDiscrRowStatus
is used to create and delete
rows in the table.
The variable evaLogTotalMaxSize
is the sum of specified
maximum sizes of all logs. This object is read-only.
The variable evaLogTotalMaxAllowedSize
is the total
size all event logs created by the manager are allowed to
fill. This object corresponds to the amount of disk space
available for the log function in the agent system. This
object is read-only.
This section describes how a manager may use the OTP-EVA-LOG-MIB to perform event and alarm logging.
When a management application wants to create an event log, it should perform the following steps.
logTable
as described
above, using the logType
evaLogType
.
evaLogDiscriminatorTable
, using the same
logIndex
as defined in step 1
When a management application wants to delete an event log, it should follow the steps defined above in the section about general log deletion.
Sometimes it can be useful to block a specific log so that no events are stored in the log, but not delete it. To accomplish this a manager should:
logAdminStatus
to down
for
the corresponding logIndex
.
In other situations it can be useful to make a certain event not be stored in any log at all, for example if the event is generated very often. This can be accomplished by:
eventTreatment
to snmpTrap
or
none
for the event in eventTable
. As long
as the eventTreatment
is not log
or
logAndTrap
, the event is not stored in any log.
The SNMPEA LOG SNMP interface consists of functionality for controlling the audit trail logging mechanisms in the Extensible Snmp Agent in the system. This functionality uses the generic log control service described above.
This MIB implements managed objects for the SNMEPA LOG service. It consists of the Snmpea Log group and Snmpea Log Transfer group.
The Snmpea Log group consists of the single variable
snmpeaLogDiscriminator
. This variable controls which
snmpeaLogTransferTable
that extends the
logTransferTable
. It consists of a single column,
snmpeaLogTransferIPAdress
, which is used as a log
specific filtering parameter. If this variable is set for a
transfer entry when the log is trasnferred, requests to or
from this address only are transferred.