Checkmk
to checkmk.com
Important

This is a machine translation based on the English version of the article. It might or might not have already been subject to text preparation. If you find errors, please file a GitHub issue that states the paragraph that has to be improved.

1. Introducción

Una ventaja importante de Checkmk en comparación con otros sistemas de monitorización es el gran número de plugins de comprobación bien mantenidos que se suministran de serie. Para que estos plugins tengan una calidad uniformemente alta, existen criterios estandarizados que cada plugin debe cumplir.

Una nota importante en relación con los criterios: no dé por sentado simplemente que todos los Plugin suministrados con Checkmk se ajustan a todos los estándares actuales. Evite copiar y pegar. Es más aconsejable orientar su trabajo según la información de este artículo.

Si desarrolla Plugin únicamente para su propio uso, por supuesto es totalmente libre y no está sujeto a nuestras normas.

1.1. Calidad

Para los check plugins que son componentes oficiales de Checkmk, o que se planea que lo sean, se exige una mayor calidad en comparación con los escritos "para su propio uso". Esta expectativa se aplica a su calidad "externa" (tal y como la ve el usuario), así como a su calidad interna (la legibilidad del código, etc.).

Por favor, codifique el Plugin correctamente y con el máximo nivel de calidad posible.

1.2. Alcance de un check plugin

Cada check plugin debe incluir como mínimo los siguientes componentes:

  • El propio check plugin.

  • Una página de manual.

  • Los Plugin con parámetros de check requieren una definición del conjunto de reglas aplicable.

  • Definicionesmétricas para gráficos y el Perf-O-Meter si el check produce datos métricos.

  • Una definición para el Agent bakery si está presente un plugin de agente.

  • Una serie de ejemplos completos y diversos de las salidas de los agentes, o respectivamente paseos SNMP.

2. Convenciones de nomenclatura

2.1. 2.1. Nombre del plugin check

Elegir un nombre para un Plugin es especialmente crítico ya que este nombre no puede ser alterado posteriormente.

  • El nombre de un plugin debe ser corto, suficientemente explícito y comprensible. Ejemplo: firewall_status sólo es un buen nombre si el plugin funciona para todos, o al menos para muchos cortafuegos.

  • Un nombre se compone de letras minúsculas y números. Se permite un guión bajo como separador.

  • Las palabras status o state son innecesarias en un nombre, ya que, por supuesto, cada plugin monitoriza un estado. Lo mismo se aplica a la palabra superflua current. Por lo tanto, en lugar de foobar_current_temp_status utilice simplemente foobar_temp.

  • Los check plugins en los que el item representa una cosa física (por ejemplo, ventilador, fuente de alimentación), deben tener un nombre en singular- por ejemplo, casa_fan, oracle_tablespace. Los check plugins en los que cada item se refiere a un número o múltiplos deben nombrarse usando un plural - por ejemplo, user_logins, printer_pages.

  • Los check plugins específicos de un producto deben ir precedidos del nombre del producto - por ejemplo, oracle_tablespace.

  • Los check plugins específicos de un fabricante que no se apliquen a un producto concreto deben ir precedidos de la abreviatura del fabricante; por ejemplo, fsc_ para Fujitsu Siemens Computers.

  • Los plugins de comprobación basados en SNMP que utilicen un componente común de la MIB y que puedan ser soportados por más de un fabricante deben llevar el nombre de la MIB, en lugar del nombre del fabricante - por ejemplo, los plugins de comprobación hr_*.

2.2. 2.2. Nombre del servicio

  • Utilice abreviaturas comunes y bien definidas (por ejemplo, CPU, DB, VPN, IO,...).

  • Escriba las abreviaturas en mayúsculas.

  • Utilice mayúsculas y minúsculas (por ejemplo, CPU utilization, no Cpu Utilization) - los nombres propios son una excepción.

  • Escriba los nombres de los productos tal y como los defina el proveedor (por ejemplo, vSphere).

  • Utilice el inglés americano (por ejemplo, utilization, no utilisation).

  • Por ejemplo, todos los servicios de interfaz utilizan la plantilla Interface %s.

  • Intente ser breve y mantenga las descripciones cortas, ya que los nombres del servicio se truncan en los dashboards, vistas e informes si son demasiado largos.

