Tutorial: NMIS8, creación de un nuevo modelo

1. Información general

En este tutorial, lo guiaremos a través de la creación de un nuevo modelo para un dispositivo compatible con NMIS 8 y para agregar una nueva métrica.

Lo que aprenderemos

  • Cómo obtener datos útiles para ser utilizados en el modelo.
  • Cómo implementar un nuevo modelo para un dispositivo Net-SNMP.
  • Agregar una nueva métrica.
  • Añadir un nuevo gráfico.

Lo que necesitarás

  • Nuestro Opmantek Virtual Appliance (VM), el cual puede ser descargado de Opmantek.com

2. Configuración del entorno de trabajo


Si aún no lo has hecho. Descargue nuestro version mas reciente del dispositivo virtual de Opmantek.com

Debe importarlo a su virtualizador de preferencia, ejecutar la VM y obtener la dirección IP asignada.

Para este tutorial, mi servidor de NMIS8 está utilizando 192.168.1.100, tenga en cuenta que esta dirección IP puede ser diferente en su configuración.


Debe acceder a la VM a través de SSH para editar los archivos de configuración, las credenciales predeterminadas para la VM son:


username: root
password: NM1$88


Important

Es importante verificar la sintaxis de los archivos editados, recuerde usar: perl -c filename después de guardar los cambios.

Important

La VM de Opmantek tiene habilitado el SNMPv2c de forma predeterminada, la comunidad utilizada en esta VM es: nmisGig8

Esto se puede verificar en el archivo de configuración snmp que se puede encontrar en /etc/snmpd/snmpd.conf

3.Recopilación de datos para el nuevo modelo y la detección del modelo.

Necesitamos tener todas las MIB estándar (IETF / IEEE) y las MIB específicas del proveedor para el dispositivo a modelar, una vez que tengamos las MIB, la mejor manera de interpretar las MIB es ejecutar un SNMPWALK al dispositivo a modelar, para ello, se primero se debe comprobar que el dispositivo este correctamente configurado.

Usualmente utilizaremos la VM de Opmantek para monitorear los dispositivos de nuestra red, pero por simplicidad, la misma VM se utilizara en este tutorial como el dispositivo a modelar, por lo que tendrá 2 roles, de manera predeterminada, el servidor NMIS se monitorea a si mismo y se puede encontrar como el dispositivo localhost.

Primero, debemos realizar un snmpwalk al dispositivo para obtener todos los datos y la métrica del mismo. Necesitamos la "comunidad" o la contraseña para acceder a esta información con éxito, para la VM de Opmantek, la comunidad es: nmisGig8 y la dirección IP para este ejemplo es 192.168.1.100

El comando debe ejecutarse de la siguiente manera:

snmpwalk -v 2c -c nmisGig8 192.168.1.100 .1

Resultado:

