Integrating with SNMP-managed devices


Simple Network Management Protocol (SNMP) is a widely used protocol for network management that provides a standardized framework for monitoring and managing network devices such as routers, switches, servers, printers, firewalls, and load balancers. 

As a tenant administrator, it's important to manage network performance, find and solve network problems, and plan for network growth. The BMC Helix Intelligent Integrations SNMP Receiver connector collects SNMP traps from SNMP-managed devices.

Important

The SNMP Receiver connector is available only for the BMC Helix Intelligent Integrations on-premises gateway deployments.  

You can view the collected data in BMC Helix Operations Management and derive the following benefits:

BMC Helix application

Type of data collected or viewed

Benefits 

BMC Helix Operations Management

 

Events (SNMP traps received as events)

Use a centralized event view to monitor and manage events, perform event operations, and filter events. Identify actionable events from a large volume of event data by processing events.

For more information, see Monitoring events and reducing event noise.

As a tenant administrator, perform the following steps to collect data from SNMP-managed devices through BMC Helix Intelligent Integrations: 

ConnectorSteps.png

Supported versions

BMC Helix Intelligent Integrations supports the following SNMP versions for data collection:

  • SNMPv1
  • SNMPv2
  • SNMPv3 

Task 1: To plan for the connection

Review the following prerequisites to help you plan and configure a connection to collect SNMP traps.

SNMP prerequisites

  • Make sure that the firewall connectivity for the UDP traffic is established between the on-premises gateway and the devices that are sending SNMP traps.
  • If you want to collect SNMPv3 traps, obtain the following information from the Network administrator for configuring the connection instance in BMC Helix Intelligent Integrations:
    • Engine IDs of devices sending the SNMPv3 traps.
    • SNMPv3 user account credentials. This includes user name, authentication, and privacy credentials.  Depending on the SNMPv3 security level, the Network administrator provides the authentication and privacy protocol credentials. 

      Security Level

      Authentication Protocol 

      Authentication Password

      Privacy Protocol

      Privacy Password

      noAuthNoPriv

      Not required

      Not required

      Not required

      Not required

      authNoPriv

      Required

      Required

      Not required

      Not required

      authPriv

      Required

      Required

      Required

      Required

      For example, if a device sends SNMPv3 traps with the authPriv security level, Network administrator provides the authentication and privacy protocol credentials. Similarly, if a device sends SNMPv3 traps with the authNoPriv security level, Network administrator provides the authentication protocol credentials.
      SNMP-managed devices send SNMPv3 traps by using one of the following authentication and privacy protocols: 

      Authentication protocol

      Privacy protocol

      • AuthHMAC128SHA224
      • AuthHMAC192SHA256
      • AuthHMAC256SHA384
      • AuthHMAC384SHA512
      • AuthMD5
      • AuthSHA (default)
      • Priv3DES
      • PrivAES128
      • PrivAES192
      • PrivAES256
      • PrivDES (default)
  • Plan for the port numbers on which you want to receive SNMP traps on the on-premises gateway host.

Important

Use the ports that are not being used by other programs. We recommend that you use ports greater than 1024 because ports lesser than 1024 can be utilized by privileged users only. 

By default, the on-premises gateway is configured to receive traps on the port numbers in the range of 1061 to 1070. To use a different port number or define a new range of port numbers, configure the on-premises gateway host.