2.3. Nombres de métricas

  • Las métricas para las que ya existe una definición significativa deben reutilizarse.

  • En caso contrario, se aplicarán reglas similares a las utilizadas para los nombres de los check plugins (específico del producto, específico del fabricante, etc.).

2.4. Nombre del conjunto de reglas de check

Se aplica la misma convención que con las métricas.

3. 3. Creación de un check plugin

3.1. Estructura general

El archivo Python real bajo ~/share/check_mk/checks/ debe tener la siguiente estructura (cumpliendo con la secuencia de codificación):

  1. Una cabecera de archivo con un aviso GPL.

  2. El nombre y dirección de correo electrónico del autor original si el Plugin no ha sido desarrollado por el proyecto Checkmk.

  3. Una breve muestra de la salida del agente.

  4. Valores por defecto para los parámetros de check (factory_settings).

  5. Funciones auxiliares, si están disponibles.

  6. La función parse, si está disponible.

  7. La función de descubrimiento.

  8. La función check.

  9. La declaración check_info.

3.2. Directrices de codificación

Autor

Si el Plugin no ha sido desarrollado por el equipo de Checkmk, el nombre y la dirección de correo electrónico del autor deben codificarse directamente después de la cabecera del archivo.

Legibilidad

  • Evite las líneas de código largas: la longitud máxima permitida es de 100 caracteres.

  • En cada caso la sangría es de cuatro caracteres en blanco - no utilice pestañas.

  • Oriéntese al estándar PEP 8 de Python.

Muestra de la salida de un agente

Incluir una muestra de la salida de un agente simplifica enormemente la lectura del código. Al hacerlo es importante incluir varias posibles salidas en la muestra. No haga la muestra más larga de lo necesario. Con chequeos basados en SNMP proporcione un paseo SNMP:

 Example excerpt from SNMP data:
 .1.3.6.1.4.1.2.3.51.2.2.7.1.0  255
 .1.3.6.1.4.1.2.3.51.2.2.7.2.1.1.1  1
 .1.3.6.1.4.1.2.3.51.2.2.7.2.1.2.1  "Good"
 .1.3.6.1.4.1.2.3.51.2.2.7.2.1.3.1  "No critical or warning events"
 .1.3.6.1.4.1.2.3.51.2.2.7.2.1.4.1  "No timestamp"

Si, por ejemplo, se producen diferentes formatos de salida debido a diferentes versiones de firmware en los dispositivos de destino, entonces se debe proporcionar un ejemplo que indique la versión para cada uno. Un buen ejemplo de este caso se puede encontrar en el plugin de check multipath.

MIB de SNMP

Al definir snmp_info, debe indicarse en los comentarios la ruta legible al OID. Ejemplo:

    'snmp_info' : (".1.3.6.1.2.1.47.1.1.1.1", [
        OID_END,
        "2",    # ENTITY-MIB::entPhysicalDescription
        "5",    # ENTITY-MIB::entPhysicalClass
        "7",    # ENTITY-MIB::entPhysicalName
    ]),

Uso de lambda

Evite expresiones complejas con lambda. Se permite lambda en la función de escaneo lambda oid: …​, y cuando desee invocar funciones existentes con sólo un argumento alterado - por ejemplo:

     "inventory_function" : lambda info: inventory_foobar_generic(info, "temperature")

Iteración de los datos del agente SNMP

Con los checks que analizan los datos SNMP, no se debe utilizar un índice como éste:

    for line in info:
        if line[1] != '' and line[0] ...

Es mejor descomprimir cada línea como variables significativas:

    for *sensor_id, state_state, foo, bar* in info:
        if sensor_state != '1' and sensor_id ...

Funciones de análisis sintáctico

Utilice siempre funciones de análisis sintáctico cuando el análisis sintáctico de la salida de un agente no sea trivial. El argumento de la función de análisis sintáctico debe llamarse siempre info, y en las funciones de descubrimiento y comprobación el argumento debe llamarse parsed en lugar de info. De esta forma, el lector tendrá claro que este resultado procede de una función de análisis sintáctico.