SNMPv2-MIB::sysDescr.0 = STRING: Linux Lab_Master 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u2 (2019-11-11) x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (166698) 0:27:46.98
SNMPv2-MIB::sysContact.0 = STRING: Root <root@nmis8> (configure /etc/snmp/snmpd.conf)
SNMPv2-MIB::sysName.0 = STRING: Lab_Master
SNMPv2-MIB::sysLocation.0 = STRING: Unknown (edit /etc/snmp/snmpd.conf)
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
SNMPv2-MIB::sysORID.6 = OID: TCP-MIB::tcpMIB
SNMPv2-MIB::sysORID.7 = OID: IP-MIB::ip
SNMPv2-MIB::sysORID.8 = OID: UDP-MIB::udpMIB
SNMPv2-MIB::sysORID.9 = OID: SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance
SNMPv2-MIB::sysORID.10 = OID: NOTIFICATION-LOG-MIB::notificationLogMIB
SNMPv2-MIB::sysORDescr.1 = STRING: The MIB for Message Processing and Dispatching.
SNMPv2-MIB::sysORDescr.2 = STRING: The management information definitions for the SNMP User-based Security Model.
SNMPv2-MIB::sysORDescr.3 = STRING: The SNMP Management Architecture MIB.
SNMPv2-MIB::sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
SNMPv2-MIB::sysORDescr.5 = STRING: View-based Access Control Model for SNMP.
SNMPv2-MIB::sysORDescr.6 = STRING: The MIB module for managing TCP implementations
SNMPv2-MIB::sysORDescr.7 = STRING: The MIB module for managing IP and ICMP implementations
SNMPv2-MIB::sysORDescr.8 = STRING: The MIB module for managing UDP implementations
SNMPv2-MIB::sysORDescr.9 = STRING: The MIB modules for managing SNMP Notification, plus filtering.
SNMPv2-MIB::sysORDescr.10 = STRING: The MIB module for logging SNMP Notifications.
SNMPv2-MIB::sysORUpTime.1 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.2 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.3 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.4 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.5 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.9 = Timeticks: (7) 0:00:00.07
SNMPv2-MIB::sysORUpTime.10 = Timeticks: (7) 0:00:00.07
IF-MIB::ifNumber.0 = INTEGER: 2
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifDescr.1 = STRING: lo
IF-MIB::ifDescr.2 = STRING: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper)
IF-MIB::ifType.1 = INTEGER: softwareLoopback(24)
IF-MIB::ifType.2 = INTEGER: ethernetCsmacd(6)
IF-MIB::ifMtu.1 = INTEGER: 65536
IF-MIB::ifMtu.2 = INTEGER: 1500
IF-MIB::ifSpeed.1 = Gauge32: 10000000
IF-MIB::ifSpeed.2 = Gauge32: 1000000000
IF-MIB::ifPhysAddress.1 = STRING: 
IF-MIB::ifPhysAddress.2 = STRING: 8:0:27:c4:1f:3f
IF-MIB::ifAdminStatus.1 = INTEGER: up(1)
IF-MIB::ifAdminStatus.2 = INTEGER: up(1)
IF-MIB::ifOperStatus.1 = INTEGER: up(1)
IF-MIB::ifOperStatus.2 = INTEGER: up(1)
IF-MIB::ifLastChange.1 = Timeticks: (0) 0:00:00.00
IF-MIB::ifLastChange.2 = Timeticks: (3927) 0:00:39.27
IF-MIB::ifInOctets.1 = Counter32: 8315005
IF-MIB::ifInOctets.2 = Counter32: 1309639
IF-MIB::ifInUcastPkts.1 = Counter32: 41439
IF-MIB::ifInUcastPkts.2 = Counter32: 15249
IF-MIB::ifInNUcastPkts.1 = Counter32: 0
IF-MIB::ifInNUcastPkts.2 = Counter32: 38
IF-MIB::ifInDiscards.1 = Counter32: 0
--snip--

Info: Para un procesamiento más rápido, puede usar el comando "snmpbulkwalk" en  lugar de "snmpwalk", ya que está optimizado para un mejor rendimiento.


Ahora que sabemos cómo obtener información útil del dispositivo, agreguemos un nuevo modelo de dispositivo a NMIS.

Imaginemos que acabamos de obtener un nuevo servidor Debian 9 (nuestra VM) y necesitamos crear un modelo para este. Para empezar,nos interesa obtener los detalles descritos en SysDescr y SysObjectId.

SNMPv2-MIB::sysDescr.0 = STRING: Linux Lab_Master 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u2 (2019-11-11) x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10

