Yes I do think this sounds similar to network switch interfaces, where each
interface has a set of properties.

I've attached the MIB file here in case that's helpful, and the generator
file I'm currently using.
There is a deviceIndex column but I'm not sure how it's supposed to work.
As an example, for one particular device with index 4201, the data looks
like this.  Do I need to configure lookups, in order to merge all these
data points into a single "device"?

deviceEth1Status_info{deviceEth1Status="online",deviceIndex="*4201*"} 1

deviceEth2Status_info{deviceEth2Status="unconfigured",deviceIndex="*4201*"}
1

deviceFirmware{deviceFirmware="5.5.0",deviceIndex="*4201*"} 1

deviceIP1{deviceIP1="10.49.55.136",deviceIndex="*4201*"} 1

deviceIP2{deviceIP2="",deviceIndex="*4201*"} 1

deviceIdentifier{deviceIdentifier="000f58fffe079bdd",deviceIndex="*4201*"} 1

deviceIndex{deviceIndex="*4201*"} *4201*

deviceLock_info{deviceIndex="*4201*",deviceLock="none"} 1

deviceMAC1{deviceIndex="*4201*",deviceMAC1="00:0f:58:07:9b:df"} 1

deviceMAC2{deviceIndex="*4201*",deviceMAC2="00:0f:58:07:9b:e0"} 1

deviceName{deviceIndex="*4201*",deviceName="ENG 4021T"} 1

deviceSerialNum{deviceIndex="*4201*",deviceSerialNum="2004A0241038"} 1

deviceStatus_info{deviceIndex="*4201*",deviceStatus="online"} 1

deviceType{deviceIndex="*4201*",deviceType="tx4"} 1




On Sat, Aug 5, 2023 at 2:47 AM Brian Candler <[email protected]> wrote:

> > This table has 15 columns and 65 rows.
>
> That sound similar to ifTable/ifXTable in IF-MIB.
>
> > Each row represents a "sub-device"
>
> That sounds similar to "interfaces" on a network device. Is there some
> column which can be used to identify the sub-device, similar to
> ifName/ifDescr/ifAlias?
>
> > Ideally, I'd like to create some kind of time series graph for each
> metric/column, each of which has lines for each device/row.
>
> Like plotting graphs for ifHCInOctets, ifHCOutOctets, ifErrors etc.  See
> if you can model on that.
>
> As for enums, there's some info here:
>
> https://github.com/prometheus/snmp_exporter/blob/v0.23.0-rc.1/generator/README.md#enumasinfo-and-enumasstateset
>
> You'd use EnumAsStateSet only if you want a single SNMP data point to be
> exploded into N different timeseries, one for each possible value. e.g.
> suppose you have a single enumerated value for the status of a UPS, it
> could expand to
>
> apcups_status{status="online"} 0
> apcups_status{status="onbatt"} 1
> apcups_status{status="trim"} 0
> apcups_status{status="boost"} 0
> apcups_status{status="overload"} 0
> ...etc
>
> EnumAsInfo will apply a single label which changes (therefore, if it ever
> changes, the timeseries will change; only use this for labels which are
> essentially static).  Alternatively, you could represent enums as a plain
> integer stored as a numeric metric, and then in Grafana you map each
> integer value to a different label and/or colour.
>
> On Saturday, 5 August 2023 at 08:13:01 UTC+1 Ben Kochie wrote:
>
>> What you need is to take the device MIB and use the SNMP exporter's
>> generator to translate the table into metrics. Unfortunately, Adder
>> Technology doesn't seem to have their MIB publicly available, so I can't
>> see what it specifies in the table.
>>
>> On Sat, Aug 5, 2023 at 3:42 AM 'Elliott Balsley' via Prometheus Users <
>> [email protected]> wrote:
>>
>>> I've just started using Grafana and Prometheus with SNMP Exporter.  My
>>> Adder AIM server provides SNMP data in a table format, which is very hard
>>> to comprehend in Grafana.  Is there some recommended way to handle this
>>> type of data?
>>> This table has 15 columns and 65 rows.  Each row represents a
>>> "sub-device", or an Adder KVM endpoint.  Attached is a screenshot from the
>>> open-source SnmpB app showing it nicely.
>>>
>>> The data comes into Prometheus looking like this (just a few lines
>>> example), with each metric on a separate line:
>>> # HELP deviceEth1Status Status of eth1 interface -
>>> 1.3.6.1.4.1.25119.1.1.1.30 (EnumAsStateSet) # TYPE deviceEth1Status gauge
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="1"} 0
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="101"} 0
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="1101"} 0
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="1201"} 0
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="1301"} 0
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="1401"} 0
>>> deviceEth1Status{deviceEth1Status="absent",deviceIndex="1501"} 0
>>>
>>> It also includes dozens of extra "rows" for devices which don't actually
>>> exist.
>>> Ideally, I'd like to create some kind of time series graph for each
>>> metric/column, each of which has lines for each device/row.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Prometheus Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/prometheus-users/fc2aceb2-6b45-4c8f-9297-eee882bdf8acn%40googlegroups.com
>>> <https://groups.google.com/d/msgid/prometheus-users/fc2aceb2-6b45-4c8f-9297-eee882bdf8acn%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Prometheus Users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/prometheus-users/J8P5NNe5ez4/unsubscribe
> .
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/prometheus-users/3f83a84d-2fb1-4320-afeb-5d6b088d750en%40googlegroups.com
> <https://groups.google.com/d/msgid/prometheus-users/3f83a84d-2fb1-4320-afeb-5d6b088d750en%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Prometheus Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/prometheus-users/CALajkdgjWcUQtUuUFRycmjA9J5KnR%2BaU_V5vqDwZyY-rehVyvA%40mail.gmail.com.
---
---  Copyright(C) 2016 Adder Technology Limited
---
---  AdderLink Infinity Manager (AIM) Management Information Base (MIB)
---