Check con varios resultados parciales

Un check que produzca múltiples resultados parciales -por ejemplo, asignaciones actuales y crecimiento- debe devolverlos con yield. Los checks que produzcan un único resultado deben utilizar return.

    if "abs_levels" in params:
        warn, crit = params["abs_levels"]
        if value >= crit:
            yield 2, "...."
        elif value >= warn:
            yield 1, "...."
        else:
            yield 0, "..."

    if "perc_levels" in params:
        warn, crit = params["perc_levels"]
        if percentage >= crit:
            yield 2, "...."
        elif percentage >= warn:
            yield 1, "...."
        else:
            yield 0, "..."

Los marcadores (!) y (!!) son obsoletos y ya no pueden utilizarse. Deben sustituirse por yield.

Claves en check_info[…​]

Almacene en check_info únicamente las claves que vaya a utilizar en su entrada. Las únicas entradas obligatorias son "service_description" y "check_function". Introduzca "has_perfdata" y otras claves con valores booleanos únicamente si su valor es True.

3.3. Plugins de agente

Si su check plugin requiere un plugin de agente, tenga en cuenta las siguientes reglas:

  • Almacene el Plugin en ~/share/check_mk/agents/plugins para sistemas de tipo de Unix, y establezca los derechos de ejecución en 755.

  • En Windows, el directorio se llama ~/share/check_mk/agents/windows/plugins.

  • Los scripts shell y Python no deben tener extensión de nombre de archivo (omita .sh y .py).

  • Utilice #!/bin/sh en la primera línea de los script shell. Utilice #!/bin/bash sólo si se requieren funciones de Bash.

  • Utilice la cabecera estándar del archivo Checkmk con el aviso GPL.

  • Su Plugin no debe dañar el sistema de destino, especialmente si el Plugin no está realmente soportado por el sistema.

  • No olvide la referencia al Plugin en la página man del check plugin.

  • Si el componente que el Plugin debe monitorizar no existe realmente en el sistema, el Plugin no debe mostrar un título de la sección.

  • Si el Plugin requiere un archivo de configuración, éste debe buscarse (en Linux) en el directorio $MK_CONFDIR, y el archivo debe tener el mismo nombre que el Plugin - aparte de la extensión .cfg, y sin un posible prefijo mk_. El procedimiento es similar para Windows - el directorio en Windows es %MK_CONFDIR%.

  • No codifique Plugin para Windows en PowerShell, ya que no es portable y, en cualquier caso, consume muchos recursos. Utilice VBScript.

  • No codifique Plugin en Java.

3.4. No hacer

  • No utilice import en su archivo check plugin. Todos los módulos Python permitidos ya han sido importados.

  • No utilice datetime para analizar y calcular las especificaciones de tiempo - utilice time. Éste puede realizar todas las tareas necesarias. ¡En serio!

  • Los argumentos que reciben sus funciones no deben modificar de ninguna manera las funciones. Esto se aplica especialmente para params y info.

  • Si realmente quieres trabajar con expresiones regulares (¡son lentas!), invócalas con la función regex() - no uses re directamente.

  • ¡Naturalmente no está permitido usar print, o enrutar salidas a stdout, o comunicarse con el mundo exterior de ninguna manera!

  • La función de escaneo SNMP no está autorizada a recuperar otros OIDs que no sean .1.3.6.1.2.1.1.1.0 y .1.3.6.1.2.1.1.2.0. Excepción: la función de escaneo SNMP se ha asegurado previamente, mediante el check de uno de estos dos OIDs, de que sólo se recuperen otros OIDs de un número estrictamente limitado de dispositivos.

4. 4. Check plugin behavior

4.1. 4.1. Excepciones

Su check plugin no debería, sino que siempre debe asumir que la salida de un agente es sintácticamente válida. En ningún caso se permite al plugin intentar manejar situaciones de error desconocidas en la propia salida.