Necesitamos obtener el OID del proveedor del sysObjectID: NET-SNMP-MIB, se puede encontrar usando google. En una búsqueda simple, obtenemos que el OID es: 1.3.6.1.4.1.8072 (https://oidref.com/1.3.6.1.4.1.8072). El código del nodo es: 8072.

El sysDescr: Debian 4.9.189-3 + deb9u2 nos dice que este dispositivo es un Debian 9 con Kernel 4.9.189

En base a esta información, crearemos un modelo.

Primero debemos agregar el Código del nodo a Enterprise.nmis, en este caso el proveedor ya está presente.

/usr/local/nmis8/conf/Enterprise.nmis
  '8071' => {
    'Enterprise' => 'Sandstorm Enterprises, Inc.',
    'OID' => '8071'
  },
  '8072' => {
    'Enterprise' => 'net-snmp',
    'OID' => '8072'
  },
  '8073' => {
    'Enterprise' => 'Lumos Technologies Inc',
    'OID' => '8073'
  },

Luego, actualizamos o agregamos la información relacionada con el dispositivo en /usr/local/nmis8/models/Model.nmis. Usamos la descripción del sysDescr para encontrar el dispositivo que le corresponde.

La sección "net-snmp" en el archivo actualmente se ve así:

/usr/local/nmis8/models/Model.nmis
    'Frogfoot Networks' => {
      'order' => {
        '10' => {
          'Ubiquiti' => 'Linux 2.6.3.'
        },
        '20' => {
          'FrogFoot' => 'Linux'
        }
      }
    },
    'net-snmp' => {
      'order' => {
        '5' => {
          'Checkpoint' => '2.6.18-92cp|2.6.18-92cpx86_64|2.4.21-21cpsmp'
        },
        '10' => {
          'net-snmp' => 'SunOS|Darwin|HP-UX'
        },
        '20' => {
          'net-snmp' => '.'
        }
      }
    },
    'Prime Computer' => {
      'order' => {
        '10' => {
          'net-snmp' => 'Cisco Secure Access Control System'
        }
      }
    },

Agregaremos un nuevo elemento para que coincida con un dispositivo que utiliza el agente net-snmp y tiene un sysDescr que incluye la palabra "Debian". Podríamos ser más específicos y agregar la versión si es necesario, sin embargo, este no es el caso.

Debería verse así ahora:

/usr/local/nmis8/models/Model.nmis
    'Frogfoot Networks' => {
      'order' => {
        '10' => {
          'Ubiquiti' => 'Linux 2.6.3.'
        },
        '20' => {
          'FrogFoot' => 'Linux'
        }
      }
    },
    'net-snmp' => {
      'order' => {
        '5' => {
          'Checkpoint' => '2.6.18-92cp|2.6.18-92cpx86_64|2.4.21-21cpsmp'
        },
        '10' => {
          'net-snmp' => 'SunOS|Darwin|HP-UX'
        },
        '15' => {
          'Debian' => 'Debian'
        },
        '20' => {
          'net-snmp' => '.'
        }
      }
    },
    'Prime Computer' => {
      'order' => {
        '10' => {
          'net-snmp' => 'Cisco Secure Access Control System'
        }
      }
    },

Con estos cambios, nuestro modelo se cargará para el dispositivo.

Ahora probamos si nuestro modelo se ha agregado correctamente y si NMIS lo detecta automáticamente.

En la GUI de NMIS, agregamos el nuevo dispositivo. Ingresamos la comunidad SNMP, IP y un nombre para el dispositivo. Se debe tener en cuenta que el Modelo está seleccionado como "Automático" de forma predeterminada, y lo dejaremos como está.

Hacemos click en "Add and Update" para aplicar los cambios al nuevo nodo. Unos segundos mas trade, NMIS nos mostrara una ventana con los detalles de la operacion ejecutada.

Aquí podemos ver que nuestro modelo ha sido detectado con éxito:

Regresamos a la GUI de NMIS para revisar el nodo creado recientemente.


Aqui vemos que el nodo agregado no parece usar nuestro modelo "Debian", en su lugar vemos que el "nodoModel" en uso es "Model".

Hasta este punto, este es el comportamiento esperado, ya que solo hemos agregado el modelo a ser detectado por NMIS pero no el archivo de modelado a usar, por lo que NMIS usa un modelo generico. Ahora es el momento de crear el archivo del modelo.

4. Implementación del modelo

Preparación del modelo

Como ya habrá notado, hay muchos dispositivos que usan los mismos agentes de snmp, en este ejemplo, los servidores Linux usan NET-SNMP, pero Net-SNMP está disponible para muchos sistemas operativos Unix y similares, también para Microsoft Windows.

Muchos dispositivos ahora usan NET-SNMP como Agente, la mayoría de las veces, es una buena idea copiar un modelo existente y adaptarlo a nuestras necesidades en lugar de crear uno nuevo.

Esta vez copiamos el archivo /usr/local/nmis8/models/Model-net-snmp.nmis actual y lo llamamos Model-Debian.nmis para ajustarlo a nuestras necesidades. Es importante mantener la estructura en el nombre del archivo, ya que esta es la forma en que NMIS encontrará el modelo.

Ahora, trabajaremos con un modelo casi vacío y luego agregaremos algunas secciones, para este propósito tenemos que editar nuestro archivo /usr/local/nmis8/models/Model-Debian.nmis y eliminar todo, excepto la seccion -common-.

/usr/local/nmis8/models/Model-Debian.snmp
%hash = (
  '-common-' => {
    'class' => {
      'database' => {
        'common-model' => 'database'
      },
      'event' => {
        'common-model' => 'event'
      },
      'heading' => {
        'common-model' => 'heading'
      },
      'software' => {
        'common-model' => 'software'
      },
      'stats' => {
        'common-model' => 'stats'
      },
      'summary' => {
        'common-model' => 'summary'
      },
      'threshold' => {
        'common-model' => 'threshold'
      }
    }
  }
);


Veamos el resultado de usar este modelo. Necesitamos ejecutar un “Update” del dispositivo y luego actualizarla vista del nodo en la GUI de NMIS. Para ejecutar el “update” manua, debemos acceder via ssh a la VM y ejecutar:

/usr/local/nmis8/bin/nmis.pl type=update node="Debian9 Opmantek VM" debug=1

Y la vista actualizada debería verse así:

Construcción del modelo

Tenemos la necesidad de agregar nuevas métricas a nuestro modelo. En este caso estamos interesados en agregar el "Linux system load". Su tabla está representada con el oid: 1.3.6.1.4.1.2021.10.1 (https://oidref.com/1.3.6.1.4.1.2021.10.1)

Veamos qué datos obtenemos usando snmpwalk en ese OID.

❯ snmpwalk -v 2c -c nmisGig8 192.168.1.100 1.3.6.1.4.1.2021.10.1

UCD-SNMP-MIB::laIndex.1 = INTEGER: 1
UCD-SNMP-MIB::laIndex.2 = INTEGER: 2
UCD-SNMP-MIB::laIndex.3 = INTEGER: 3
UCD-SNMP-MIB::laNames.1 = STRING: Load-1
UCD-SNMP-MIB::laNames.2 = STRING: Load-5
UCD-SNMP-MIB::laNames.3 = STRING: Load-15
UCD-SNMP-MIB::laLoad.1 = STRING: 0.02
UCD-SNMP-MIB::laLoad.2 = STRING: 0.04
UCD-SNMP-MIB::laLoad.3 = STRING: 0.04
UCD-SNMP-MIB::laConfig.1 = STRING: 12.00
UCD-SNMP-MIB::laConfig.2 = STRING: 12.00
UCD-SNMP-MIB::laConfig.3 = STRING: 12.00
UCD-SNMP-MIB::laLoadInt.1 = INTEGER: 2
UCD-SNMP-MIB::laLoadInt.2 = INTEGER: 4
UCD-SNMP-MIB::laLoadInt.3 = INTEGER: 4
UCD-SNMP-MIB::laLoadFloat.1 = Opaque: Float: 0.020000
UCD-SNMP-MIB::laLoadFloat.2 = Opaque: Float: 0.040000
UCD-SNMP-MIB::laLoadFloat.3 = Opaque: Float: 0.040000
UCD-SNMP-MIB::laErrorFlag.1 = INTEGER: noError(0)
UCD-SNMP-MIB::laErrorFlag.2 = INTEGER: noError(0)
UCD-SNMP-MIB::laErrorFlag.3 = INTEGER: noError(0)
UCD-SNMP-MIB::laErrMessage.1 = STRING: 
UCD-SNMP-MIB::laErrMessage.2 = STRING: 
UCD-SNMP-MIB::laErrMessage.3 = STRING:

Listo, estamos interesados en los valores "laLoad", laLoad.1 (1.3.6.1.4.1.2021.10.1.3.1) y laLoad.2 (1.3.6.1.4.1.2021.10.1.3.2) para ser más exactos. En otras palabras, queremos trabajar con "1 Minute Load" y "5 Minutes Load" por ahora.

Con estos detalles podemos comenzar a construir nuestro modelo. Primero tenemos que agregar una nueva secciónbajo la sección -common- y nombrarla "system". Dentro de la sección “system” crearemos 2 secciones más, las secciones "rrd" y "sys".

Debe verse asi:

%hash = (
  '-common-' => {
    'class' => {
      'database' => {
        'common-model' => 'database'
      },
      'event' => {
        'common-model' => 'event'
      },
      'heading' => {
        'common-model' => 'heading'
      },
      'software' => {
        'common-model' => 'software'
      },
      'stats' => {
        'common-model' => 'stats'
      },
      'summary' => {
        'common-model' => 'summary'
      },
      'threshold' => {
        'common-model' => 'threshold'
      }
    }
  },
  'system' => {
    'rrd' => {

      },
    },
    'sys' => {

      },
    }
  },
);