Click here to see the instructions:
  1. Navigate to the /<IIGateway_INSTALL_DIR>/hii directory and open the docker-compose.yaml or podman-compose.yaml file with a text editor.
  2. Navigate to the mediator section and perform the following steps:
    • To add a new port number (for example, 1074), add 1074 in the expose and ports sections, as shown in the following example:

          expose:
            - 1600
            - 9000
            - 1074

      #you'll have to make a new entry for every new port you wish to use
          ports:
            - 10002:10002
            - 9095:9095 #Prometheus metrics
           - "1074:1075/udp"
    • To define a new range of port numbers (for example, 1062-1080), edit the existing range in the expose and ports sections, as shown in the following example:

          expose:
            - 1600
            - 9000
            - "1062-1080"

      #you'll have to make a new entry for every new port you wish to use
          ports:
            - 10002:10002
            - 9095:9095 #Prometheus metrics
           - "1062-1080:1062-1080/udp"
  3. Save and close the file.
  4. Restart the container service by using the following command:
    • docker-compose

      docker compose down
      docker compose up -d
    • podman-compose

      podman-compose -f podman-compose.yaml down
      podman-compose -f podman-compose.yaml up -d
  • On the SNMP device from which you want to receive traps, configure the destination IP address and the planned port number. 
  • Before you start configuring a connection with SNMP, prepare the events JSLT mapping. 
    ​​​​​BMC Helix Intelligent Integrationsreceives the SNMP traps from the devices and applies JSLT mapping to transform them into BMC Helix Operations Management understandable events (in JSON format). 
    ​​​​​​

    • Refer to this JSLT to map the incoming SNMP traps to the default SNMP_TRAP event class.
    Click here to expand...

      def search-key(data, searchkey)
        if (is-object($data))
            [ for ($data)
                if (.key == $searchkey)
                    trim(.value)
                else
                    search-key(.value, $searchkey)
            ] |
            flatten(.)
        else if (is-array($data))
            [
                for ($data)
                    search-key(., $searchkey)
            ] |
            flatten(.)
        else
            []

    def remove-search-key-keep-keys(data, searchKey)
        if (is-object($data))
            [
                for ($data)
                    trim(.key) if(.key != $searchKey and not(is-object(.value)) and not(is-array(.value)) )
            ] +
            [
                for ($data)
                    remove-search-key-keep-keys(.value,$searchKey)
            ]
        else if (is-array($data))
            [
                for ($data)
                    remove-search-key-keep-keys(.,$searchKey)
            ]
        else
            []

    def remove-search-key-keep-values(data, searchKey)
        if (is-object($data))
            [for ($data)
                trim(.value) if(.key != $searchKey and not(is-object(.value)) and not(is-array(.value)) )
            ] +
            [
                for ($data)
                    remove-search-key-keep-values(.value,$searchKey)
            ]
        else if (is-array($data))
            [
                for ($data)
                    remove-search-key-keep-values(.,$searchKey)
            ]
        else
            []

    def getSnmpVersionString(input)(
    [
        for ($input)
            .|.key if(.value.snmpModules != null)
    ]
    )

    // ************** Do not modify the above methods *************

    def mapTrapType(inputTrapStr)(
    if(lowercase($inputTrapStr) == "coldstart")
        "0"
    else if(lowercase($inputTrapStr) == "warmstart")
        "1"
    else if(lowercase($inputTrapStr) == "linkdown")
        "2"
    else if(lowercase($inputTrapStr) == "linkup")
        "3"
    else if(lowercase($inputTrapStr) == "authenticationfailure")
        "4"
    else if(lowercase($inputTrapStr) == "snmpTraps.6")
        "5"
    else
        "6"
    )

    def getValueByOid(data,oid)
        if (is-object($data))
            [ for ($data)
                if (.value == $oid)
                    [for($data) .value if(.key != "oid") ]
                else
                    getValueByOid(.value, $oid)
            ] |
            flatten(.)
        else if (is-array($data))
            [
                for ($data)
                    getValueByOid(., $oid)
            ] |
            flatten(.)
        else
            []

    def mapSeverity(inputSeverity)
        (
        if(lowercase($inputSeverity) == "info")
            "INFO"
        else if(lowercase($inputSeverity) == "okay")
            "OK"
        else if(lowercase($inputSeverity) == "failure")
            "CRITICAL"
        else if(lowercase($inputSeverity) == "warning")
            "WARNING"
        else
            $inputSeverity
        )

    let root = ."1".org.dod.internet
    let additional_info=.additionalDetails
    let enterpriseInfo = ($root.private)
    let snmp_version = getSnmpVersionString($root)[0]
    let snmp_oid_path = get-key($root,$snmp_version).snmpModules.snmpMIB
    let snmp_address_path = get-key($root,$snmp_version).snmpModules.snmpCommunityMIB
    let snmp_trap_address = fallback(search-key($snmp_address_path,"snmpTrapAddress.0")[0],
    capture($additional_info.peerAdresss,"^(?<host>[^/]+)").host)

    let severity=fallback(search-key($enterpriseInfo,"omEntAlertSeverity")[0],
    getValueByOid($enterpriseInfo,"1.3.6.1.4.1.674.11000.1000.500.1.3")[0],"OK")

    let source_hostname = fallback(search-key($enterpriseInfo,"omEntAlertDevice")[0],
    getValueByOid($enterpriseInfo,"1.3.6.1.4.1.674.11000.1000.500.1.2")[0],$snmp_trap_address)

    let snmpTrapOID = search-key($snmp_oid_path,"snmpTrapOID.0")[0]

    let trapType = mapTrapType($snmpTrapOID)
    let trapTypeStr = if( $trapType == "6") "enterpriseSpecific" else $snmpTrapOID

    let message = if($trapTypeStr == "enterpriseSpecific")  fallback(search-key($enterpriseInfo,"omEntAlertMessage")[0],
    getValueByOid($enterpriseInfo,"1.3.6.1.4.1.674.11000.1000.500.1.1")[0],"SNMP Trap Received")
    else $snmpTrapOID


    {
        "class":"SNMP_TRAP",
        "status": "OPEN",
        "severity":mapSeverity($severity),
        "msg":$message,
        "details":"sample details",
        "creation_time": string(number(round(now())) * 1000),
        "source_identifier":$source_hostname,
        "source_hostname":$source_hostname,
        "source_unique_event_id":fallback($snmpTrapOID,"dummy id"),
        "_ci_id":$source_hostname,
        "extras":{
            "snmp_oids": fallback(search-key($enterpriseInfo,"oid"),[""]),
            "snmp_oidst": fallback(flatten(remove-search-key-keep-keys($enterpriseInfo,"oid")),[""]),
            "snmp_vals":fallback(flatten(remove-search-key-keep-values($enterpriseInfo,"oid")),[""]),
            "additional_info":string($additional_info),
            "snmp_version":number($additional_info.snmpVersion),
            "snmp_error_status":$additional_info.errorStatus,
            "snmp_request_id":$additional_info.requestId,
            "snmp_error_index":$additional_info.errorIndex,
            "snmp_trap_type":$trapType,
            "snmp_trap_type_str": $trapTypeStr,
            "snmp_raw_json":""
        },
        "sourceEntityType":"SNMP",
        "source_attributes": {
            "external_id" : $source_hostname
        }
    }
        

    • Refer to this JSLT to map the incoming SNMP traps to vendor specific custom classes. 
    Click here to expand...

       def search-key(data, searchkey)
        if (is-object($data))
            [ for ($data)
                if (.key == $searchkey)
                    trim(.value)
                else
                    search-key(.value, $searchkey)
            ] |
            flatten(.)
        else if (is-array($data))
            [
                for ($data)
                    search-key(., $searchkey)
            ] |
            flatten(.)
        else
            []
      
    def remove-search-key-keep-keys(data, searchKey)
        if (is-object($data))
            [
                for ($data)
                    trim(.key) if(.key != $searchKey and not(is-object(.value)) and not(is-array(.value)) )
            ] +
            [
                for ($data)
                    remove-search-key-keep-keys(.value,$searchKey)
            ]
        else if (is-array($data))
            [
                for ($data)
                    remove-search-key-keep-keys(.,$searchKey)
            ]
        else
            []
      
    def remove-search-key-keep-values(data, searchKey)
        if (is-object($data))
            [for ($data)
                trim(.value) if(.key != $searchKey and not(is-object(.value)) and not(is-array(.value)) )
            ] +
            [
                for ($data)
                    remove-search-key-keep-values(.value,$searchKey)
            ]
        else if (is-array($data))
            [
                for ($data)
                    remove-search-key-keep-values(.,$searchKey)
            ]
        else
            []
      
    def getSnmpVersionString(input)(
    [
        for ($input)
            .|.key if(.value.snmpModules != null)
    ]
    )
      
    def dropKeysFromJSON(input, keysToDrop)(
    {
        for ($input)
            .key : .value if (not(contains(.key, $keysToDrop)))
    })
     
    let varnames = ["varbind_01", "varbind_02", "varbind_03", "varbind_04", "varbind_05", "varbind_06", "varbind_07", "varbind_08", "varbind_09", "varbind_10", "varbind_11", "varbind_12", "varbind_13", "varbind_14", "varbind_15", "varbind_16", "varbind_17", "varbind_18", "varbind_19", "varbind_20", "varbind_21", "varbind_22", "varbind_23", "varbind_24", "varbind_25", "varbind_26", "varbind_27", "varbind_28", "varbind_29", "varbind_30", "varbind_31", "varbind_32", "varbind_33", "varbind_34", "varbind_35", "varbind_36", "varbind_37", "varbind_38", "varbind_39", "varbind_40", "varbind_41", "varbind_42", "varbind_43", "varbind_44", "varbind_45", "varbind_46", "varbind_47", "varbind_48", "varbind_49", "varbind_50"]
      
      
    // ****************Do not modify the above declarations **************

    def mapTrapType(inputTrapStr)(
    if(lowercase($inputTrapStr) == "coldstart")
        "0"
    else if(lowercase($inputTrapStr) == "warmstart")
        "1"
    else if(lowercase($inputTrapStr) == "linkdown")
        "2"
    else if(lowercase($inputTrapStr) == "linkup")
        "3"
    else if(lowercase($inputTrapStr) == "authenticationfailure")
        "4"
    else if(lowercase($inputTrapStr) == "snmpTraps.6")
        "5"
    else
        "6"
    )
      
    def getValueByOid(data,oid)
        if (is-object($data))
            [ for ($data)
                if (.value == $oid)
                    [for($data) .value if(.key != "oid") ]
                else
                    getValueByOid(.value, $oid)
            ] |
            flatten(.)
        else if (is-array($data))
            [
                for ($data)
                    getValueByOid(., $oid)
            ] |
            flatten(.)
        else
            []
      
    def mapSeverity(inputSeverity)
        (
        if(lowercase($inputSeverity) == "info")
            "INFO"
        else if(lowercase($inputSeverity) == "okay")
            "OK"
        else if(lowercase($inputSeverity) == "failure")
            "CRITICAL"
        else if(lowercase($inputSeverity) == "warning")
            "WARNING"
        else
            $inputSeverity
        )
      
    let root = ."1".org.dod.internet
    let additional_info=dropKeysFromJSON(.additionalDetails, ["requestId" ,"errorStatus" ,"errorIndex" ,"BERLength" ,"BERPayloadLength" ,"maxRepetitions" ,"nonRepeaters" ,"snmpVersion" ,"eventMaxSizeResponsePDU" ,"eventPduHandle" ,"transportSecurityLevel" ,"stateMaxSizeResponseScopedPDU" ,"stateTransportMappingInformation"])
      
    let enterpriseInfo = ($root.private)
    let snmp_version = getSnmpVersionString($root)[0]
    let snmp_oid_path = get-key($root,$snmp_version).snmpModules.snmpMIB
    let snmp_address_path = get-key($root,$snmp_version).snmpModules.snmpCommunityMIB
    let snmp_trap_address = fallback(search-key($snmp_address_path,"snmpTrapAddress.0")[0],
    capture($additional_info.peerAdresss,"^(?<host>[^/]+)").host)
      
    let severity=fallback(search-key($enterpriseInfo,"omEntAlertSeverity")[0],
    getValueByOid($enterpriseInfo,"1.3.6.1.4.1.674.11000.1000.500.1.3")[0],"OK")
      
    let source_hostname = fallback(search-key($enterpriseInfo,"omEntAlertDevice")[0],
    getValueByOid($enterpriseInfo,"1.3.6.1.4.1.674.11000.1000.500.1.2")[0],$snmp_trap_address)
      
    let snmpTrapOID = search-key($snmp_oid_path,"snmpTrapOID.0")[0]
      
    let trapType = mapTrapType($snmpTrapOID)
    let trapTypeStr = if( $trapType == "6") "enterpriseSpecific" else $snmpTrapOID
      
    let message = if($trapTypeStr == "enterpriseSpecific")  fallback(search-key($enterpriseInfo,"omEntAlertMessage")[0],
    getValueByOid($enterpriseInfo,"1.3.6.1.4.1.674.11000.1000.500.1.1")[0],"SNMP Trap Received")
    else $snmpTrapOID
      
    let oidst = fallback(flatten(remove-search-key-keep-keys($enterpriseInfo,"oid")),[""])
       
    let dynamic_class_name = if(size($oidst) == 0)
    "SNMP_TRAP"
    else
    "SNMP_" + uppercase($additional_info.enterpriseName)
     
      
    let custom-class-extras = zip($oidst, fallback(flatten(remove-search-key-keep-values($enterpriseInfo,"oid")),[""]))
    let snmpOIDs = fallback(search-key($enterpriseInfo,"oid"),[""])
    let snmpEnterpriseOID = "1.3.6.1.4.1." + split($snmpOIDs[0], "\\.")[6]
     
     
    {
        "class":"",
        "status": "OPEN",
        "severity":mapSeverity($severity),
        "msg":$message,
        "details":"sample details",
        "creation_time": string(number(round(now())) * 1000),
        "source_identifier":$source_hostname,
        "source_hostname":$source_hostname,
        "source_unique_event_id":fallback($snmpTrapOID,"dummy id"),
        "_ci_id":$source_hostname,
        "extras":{
            "snmp_oids": $snmpOIDs ,
            "snmp_oidst": $oidst,
            "snmp_vals":fallback(flatten(remove-search-key-keep-values($enterpriseInfo,"oid")),[""]),
            "additional_info":string($additional_info),
            "snmp_version":number($additional_info.snmpVersion),
            "snmp_error_status":$additional_info.errorStatus,
            "snmp_request_id":$additional_info.requestId,
            "snmp_error_index":$additional_info.errorIndex,
            "snmp_trap_type":$trapType,
            "snmp_trap_type_str": $trapTypeStr,
            "snmp_dynamic_class": $dynamic_class_name,
            "snmp_raw_json":"",
            "snmp_enterprise_entity_name" : $additional_info.enterpriseEntityName,
            "snmp_enterprise" : $snmpEnterpriseOID,
            "snmp_enterprise_str": $additional_info.enterpriseName
        } + {
    for ($varnames) string(.) : join($custom-class-extras[index-of($varnames, .)], "=")
    }
    ,
        "sourceEntityType":"SNMP",
        "source_attributes": {
            "external_id" : $source_hostname
        }
    }
      

    Important
    • If MIBs are missing for SNMP traps, BMC Helix Intelligent Integrations maps the traps to the default SNMP_TRAP event class.
    • If you are using a user-defined class name in the custom JSLT, make sure that the user-defined class is the child of the SNMP_ENTERPRISE class to avoid any unmapped data.

    For example,
    {
      "name": "SNMP_XYZ",
      "parentClassName": "SNMP_ENTERPRISE",
      "attributes": [
        {
          "name": "sample_attribute",
          "dataType": "STRING"
        }
      ]
    }
     