¿Por qué es así? Checkmk tiene una función muy refinada para manejar automáticamente este tipo de errores. Para el usuario puede generar completos informes de fallos, y también establece el estado del Plugin en UNKNOWN. Esto es mucho más útil que si el check, por ejemplo, simplemente produce un unknown SNMP code 17.

La función de descubrimiento, parse y/o check debería generalmente introducir una excepción si la salida del agente no está en el formato definido y conocido para el que se desarrolló el Plugin.

4.2. saveint() y savefloat()

Las funciones saveint() y savefloat() convierten una cadena en int o float y producen un 0 si la cadena no puede convertirse (por ejemplo, es una cadena vacía).

Utilice estas funciones sólo si el valor vacío o inválido es una condición conocida; de lo contrario, se suprimirán mensajes de error importantes (véase más arriba).

4.3. Item no encontrado

Un check que no encuentra un item que está siendo monitorizado debería simplemente producir un None, y no generar su propio mensaje de error. En tal caso Checkmk producirá un mensaje de error estandarizado y consistente, y establecerá el servicio como UNKNOWN.

4.4. Umbrales

Muchos plugins de check tienen parámetros que definen umbrales para métricas específicas y, por tanto, determinan cuándo el check asume un estado WARN o CRIT. Tenga en cuenta las siguientes reglas que garantizan que Checkmk reaccione de forma coherente:

  • Los umbrales para WARN y CRIT deben verificarse siempre con >= y <=. Ejemplo: un Plugin monitoriza la longitud de la cola de correo. El límite superior crítico es 100. Esto significa que si el valor real es '100', ¡ya es crítico!

  • Si sólo hay umbrales superiores o inferiores (los casos más comunes), los campos de entrada del conjunto de reglas deben codificarse con Warning at y Critical at.

  • Si hay umbrales superiores e inferiores, la codificación debe ser la siguiente: Warning at or above, Critical at or above, Warning at or below y Critical at or below.

4.5. Salida del check plugin

Cada check produce una línea de texto: la salida del plugin. Para conseguir un comportamiento coherente para todos los plugins, se aplican las siguientes reglas:

  • Para mostrar valores medidos, exactamente un carácter en blanco debe separar el valor y la unidad (p. ej. 17.4 V). La única excepción a esta regla es con %, donde no hay ningún espacio en blanco: 89.5%.

  • En las listas de valores medidos, el nombre del valor con mayúscula inicial va seguido de dos puntos. Ejemplo: Voltage: 24.5 V, Phase: negative, Flux-Compensator: operational

  • No muestre claves internas, palabras clave, SNMP-internas u otra basura en las salidas de Plugin que no sea de utilidad para el usuario. Utilice términos significativos y legibles para el ser humano. Utilice términos que el usuario espere normalmente. Ejemplo: Utilice route monitor has failed en lugar de routeMonitorFail.

  • Si el item de check tiene una especificación adicional, codifíquela entre corchetes al principio de la salida (por ejemplo Interface 2 - [eth0] …​).

  • En las listas, los items se separan por comas, y los items siguientes llevan mayúsculas iniciales: Swap used: …​, Total virtual memory used: …​

4.6. Umbrales por defecto

Todo Plugin que trabaje con umbrales debe tener definidos unos valores por defecto significativos para los umbrales. Se aplican las siguientes reglas:

  • Los umbrales por defecto utilizados en el check deben definirse también 1:1 como parámetros por defecto en el conjunto de reglas aplicable.

  • Los umbrales por defecto deben definirse en factory_settings (si el check tiene un diccionario como parámetro).

  • Los umbrales por defecto deben seleccionarse sobre una base técnicamente sólida: ¿Existe una especificación del fabricante? ¿Existen mejores prácticas?

  • Es esencial que la fuente de los umbrales esté documentada en el check.

4.7. Nagios vs. CMC

Asegúrese de que su check también funciona con un núcleo de monitorización Nagios. Suele ser el caso automáticamente, pero no siempre.

5. Métrica