Ahora, dentro de las secciones rrd y sys, agregaremos la sección del elemento "laload", el nombre usado en esta sección es importante ya que mantendrá una relación entre el modelo y la base de datos donde se almacenan los datos. Dentro de la sección "laload" agregaremos la sección "snmp".

--snip--
  'system' => {
    'rrd' => {
      'laload' => {
        'snmp' => {

        }
      },
    },
    'sys' => {
      'laLoad' => {
        'snmp' => {

        }
      },
    }
  },
--snip--

Ahora agregamos la sección de elementos que queremos modelar, como decidimos antes, será laLoad1 y laLoad2. Una vez más, el nombre de los elementos es importante, ya que esta es el “Data Source” o DS en nuestra base de datos (archivo RRD). Necesitamos agregar el elemento "oid" para cada elemento. El oid debe ser el OID numérico snmp o un OID previamente mapeado (veremos esta opción más adelante). En este caso usaremos el OID numérico.

--snip--
  'system' => {
    'rrd' => {
      'laload' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1',
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2',
          }
        }
      },
    },
    'sys' => {
      'laLoad' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2'
          }
        }
      },
    }
  },
--snip--

Para la sección “rrd” necesitamos especificar el tipo de datos y el rango que se guardará en el archivo RRD. Para esto tenemos que usar el elemento "opción", que indica si es un contador o un medido (counter o gauge), y los límites de valor inferior y superior, siendo "U" equivalente a Ilimitado o “Unlimited”.