On-premises gateway prerequisites

  1. (Optional) Perform the following steps to configure multiple Engine IDs in a connection instance by using a configuration file:
    1. Obtain all the Engine IDs with the SNMP user credentials from the Network administrator.

      Important
      User credentials are provided based on the security level of the SNMPv3 traps.

    2. Store all the details in a configuration file, for example, snmptrapd.conf, in the following format:

      createUser -e <engineID> <userName> <authenticationProtocol> <authenticationPassword> <privacyProtocol> <privacyPassword>

      This table describes the parameters used in the snmptrapd.conf file:
      ParameterDescription
      engineIDUnique identifier of the device that sends the SNMPv3 traps.
      userNameName of the user associated with the Engine ID that sends the SNMPv3 traps.
      authenticationProtocolAuthentication type to make sure that traps are from legitimate source. For more information, see SNMP prerequisites.
      authenticationPasswordAuthentication password to make sure that traps are from legitimate source.
      privacyProtocolEncryption type to protect sensitive data from interception and unauthorized viewing during transit. For more information, see SNMP prerequisites.
      privacyPasswordEncryption password to protect sensitive data from interception and unauthorized viewing during transit.

      For example:

      createUser -e 0x80000549010f0f1008 userA SHA 1234567890abcdef DES 1234567890abcdef
      createUser -e 0x80000549010f0f1007 userB SHA 1234567000abcdef DES 1234567000abcdef
    3. Navigate to the /<IIGateway_INSTALL_DIR>/hii/conf directory and save the configuration file you created in step 1(b).

  2. Perform the following steps to store the Management Information Base (MIB) files on the on-premises gateway:
    MIB is a hierarchical database that contains configuration and other vital management information of SNMP devices in the form of data objects. An SNMP management system uses these database files to interpret the messages sent by the managed devices.
    1. Obtain the MIB files of the SNMP-managed devices from where you want to receive traps.
    2. Copy the MIB files to the /<IIGateway_INSTALL_DIR>/hii/mibs directory.

