[Erlang Systems]

4 EVA SNMP interface

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.

4.1 EVA SNMP adaptation

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.

4.1.1 OTP-EVA-MIB

This MIB implements managed objects for the basic EVA service in OTP. It consists of the Event, Alarm and CurrentAlarms groups.

4.1.1.1 Event group

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:

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.

4.1.1.2 Alarm group

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:

The alarmClass and alarmSeverity have the values defined by EVA. alarmSeverity is writable.

4.1.1.3 CurrentAlarm group

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:

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.

4.1.2 API

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}]
This function is used to associate each event with the corresponding trap and an Erlang instrumentation function that translates the #event into a trap. It also defines the default treatment and community.
register_alarms([{Name, Trap, AFunc, Treatment, Community}]
This function is used to associate each alarm with the corresponding trap and an Erlang instrumentation function that translates the #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.

4.1.3 MIB definition rules

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:

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.

4.1.4 Example

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].

4.2 LOG SNMP interface

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.

4.2.1 OTP-LOG-MIB

This MIB implements managed objects for the Log Control service. It consists of the logGroup, logTransferGroup, and the logAlarmsGroup.

4.2.1.1 Log group

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:

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.

4.2.1.2 Log Alarms group

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.

4.2.1.3 Log Transfer group

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:

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:

ok
the transfer succeded
aborted
the transfer was aborted by the management station
ftpBadAddress
the FTP address could not be contacted
ftpLoginError
the combination of FTP user and passwd was invalid
ftpWriteError
the user had no write access to the file
ftpTransferError
the FTP session aborted
otherError
any other error, e.g. internal error in log

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.

4.2.2 Creation of local logs

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.

4.2.3 Manager use cases

This section describes how a manager may use the OTP-LOG-MIB to perform logging.

4.2.3.1 Log creation

When a management application wants to create a log, it should perform the following steps.

  1. Decide which type of log is wanted. This is defined in MIBs for applications that uses the generic log control service.
  2. Find a free logIndex by looping through the logTable.
  3. Choose a name for the log, choose the maximum size, wrap percentage and minimum wrap time for the log.
  4. Send a SET request with these parameters and logRowStatus = createAndGo to the agent.
  5. If the creation failed because the logIndex was occupied, choose a new logIndex.
4.2.3.2 Log deletion

When a management application wants to delete a log, it should perform the following steps.

  1. Set the logRowStatus to destroy for the corresponding logIndex.
4.2.3.3 Controlling logs

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:

  1. Set the logAdminStatus to down for the corresponding logIndex.
4.2.3.4 Log transfer creation

When a log should be transferred to a remote host, the following steps should be followed.

First, create the log transfer entry:

  1. Decide the logIndex of the log that should be transferred.
  2. Choose a free logTransferIndex by looping through all transfer entries with the same log index as the selected log.
  3. Decide general filtering parameters for the selected log. This means find values for logTransferStartTime and logTransferStopTime.
  4. Choose a remote host, user, password and filename.
  5. Send a SET request with these parameters and logTransferRowStatus = createAndWait to the agent.
  6. Decide log specific filtering parameters for the selected log. This depends on if the type of the log has defined additional filtering parameters.

When the log transfer entry is created, the log will be transferred each time the row is activated:

  1. Send a SET request with logTransferRowStatus = active to the agent.
  2. Poll the value of logTransferRowStatus until it becomes notInService.
  3. Check the value of logTransferLastResult if the transfer succeeded or not.

If a log transfer takes too long time, the transfer may be aborted in the following way:

  1. Send a SET request with logTransferRowStatus = notInService to the agent.
  2. Poll the value of logTransferRowStatus until it becomes notInService. The logTransferLastResult is now aborted.

4.2.4 API

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.

4.3 EVA-LOG SNMP interface

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.

4.3.1 OTP-EVA-LOG-MIB

This MIB implements managed objects for the EVA LOG service. It consists of the Eva Log group.

4.3.1.1 Eva Log group

The Eva Log group consists of the table evaLogDiscriminatorTable, and the variables evaLogTotalMaxSize and evaLogTotalMaxAllowedSize.

The evaLogDiscriminatorTable has the following attributes:

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.

4.3.2 Manager use cases

This section describes how a manager may use the OTP-EVA-LOG-MIB to perform event and alarm logging.

4.3.2.1 Log creation

When a management application wants to create an event log, it should perform the following steps.

  1. Create a log in the logTable as described above, using the logType evaLogType.
  2. If the creation succeed, decide which events should be logged in the log.
  3. For each such event, create the corresponding row in evaLogDiscriminatorTable, using the same logIndex as defined in step 1
4.3.2.2 Log deletion

When a management application wants to delete an event log, it should follow the steps defined above in the section about general log deletion.

4.3.2.3 Controlling logs

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:

  1. Set the 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:

  1. Set the 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.

4.4 SNMPEA LOG SNMP interface

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.

4.4.1 OTP-SNMPEA-LOG-MIB

This MIB implements managed objects for the SNMEPA LOG service. It consists of the Snmpea Log group and Snmpea Log Transfer group.

4.4.1.1 Snmpea Log group

The Snmpea Log group consists of the single variable snmpeaLogDiscriminator. This variable controls which requests should be stored in the singel snmp audit trail log in the system. The possible values are:

none
Nothing is stored in the log.
readWrite
All requests and traps are stored in the log.
write
Only SET requests are stored in the log.
4.4.1.2 Snmpea Log Transfer group

The Snmpea Log Transfer group consists of a table 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.


Copyright © 1991-98 Ericsson Telecom AB