ADDER-AIM-MIB DEFINITIONS ::= BEGIN

    IMPORTS
        MODULE-IDENTITY, OBJECT-IDENTITY, NOTIFICATION-TYPE,
        OBJECT-TYPE, Unsigned32, enterprises FROM SNMPv2-SMI
        NOTIFICATION-GROUP, OBJECT-GROUP FROM SNMPv2-CONF;

    adderlinkInfinityManager MODULE-IDENTITY
        LAST-UPDATED "201606271450Z"
        ORGANIZATION "Adder Technology Limited"
        CONTACT-INFO
            "http://www.adder.com/contact-details";
        DESCRIPTION
            "Top level AdderLink Infinity Manager MIB tree"
        REVISION    "201606271450Z"
        DESCRIPTION
            "In development"
    ::= { enterprises 25119 1 }

    adderTechnology OBJECT IDENTIFIER ::= { enterprises 25119 }

    infinityTable OBJECT-TYPE
        SYNTAX SEQUENCE OF InfinityEntry
        MAX-ACCESS not-accessible
        STATUS current
        DESCRIPTION
            "Table of Infinities"
        ::=  { adderlinkInfinityManager 1 }

    infinity OBJECT-TYPE
        SYNTAX InfinityEntry
        MAX-ACCESS not-accessible
        STATUS current
        DESCRIPTION
            "Row definition for Infinity table."
        INDEX { deviceIndex }
    ::= { infinityTable 1 }

    InfinityEntry ::= SEQUENCE {
        deviceIndex         Unsigned32,
        deviceType          OCTET STRING,
        deviceFirmware      OCTET STRING,
        deviceName          OCTET STRING,
        deviceIdentifier    OCTET STRING,
        deviceIP1           OCTET STRING,
        deviceMAC1          OCTET STRING,
        deviceIP2           OCTET STRING,
        deviceMAC2          OCTET STRING,
        deviceSerialNum     OCTET STRING,
        deviceStatus        INTEGER,
        deviceLock          INTEGER,
        deviceEth1Status    INTEGER,
        deviceEth2Status    INTEGER
    }

    deviceIndex OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "d_id from the 'device' tuple"
    ::= { infinity 1 }

    deviceType OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(2..10))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Type of device"
    ::= { infinity 2 }

    deviceFirmware OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(1..30))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Firmware version of device"
    ::= { infinity 3 }

    deviceName OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(1..45))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "User-assigned name of device"
    ::= { infinity 4 }

    deviceIdentifier OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..16))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Unique Identifier of device"
    ::= { infinity 5 }

    deviceIP1 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..15))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "IP address of interface eth1"
    ::= { infinity 6 }

    deviceMAC1 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..17))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "MAC address of interface eth1"
    ::= { infinity 7 }

    deviceIP2 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..15))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "IP address of interface eth2"
    ::= { infinity 8 }

    deviceMAC2 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..17))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "MAC address of interface eth2"
    ::= { infinity 9 }

    deviceSerialNum OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..12))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Serial number of device"
    ::= { infinity 10 }

    deviceStatus OBJECT-TYPE
        SYNTAX INTEGER {
                        offline(1),
                        online(2),
                        rebooting(3),
                        resetting(4),   -- executing a factory reset
                        upgrading(5),   -- upgrading firmware
                        unconfigured(6),-- unconfigured
                        backup(7),      -- running backup firmware image
                        unknown(8)      -- status unknown
                 }
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "General status of device"
    ::= { infinity 20 }

    deviceLock OBJECT-TYPE
        SYNTAX INTEGER {
                        none(1),        -- Not connected
                        videoOnly(2),
                        shared(3),
                        exclusive(4),
                        private(5),
                        unknown(6)      -- lockmode unknown
                 }
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Lock mode of device"
    ::= { infinity 21 }

    deviceEth1Status OBJECT-TYPE
        SYNTAX INTEGER {
                        offline(1),        -- Not connected
                        online(2),         -- Connected
                        unconfigured(3),   -- Existing but no IP address
                        absent(4),         -- Does not exist
                        unknown(5)         -- Status unknown
                 }
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Status of eth1 interface"
    ::= { infinity 30 }

    deviceEth2Status OBJECT-TYPE
        SYNTAX INTEGER {
                        offline(1),        -- Not connected
                        online(2),         -- Connected
                        unconfigured(3),   -- Existing but no IP address
                        absent(4),         -- Does not exist
                        unknown(5)         -- Status unknown
                 }
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Status of eth2 interface"
    ::= { infinity 40 }

    deviceNetwork OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "Organisational node for data on the KVM network."
        ::= { adderlinkInfinityManager 2 }
        
    numRx OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "The number of Rx devices."
        ::= { deviceNetwork 1 }
        
    numTx OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "The number of Tx devices."
        ::= { deviceNetwork 2 }
        
    numActiveConnexions OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "The number of currently connected Rx devices."
        ::= { deviceNetwork 3 }

    serverState OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "Organisational node for data on the server's current state."
        ::= { adderlinkInfinityManager 3 }
        
    serverCPULoad OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(4..6))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Load average over the last minute ('0.00' to '100.00', 
            where '8.00' is fully loaded)."
        ::= { serverState 1 }
        
    serverMemoryUsage OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(2..4))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Memory usage ('0%' to '100%')."
        ::= { serverState 2 }
        
    serverSoftwareVersion OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(9..12))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "The software version (e.g. '4.3.12345')."
        ::= { serverState 3 }
        
    serverDiskSpace OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(2..4))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "Disk space in use ('0%' to '100%')."
        ::= { serverState 4 }

    events OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "System event data and trap definitions are organised under this 
            node."
        ::= { adderlinkInfinityManager 4 }

    eventList OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "Notification objects are organised under this node."
        ::= { events 0 }

    deviceEthStatusChangedEv NOTIFICATION-TYPE
        OBJECTS
        {
            deviceIndex,
            deviceStatus,
            deviceEth1Status,
            deviceEth2Status
        }
        STATUS current
        DESCRIPTION
            "Sent when a device's eth1 or eth2 status changes."
        ::= { eventList 1 }

    packetLossData OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "Organisational node for data on a receiver head's packet loss."
        ::= { adderlinkInfinityManager 5 }
        
    rxHead OBJECT-TYPE
        SYNTAX BITS {
                        head1(0), -- Video Head 1
                        head2(1)  -- Video Head 2
                 }
        MAX-ACCESS accessible-for-notify
        STATUS current
        DESCRIPTION
            "The video head to which the data apply."
        ::= { packetLossData 1 }
        
    packetsSent OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS accessible-for-notify
        STATUS current
        DESCRIPTION
            "The number of packets sent during the alert window."
        ::= { packetLossData 2 }
        
    packetsDropped OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS accessible-for-notify
        STATUS current
        DESCRIPTION
            "The number of packets dropped during the alert window."
        ::= { packetLossData 3 }

    packetLossEv NOTIFICATION-TYPE
        OBJECTS
        {
            deviceIndex,
            rxHead,
            packetsSent,
            packetsDropped
        }
        STATUS current
        DESCRIPTION
            "Sent when a receiver exceeds the packet-loss threshold within the 
            alert window."
        ::= { eventList 2 }

    conformance OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "Organisational node for Conformance Objects."
        ::= { adderlinkInfinityManager 6 }

    conformanceGroups OBJECT-IDENTITY
        STATUS current
        DESCRIPTION
            "Organisational node for Conformance Groups."
        ::= { conformance 0 }

    notificationsGroup NOTIFICATION-GROUP
        NOTIFICATIONS
        {
            deviceEthStatusChangedEv,
            packetLossEv
        }
        STATUS current
        DESCRIPTION
            "Group of all notification types."
        ::= { conformanceGroups 1 }

    objectsGroup OBJECT-GROUP
        OBJECTS
        {
            deviceIndex,
            deviceType,
            deviceFirmware,
            deviceName,
            deviceIdentifier,
            deviceIP1,
            deviceMAC1,
            deviceIP2,
            deviceMAC2,
            deviceSerialNum,
            deviceStatus,
            deviceLock,
            deviceEth1Status,
            deviceEth2Status,
            numRx,
            numTx,
            numActiveConnexions,
            serverCPULoad,
            serverMemoryUsage,
            serverSoftwareVersion,
            serverDiskSpace,
            rxHead,
            packetsSent,
            packetsDropped
        }
        STATUS current
        DESCRIPTION
            "Group of all object types."
        ::= { conformanceGroups 2 }
     
    serverDetailsTable OBJECT-TYPE
        SYNTAX SEQUENCE OF ServerEntry
        MAX-ACCESS not-accessible
        STATUS current
        DESCRIPTION
            "Table of server details"
        ::=  { adderlinkInfinityManager 7 }

    serverDetails OBJECT-TYPE
        SYNTAX ServerEntry
        MAX-ACCESS not-accessible
        STATUS current
        DESCRIPTION
            "Row definition for server details."
        INDEX { serverId }
    ::= { serverDetailsTable 1 }

    ServerEntry ::= SEQUENCE {
        serverId            Unsigned32,
        serverName          OCTET STRING,
        serverRole          OCTET STRING,
        serverStatus        OCTET STRING,
        serverIP1           OCTET STRING,
        serverMAC1          OCTET STRING,
        serverEth1Enabled   INTEGER,
        serverIP2           OCTET STRING,
        serverMAC2          OCTET STRING
    }
        
    serverId OBJECT-TYPE
        SYNTAX Unsigned32
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "id of servers"
        ::= { serverDetails 1 }

    serverName OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(1..45))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "User-assigned name of server"
        ::= { serverDetails 2 }

    serverRole OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(1..20))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "current role of server"
        ::= { serverDetails 3 }

    serverStatus OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(1..20))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "current status of server"
        ::= { serverDetails 4 }

    serverIP1 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..15))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "IP address of interface eth1"
        ::= { serverDetails 5 }

    serverMAC1 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..17))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "MAC address of interface eth1"
        ::= { serverDetails 6 }

    serverEth1Enabled OBJECT-TYPE
        SYNTAX INTEGER {
                        no(0),
                        dhcp(1),
                        static(2),
                        bonded(3),
                        unknown(4)      -- serverEth1Enabled unknown
                 }
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "status of interface eth1 enable"
        ::= { serverDetails 7 }

    serverIP2 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..15))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "IP address of interface eth2"
        ::= { serverDetails 8 }

    serverMAC2 OBJECT-TYPE
        SYNTAX OCTET STRING(SIZE(0..17))
        MAX-ACCESS read-only
        STATUS current
        DESCRIPTION
            "MAC address of interface eth2"
        ::= { serverDetails 9 }

 
    serverStatusChangedEv NOTIFICATION-TYPE
        OBJECTS
        {
            serverId,
            serverName,
            serverRole,
            serverStatus
        }
        STATUS current
        DESCRIPTION
            "Sent when server changes its status."
        ::= { eventList 3 }
   
END
  adder:
    walk:
      - 1.3.6.1.4.1.25119
      - sysUpTime
    version: 3
    auth:
      username: aim
      security_level: authPriv
      password: password
      auth_protocol: SHA
      priv_protocol: AES
      priv_password: password
    overrides:
      deviceEth1Status:
        type: EnumAsInfo
      deviceEth2Status:
        type: EnumAsInfo
      deviceFirmware:
        type: DisplayString
      deviceIP1:
        type: DisplayString
      deviceIP2:
        type: DisplayString
      deviceIdentifier:
        type: DisplayString
      deviceLock:
        type: EnumAsInfo
      deviceMAC1:
        type: DisplayString
      deviceMAC2:
        type: DisplayString
      deviceName:
        type: DisplayString
      deviceSerialNum:
        type: DisplayString
      deviceStatus:
        type: EnumAsInfo
      deviceType:
        type: DisplayString

Reply via email to