Task 2: To configure the connection with SNMP-managed devices

  1. Use the following URL to access the on-premises gateway: https://<hostName>:<portNumber>/swpui
  2. On the CONNECTORS tab, click add_icon.pngin the SOURCES panel.
  3. Click the SNMP Receiver tile.
  4. Specify the source connection details:
    1. Specify a unique instance name.

      Best practice
      We recommend that you specify the instance name in the following format:

      <sourceType>_<sourceControllerServerName>_<InstanceQualifier>

      The instance qualifier helps you distinguish the multiple instances configured from the same source server. For example, you can name your instances SNMP_PROD and SNMP_TEST.

    2. (Optional) Select the Logging for SNMP4j option to enable logging.
    3. Specify the port number that you have configured on the SNMP-managed device, as described in SNMP prerequisites.
    4. (Optional) To collect SNMPv3 traps in addition to the SNMPv1 and SNMPv2 traps, select the Accept SNMP V3 Traps option. You can either provide details to collect SNMPv3 traps from one device with one user, or use the Use Configuration File option to collect SNMPv3 traps from multiple devices and multiple users associated with them.

      • To collect SNMPv3 traps from one device with one user:
        1. Specify the SNMPv3 user name.
        2. Depending on the security protocol used for SNMPv3, select the Authentication and Privacy options and enter the credentials provided by the Network administrator. For more information, see SNMP prerequisites.
        3. Specify the Engine ID.
      • To collect SNMPv3 traps from multiple devices with multiple users:
        1. Select the Use Configuration File option.
        2. Provide the configuration file name where the Engine IDs with the user credentials are stored. For more information, see On-premises gateway prerequisites.

      For more information, see On-premises gateway prerequisites.

      Important
      If you provide the details of one device with one user by using the available fields and also use the Use Configuration File option to provide details of multiple devices with multiple users, the Use Configuration File option takes precedence.

  5. Click VALIDATE AND CREATE.
    The source connection is created in the Source Connection list.
  6. Verify that the source connection you created is selected.

    Important

    The destination host connection is created and configured automatically for each tenant when the source connection is created.

  7. Verify that the options for the data types for which you want to collect data are selected.
  8. Click CREATE COLLECTORS to create the required collector streams for the selected data types.
  9. Click a data type and specify the configuration parameters in the Distributors section as described in the following table:

    Parameter name

    Description

    Max Batching Size

    Specify the maximum number of data items to send in a single POST request to the destination API.

    The batch size depends on the destination’s ability to buffer the incoming data.

    Default: 250

    Max Batching Delay

    Specify the maximum time (in seconds) to wait before the system builds and processes a batch.

    Default: 3 seconds 

    Base Retry Delay

    Specify the initial time (in seconds) for which to wait before the system tries to rebuild and process a batch.

    The waiting time increases in the following sequence: n1, n2, n3, and so on, where n indicates the number of seconds.

    Default: 2 seconds

    Example:

    Base Retry Delay is set to 2 seconds.

    Retry is performed after 2, 4, 8, 16, and so on, seconds.

    Max Intra-Retry Delay

    Specify the maximum limit for the base retry delay. 

    Default: 60 seconds

    Example:

    Max Intra-Retry Delay is set to 60 seconds.
    Base Retry Delay is set to 2 seconds.

    Retries are performed 2, 4, 8, 16, 32, and so on, seconds later.

    Max Retry Duration

    Specify the total time for which the system retries a delivery. For REST destinations, a delivery is a batch of data items in one POST request. 

    Default: 5 minutes

    Example:

    Max Retry Duration is set to 8 hours.
    Base Retry Delay is set to 2 seconds.

    Requests are sent for 2+4+8+16+32+64+132, and so on until 8 hours in total duration is reached. After that, no subsequent attempts are made to retry the delivery.

    The assumption here is that if there is an outage or other issue with the destination tool, recovery should take less than the value of the Max Retry Duration parameter to be completed.

    Attributes To Be Dropped When Updating Events

    Specify the event attributes that you do not want to be updated in BMC Helix Operations Management when events are updated. 

    For example, if you do not want an event's severity, source address, source category, and subcategory to be updated in  BMC Helix Operations Management, you need to specify those attributes in a comma-separated format: severity,source_address,source_category,source_subcategory

    Important:

    You can obtain the event attribute names in  BMC Helix Operations Management, by exporting any event data  in JSON, BAROC, XML, or CSV  format. The exported file contains all attributes of the event data, and from there you can identify the attributes to be dropped. 

    JSLT

    JSLT

    Replace the existing JSLT with the default or custom JSLT that you have prepared according to the sample shown in SNMP prerequisites.

    Event Class JSON

    (Optional) If you are using any event class other than the already existing classes in BMC Helix Operations Management, specify the JSON for the event class.
    Important:
    If you are using a user-defined class name in the custom JSLT, make sure that the user-defined class is the child of the SNMP_ENTERPRISE class to avoid any unmapped data.
    For example,
    {
      "name": "SNMP_XYZ",
      "parentClassName": "SNMP_ENTERPRISE",
      "attributes": [
        {
          "name": "sample_attribute",
          "dataType": "STRING"
        }
      ]
    }
    For more information, see SNMP prerequisites.

    Event Policy JSON

    (Optional) By default, events are processed in BMC Helix Operations Management according to an out-of-the-box policy. If you want to apply a different policy, specify the JSON for the same.

    For information about creating event policies, see Defining event policies for enrichment correlation notification and suppression and for exporting policies in JSON format, see Migrating event policies between tenants..

     

  10. Click CREATE DISTRIBUTORS to create the required distributor streams for the selected data types.
  11. Click one of the following buttons:
    • SAVE STREAM: Click this button if you want to edit the connection details before the data collection starts. After you save the stream, the connection instance that you just created is listed in the SOURCES panel. Move the slider to the right to start the data stream.
    • SAVE AND START STREAM: Click this button if you want to save the connection details and start collecting data immediately.
      For more information about the data streams, see Starting-or-stopping-data-streams.