En este caso es un medidor o "gauge", y el rango de valores comienza desde 0, por lo que usaremos: 'option' => 'gauge, 0: U'.

--snip--
  'system' => {
    'rrd' => {
      'laload' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1',
            'option' => 'gauge,0:U'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2',
            'option' => 'gauge,0:U'
          }
        }
      },
    },
    'sys' => {
      'laLoad' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2'
          }
        }
      },
    }
  },
--snip--

Por ahora agregaremos el elemento 'no_graphs' => '1' a la sección rrd. Este elemento u opción indica que no vamos a utilizar un gráfico con los datos recopilados. Cambiaremos esta opción mas adelante, pero hasta ahora esto es lo que necesitamos para comenzar a probar nuestra implementación antes de pasar a los gráficos.

--snip--
  'system' => {
    'rrd' => {
      'laload' => {
        'no_graphs' => '1',
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1',
            'option' => 'gauge,0:U'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2',
            'option' => 'gauge,0:U'
          }
        }
      },
    },
    'sys' => {
      'laLoad' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2'
          }
        }
      },
    }
  },
--snip--

Antes de probar nuestra implementación, debemos agregar los detalles de la base de datos a utilizar para almacenar los datos obtenidos. Para esto, necesitamos editar el archivo /usr/local/nmis8/models/Common-database.nmis y agregarle la referencia. El nombre debe coincidir exactamente con el nombre utilizado en la sección rrd del modelo. El lado derecho debe indicar dónde se guardará el rrd y su nombre.

--snip--
      'jnxOperations' => '/nodes/$node/health/jnxOperations-$index.rrd',
      'jnxSourceClassUsage' => '/nodes/$node/health/jnxSCUstats-$index.rrd',
    'laload' => '/nodes/$node/health/laload.rrd',
      'memUsageUtil' => '/nodes/$node/health/mem-$index.rrd',
      'memUtil' => '/nodes/$node/health/mem.rrd',
--snip--

Ahora ya podemos probarlo, ejecutando un "update" y un "collect" utilizando las opciones “debug” y “model”:

$ /usr/local/nmis8/bin/nmis.pl type=update node="Debian9 Opmantek VM" debug=1
$/usr/local/nmis8/bin/nmis.pl type=collect node="Debian9 Opmantek VM" debug=1 force=true model=true	

En esta etapa, estamos interesados en el resultado del "Collect". Nos dara información relacionada con las secciones que estamos modelando. Como podemos ver aquí, obtuvimos la información correcta para laLoad1 y laLoad5 y los datos se guardaron con éxito en la base de datos RRD.