5.1. Formatos para métricas

  • El plugin check plugin siempre devuelve datos métricos como int o float. No se permiten cadenas.

  • Si desea emitir la séxtuple de un campo de valor métrico, utilice None en su posición. Ejemplo: [("taple_util", utilization, None, None, 0, size)]

  • Si no necesita la entrada al final, simplemente acorte la tupla. No utilice None al final.

5.2. Nomenclatura de las métricas

  • Los nombres de las métricas se componen de letras minúsculas y guiones bajos. Los números están permitidos, pero no en cabeza.

  • Los nombres de las métricas deben ser, como en el caso de los check plugins, cortos y específicos. Las métricas que vayan a ser utilizadas por varios plugins deben tener nombres genéricos.

  • Evite utilizar la palabra de relleno sin sentido current. El valor medido es siempre el actual.

  • La métrica debe llamarse como la "cosa", no como la unidad de medida. Así, por ejemplo, current en lugar de ampere, o size en lugar de bytes.

Importante: utilice siempre el tamaño canónico. ¡En serio! Checkmk escala los datos en sí según convenga. Ejemplos:

Tipo de medida Unidad canónica

Duración

Segundos

Tamaño del archivo

Bytes

Temperatura

Celsius

Rendimiento de la red

Octetos por segundo (no Bits/s)

Valor porcentual

Un valor de 0 a 100 (no de 0,0 a 1,0)

Eventos por periodo de tiempo

1 por segundo

Rendimiento eléctrico

Vatios (no mW)

5.3. Indicador de datos métricos

Establezca "has_perfdata" en check_info a True sólo si el check emite realmente datos métricos (o puede emitirlos).

5.4. Definición de gráfico y Perf-O-Meter

Las definiciones para gráficos deben ser como las definiciones en ~/web/plugins/metrics/check_mk.py. No cree definiciones para gráficos PNP. En Raw Edition también se generarán sobre la base de las definiciones métricas en el propio Checkmk.

6. Definición del conjunto de reglas

6.1. Nombre del grupo de check

Los check plugin con parámetros requieren obligatoriamente la definición de un conjunto de reglas. La conexión entre un plugin y un conjunto de reglas se realiza a través del grupo de chequeo (la entrada "group" en check_info). Todos los chequeos configurados con el mismo conjunto de reglas se consolidan a través del grupo.

Si su Plugin debe configurarse sensatamente con un conjunto de reglas existente, utilice también un grupo existente.

Si su Plugin es tan específico que en cualquier caso requiere su propio grupo, entonces cree un grupo propio para él donde el nombre del grupo debe hacer referencia al Plugin.

Si es previsible que en el futuro otros Plugins puedan utilizar el mismo conjunto de reglas, utilice un nombre genérico apropiado.

6.2. Valores por defecto para ValueSpecs

Cuando defina sus definiciones de parámetros(ValueSpecs), utilice exactamente los mismos valores por defecto que los utilizados realmente en los checks (si es posible).

Ejemplo: si sin una regla el check asume el umbral (5, 10) para WARN y CRIT, entonces el ValueSpec debe definirse de tal forma que 5 y 10 se ofrezcan automáticamente como umbrales.

6.3. Elección de ValueSpecs

Para algunos tipos de datos existen ValueSpecs especializados. Un ejemplo es Age para un determinado número de segundos. Éste debe utilizarse siempre que sea apropiado. No utilice, por ejemplo, Integer en tal caso.

7. Archivos de inclusión

Para una serie de tipos de check existen implementaciones ya preparadas en archivos include, que no sólo pueden utilizarse, sino que deben utilizarse. Los archivos include importantes son:

temperature.include

Monitorización de temperaturas

elphase.include

Fases eléctricas de CA (por ejemplo, en USV)

fan.include

Ventiladores

if.include

Interfaces de red

df.include

Niveles del sistema de archivos

mem.include

Monitorización de RAM (almacenamiento principal)

ps.include

Procesos del sistema operativo

Importante: utilice los archivos de inclusión existentes sólo si han sido diseñados para el propósito en cuestión, y no simplemente porque se ajustan de forma aproximada.

8. Páginas man