Important

Wait for some time after starting the data stream. Large MIB files might take longer to compile.

Task 3: To verify the connection

In BMC Helix Intelligent Integrations, on the SOURCES panel, confirm that the data stream for the connection you created is running. Data streaming is indicated by moving arrow.

SNMP_connector.png

A moving dark blue arrow (EventsStream_Icon.png ) indicates that the event stream is running. Event data is pushed as soon as the SNMP traps are available.

To view events in BMC Helix Operations Management

  1. In BMC Helix Operations Management, select Monitoring > Events.
  2. Filter the events by the SNMP_TRAP class (represented by SNMP Trap on the Events page).
    SNMP_traps.png

Incoming events from SNMP  are processed in BMC Helix Operations Management through a set of deduplication rules to determine whether the incoming event is a duplicate event or a new event. For more information about the rules, see Event-deduplication-suppression-and-closure-for-reducing-event-noise

For information about events, see Monitoring and managing events.

If you face any issues when viewing events, see To troubleshoot SNMP data collection issues.

To troubleshoot SNMP data collection issues

You might encounter the following issues when collecting traps from SNMP-managed devices.

SNMP traps are not collected by the on-premises gateway

Issue symptoms

BMC Helix Operations Managementdoes not show any SNMP events. 

Resolution

Important: Make sure that before you modify any connector configuration, stop the stream, make the changes,
and then start the stream again.

  1. Make sure that the SNMP event stream is running.
  2. Make sure that the docker-compose.yaml or podman-compose.yaml file contains the correct port numbers. 
  3. Verify that the port you have used when configuring the connection instance is listening by running the following command on the on-premises gateway host:

    netstat -lntu | grep <portNumber>

    If the port is listening, go to step 4. If the port is not listening, verify that that the port is open.

  4. Verify that the SNMP trap destination address and port are configured properly, as described in the SNMP prerequisites section.
  5. Verify that the JSLT provided in the SNMP configuration is correct by performing the following steps:
    1. Stop the data stream.
    2. Click Configure Mediator icon_gear.pngadjacent to SNMP.
    3. Expand the SNMP RECEIVER section.
    4. Select the Logging for SNMP4j option.
    5. Click VALIDATE.
    6. Click SAVE & CLOSE.
    7. Start the stream and wait for few minutes until you receive the following log entry in the swp-mediator container logs:

      SNMP-Receiver-Collector:snmpreceiver:XXXX has become Active

      This log entry indicates that the SNMP event stream is running.

    8. Identify the issue from the log entries in the swp-mediator container logs: 
      • If you do not see the following log entry, it indicates that BMC Helix Intelligent Integrations is not receiving SNMP trapsDefaultUDPTransportMapping_0:0:0:0:0:0:0:0/1062 DEBUG Received message from ...Make sure that in the source device, the SNMP trap destination address and port are configured correctly. 
        Alternatively, you can identify the issue by using the tcpdump command:tcpdump -A -i {INTERFACE_NAME} 'port 1062'
      • If you see the following log entry, provide the correct JSLT in the distributor configuration. Use the sample JSLT to create the JSLT.

        "level":"ERROR","thread":"zio-fiber-xxxxxxxxx","message":"failed to convert StringEvent Unable to extract events, individually or as an array from the incoming JSON - check JSLT. errors seen :this error indicates improper JSLT -