21:45:29 getValues, wanted section=, now handling section=laLoad
21:45:29 getValues, class: index= port= suffix=
21:45:29 getValues, loaded 2 values, status: ok
MODEL loadInfo Debian9 Opmantek VM class=system:
  :  oid=1.3.6.1.4.1.2021.10.1.3.2 name=laLoad5 value=0.20
  :  oid=1.3.6.1.4.1.2021.10.1.3.1 name=laLoad1 value=0.30
21:45:29 updateNodeInfo, sysUpTime: Old=5:06:48 New=5:06:48
21:45:29 checkPIX, Starting
21:45:29 checkPIX, Finished
MODEL Debian9 Opmantek VM: nodedown=false sysUpTime=5:06:48 sysObjectID=1.3.6.1.4.1.8072.3.2.10
21:45:29 updateNodeInfo, Finished with exit=1
MODEL Debian9 Opmantek VM: role=core type= sysObjectID=1.3.6.1.4.1.8072.3.2.10 sysObjectName=_linux
MODEL Debian9 Opmantek VM: sysDescr=Linux Lab_Master 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u2 (2019-11-11) x86_64
MODEL Debian9 Opmantek VM: vendor=net-snmp model=Debian interfaces=2
21:45:29 getNodeData, Starting Node get data, node Debian9 Opmantek VM
21:45:29 getData, index= port= class=system section=
21:45:29 getValues, wanted section=, now handling section=laload
21:45:29 getValues, class: index= port= suffix=
21:45:29 getValues, loaded 2 values, status: ok
MODEL getData Debian9 Opmantek VM class=system:
  section=laload index= port=
    oid=1.3.6.1.4.1.2021.10.1.3.1 name=laLoad5 value=0.30
    oid=1.3.6.1.4.1.2021.10.1.3.1 name=laLoad1 value=0.30
21:45:29 updateRRD, Starting RRD Update Process, type=laload, index=, item=
21:45:29 getFileName, filename of type=laload is /usr/local/nmis8/database/nodes/debian9 opmantek vm/health/laload.rrd
21:45:29 updateRRD, database /usr/local/nmis8/database/nodes/debian9 opmantek vm/health/laload.rrd exists and is R/W
21:45:29 updateRRD, DS laLoad5:laLoad1, 2
21:45:29 updateRRD, value N:0.30:0.30, 16 bytes
21:45:29 getNodeData, Finished

Construcción de la gráfica

Hasta ahora hemos recopilado los datos del dispositivo y los hemos almacenado en nuestra base de datos, ahora debemos mostrar esos datos de manera útil a través de un gráfico.

Necesitamos especificar el gráfico en nuestro modelo, habiamos usado la opción 'no_graphs' => '1' para indicar que no queríamos un gráfico, ahora tenemos que reemplazar esta opción con: 'graphtype' => 'laload' , donde "laload" es el nombre del gráfico que usaremos, por lo que el nombre de archivo de nuestro gráfico debe ser: /usr/local/nmis8/models/Graph-laload.nmis

--snip--
  'system' => {
    'rrd' => {
      'laload' => {
        'graphtype' => 'laload'
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1',
            'option' => 'gauge,0:U'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2',
            'option' => 'gauge,0:U'
          }
        }
      },
    },
    'sys' => {
      'laLoad' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2'
          }
        }
      },
    }
  },
--snip--

Ahora, creemos el archivo /usr/local/nmis8/models/Graph-laload.nmis. y agregue los siguientes detalles:

%hash = (
	'title' => {

	},
	'vlabel' => {

	},
	'option' => {

	}
);

Como podemos ver aquí, el gráfico necesita algunos elementos básicos para ser construido. Una sección de título (title), una etiqueta (vlabel) y las opciones (option). Para el título debemos tener un título para la versión estándar (standard) y para la versión corta (short). Esto es estándar en todos los gráficos y cualquier otro gráfico que incluye NMIS puede usarse como referencia. La etiqueta tiene una descripción del gráfico y las opciones también se dividen en 2 secciones: "stadard" y "small", en esta sección donde definimos el gráfico en sí.