Cada check plugin debe tener una página man. Si ha programado varios plugins en un archivo check plugin, cada uno de ellos debe tener, por supuesto, su propia página man.

Aquí no se trata de documentar lo que has programado, sino de dar al usuario la información útil que necesita.

Una página man debe ser

  • completa,

  • precisa,

  • breve,

  • útil.

Una página de manual consta de varias secciones, algunas de las cuales son opcionales:

8.1. Título

Con la macro title: se determina el título, que consta de:

  • el nombre exacto del dispositivo o grupo de dispositivos para el que se escribe el check,

  • información sobre lo que monitoriza el check (por ejemplo, la salud del sistema).

Estas dos partes se separan con dos puntos: sólo así se pueden buscar y, sobre todo, encontrar fácilmente los checks existentes.

8.2. Categorías de agentes

La macro agents: puede tener diferentes categorías. Básicamente hay tres categorías:

  • Agentes: En este caso se especifican los sistemas operativos para los que se ha construido el check y para los que está disponible, por ejemplo linux, o linux, windows, solaris.

  • SNMP: En este caso sólo existe la entrada snmp.

  • Check activos: Si se ha integrado un check activo en la interfaz Checkmk, utilice la categoría active.

8.3. Entrada de catálogo

Utilice la cabecera catalog: para especificar dónde debe almacenarse la página de manual en el catálogo de plugins de check.

Si falta una categoría - por ejemplo, para un nuevo fabricante - la categoría debe ser definida en la variable catalog_titles en el archivo cmk/utils/man_pages.py. Actualmente este archivo no puede ser ampliado en local/ por Plugins, por lo que sólo los desarrolladores de Checkmk pueden hacer cambios aquí.

Tenga en cuenta el uso exacto de mayúsculas en los nombres de productos y empresas. Esto se aplica no sólo a la entrada del catálogo, sino también a todos los demás textos en los que aparezcan. Ejemplo: NetApp se escribe siempre NetApp, y no netapp, NETAPP, Netapp, o similares. Google puede ayudarle a encontrar la ortografía correcta.

8.4. Descripción del Plugin

La siguiente información debe incluirse en description: en la página man:

  • ¿Qué hardware o software monitoriza exactamente el check? ¿Existen características especiales de determinadas versiones de firmware o de producto de los dispositivos? No haga referencia a una MIB, sino a denominaciones de producto. Ejemplo: No es útil escribir "Este check funciona para todos los dispositivos que soportan la MIB Foobar-17.11". Escriba con precisión qué líneas de producto o similares se soportan.

  • ¿Qué aspecto se monitoriza? ¿Qué hace el check?

  • ¿En qué condiciones el check es OK, WARN o CRIT?

  • ¿Se necesita un plugin de agente para el check? En caso afirmativo, ¿cómo se instala? Debe funcionar sin el Agent bakery.

  • ¿Existen otros requisitos para que el check funcione (preparación del sistema de destino, instalación de controladores, etc.)? Sólo deben listarse si no se cumplen normalmente de todos modos (por ejemplo, el montaje de /proc en Linux).

No escriba nada que afecte a todas las comprobaciones juntas. Por ejemplo, no repita cosas generales como cómo configurar comprobaciones basadas en SNMP.

8.5. Item

Para los chequeos que tienen un item (es decir, un %s en el nombre del servicio), la página man bajo item: debe describir cómo está formado. Si el check plugin no usa un item, puede omitir esta línea completamente.

8.6. 8.6. Descubrimiento de servicios

En inventory:, escriba en qué condiciones se encontrarán automáticamente los servicios de este check, es decir, cómo se comporta el descubrimiento de servicios. Un ejemplo de nfsmounts:

nfsmounts
inventory:
  All NFS mounts are found automatically. This is done
  by scanning {/proc/mounts}. The file {/etc/fstab} is irrelevant.

Asegúrese de que el texto es comprensible sin un conocimiento más profundo de una MIB o del código, por lo que no lo escriba:

One service is created for each temperature sensor if the state is 1.

En su lugar, es mejor traducir todo lo posible:

One service is created for each temperature sensor, if the state is "active".
En esta página