If the issue persists, contact BMC Support with the swp-mediator logs.

SNMPv1 and SNMPv2 traps are collected, but SNMPv3 traps are not collected  

Issue symptoms

BMC Helix Operations Managementdoes not show any SNMPv3 events. However, SNMPv1 and SNMPv2 events are present.

Resolution

  1. Verify that one of the following authentication and privacy protocols is used when configuring the SNMP connection instance:

    Authentication protocols

    Privacy protocols

    • AuthHMAC128SHA224
    • AuthHMAC192SHA256
    • AuthHMAC256SHA384
    • AuthHMAC384SHA512
    • AuthMD5
    • AuthSHA
    • PrivDES
    • Priv3DES
    • PrivAES128
    • PrivAES192
    • PrivAES256
  2. Verify that the Engine ID used to configure the SNMP connection instance is correct:
    1. Stop the stream.
    2. Click Configure Mediator icon_gear.pngadjacent to SNMP.
    3. Expand the SNMP RECEIVER section.
    4. Select the Logging for SNMP4j option.
    5. Click VALIDATE.
    6. Click SAVE & CLOSE.
    7. Start the stream and wait for few minutes until you receive the following log entry in the swp-mediator container logs:

      SNMP-Receiver-Collector:snmpreceiver:XXXX has become Active

      This log entry indicates that the SNMP event stream is running.

    8. In the swp-mediator container logs, search for the following log entry:

      DefaultUDPTransportMapping_0:0:0:0:0:0:0:0/1062 DEBUG getUser(engineID=XX:XX:XX:XX:XX:XX:XX:XX,securityName=user1,requiredLocalizationGrant=incoming..
    9. Update the Engine ID with the Engine ID provided in the logs.

 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*