%hash = (
	'title' => {
		'standard' => '$node - $length from $datestamp_start to $datestamp_end',
		'short' => '$node - $length'
	},
	'vlabel' => {
		'standard' => 'Load Average'
	},
	'option' => {
		'standard' => [],
		'small' => []
	}
);

Aquí tenemos el gráfico completado. Explicaré los detalles a continuación.

%hash = (
	'title' => {
		'standard' => '$node - $length from $datestamp_start to $datestamp_end',
		'short' => '$node - $length'
	},
	'vlabel' => {
		'standard' => 'Load Average'
	},
	'option' => {
		'standard' => [
			'DEF:laLoad1=$database:laLoad1:AVERAGE',
			'LINE1:laLoad1#00BFFF:Load Average 1 Min',                        
			'GPRINT:laLoad1:MIN:Minimum %1.2lf',
			'GPRINT:laLoad1:AVERAGE:Avg %1.2lf',
			'GPRINT:laLoad1:MAX:Max %1.2lf\\n',


			'DEF:laLoad5=$database:laLoad5:AVERAGE',
			'LINE1:laLoad5#00FF7F:Load Average 5 Min',                        
			'GPRINT:laLoad5:MIN:Minimum %1.2lf',
			'GPRINT:laLoad5:AVERAGE:Avg %1.2lf',
			'GPRINT:laLoad5:MAX:Max %1.2lf\\n',
		],
		'small' => [
			'DEF:laLoad1=$database:laLoad1:AVERAGE',
			'DEF:laLoad5=$database:laLoad5:AVERAGE',
			'LINE1:laLoad1#00BFFF:Load Average 1 Min',                        
			'GPRINT:laLoad1:AVERAGE:Avg %1.2lf\\n',
			'LINE1:laLoad5#00FF7F:Load Average 5 Min',                        
			'GPRINT:laLoad5:AVERAGE:Avg %1.2lf\\n',
		]
	}
);

Examinemos la primera línea dentro de "option-> standard" para comprender cuál es el significado de cada término.

DEF:laLoad1=$database:laLoad1:AVERAGE

DEF:<vname>=<rrdfile>:<ds-name>:<CF>

vname: variable interna donde se almacenarán los datos del RRD, en nuestro caso: "laLoad1".

rrdfile: el RRD donde se almacenan los datos, en nuestro caso: $database (ya definido en Common-database.nmis).

ds-name: el nombre del origen de datos utilizado para almacenar datos particulares en el RRD, en nuestro caso "laLoad1".

CF: La función de consolidación puede ser AVERAGE, MINIMUM, MAXIMUM, o LAST, en nuestro caso: "AVERAGE".

El ds-name(RouteNumber) debe ser exactamente el mismo que el nombre dado a la variable asignada en el modelo ("sistema -> rrd -> nodehealth -> snmp").


El siguiente elemento define el tipo de trazado que se realizará con los datos.

LINE1:laLoad1#00BFFF:Load Average 1 Min

LINE:valor[#color]:[leyenda] 

LINE1: Tipo de trazado, en nuestro caso: Linea

Valor: Variable que contiene el valor, en nuestro caso: load value.

#color: Valor de color hexadecimal, en nuestro caso: # 00BFFF.

Leyenda: la leyenda asociada al valor.

Las dos últimas líneas son similares, son los valores calculados que se muestran como parte de la leyenda.

Básicamente, el gráfico se define en función del sistema de gráficos de la herramienta RRD y puede encontrar información adicional y opciones avanzadas aquí:  https://oss.oetiker.ch/rrdtool/doc/rrdgraph.en.html


Ahora que tenemos el gráfico construido, necesitamos agregarlo a la sección del sistema para que se muestre de la siguiente manera:

--snip--
  'system' => {
    'nodegraph' => 'laload',
    'rrd' => {
      'laload' => {
        'graphtype' => 'laload'
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1',
            'option' => 'gauge,0:U'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2',
            'option' => 'gauge,0:U'
          }
        }
      },
    },
    'sys' => {
      'laLoad' => {
        'snmp' => {
          'laLoad1' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.1'
          },
          'laLoad5' => {
            'oid' => '1.3.6.1.4.1.2021.10.1.3.2'
          }
        }
      },
    }
  },
--snip--


Una vez más, realizamos un "Update" y un "Collect", luego actualizamos la vista de nodo en NMIS y podremos ver nuestro gráfico.