![]() |
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 respecto a otros sistemas de monitorización es el gran número de plugins de check bien mantenidos que se suministran de serie. Para que estos plugins tengan una calidad uniformemente alta, hay criterios estandarizados que cada plugin debe cumplir.
Una nota importante sobre los criterios: no te limites a suponer que todos los Plugin suministrados con Checkmk cumplen todas las normas vigentes. Evita copiar y pegar. Es más aconsejable orientar tu trabajo según la información de este artículo.
Si desarrollas Plugin únicamente para tu propio uso, por supuesto tienes total libertad y no estás obligado a cumplir nuestras normas.
1.1. Calidad
Para los check plugins que son componentes oficiales de Checkmk, o que está previsto que lo sean, se exige una mayor calidad en comparación con los escritos "para tu 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, codifica bien el Plugin y con el máximo nivel de calidad que te sea posible.
1.2. Alcance de un plugin de check
Todo plugin de check 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.
Definiciones métricas para gráficos y el Perf-O-Meter si el check produce datos métricos.
Una definición para el Agent bakery si hay un plugin de agente.
Una serie de ejemplos completos y diversos de las salidas de los agentes, o respectivamente paseos SNMP.
2. Convenciones de denominación
2.1. Check Nombre del plugin
Elegir un nombre para un Plugin es especialmente crítico, ya que este nombre no puede modificarse 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
ostate
son innecesarias en un nombre, ya que, por supuesto, cada plugin monitoriza un estado. Lo mismo se aplica a la palabra superfluacurrent
. Así que, en lugar defoobar_current_temp_status
utiliza simplementefoobar_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 plugins de comprobación específicos de un producto deben ir precedidos del nombre del producto - por ejemplo,
oracle_tablespace
.Los plugins de comprobación específicos de un fabricante que no se apliquen a un producto concreto deben llevar como prefijo 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 que pueda ser soportado 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. Nombre del servicio
Utiliza abreviaturas comunes y bien definidas (por ejemplo, CPU, BD, VPN, IO,...).
Escribe las abreviaturas en mayúsculas.
Utiliza mayúsculas y minúsculas (por ejemplo,
CPU utilization
, noCpu Utilization
) - los nombres propios son una excepción.Escribe los nombres de los productos tal y como los defina el proveedor (por ejemplo,
vSphere
).Utiliza el inglés americano (por ejemplo,
utilization
, noutilisation
).Cíñete a los esquemas de nomenclatura existentes, si existen. Por ejemplo, todos los servicios de interfaz utilizan la plantilla
Interface %s
.Intenta ser breve y que las descripciones sean 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 exista una definición significativa deben reutilizarse.
De lo contrario, se aplicarán reglas similares a las utilizadas para nombrar los plugins de check (específicos del producto, del fabricante, etc.).
2.4. Nombre del grupo de reglas de check para el conjunto de reglas
Se aplica la misma convención que con las métricas.
3. Construir un plugin de check
3.1. Estructura general
El archivo Python propiamente dicho bajo ~/share/check_mk/checks/
debe tener la siguiente estructura (respetando la secuencia de codificación):
Una cabecera de archivo con un aviso GPL.
El nombre y la dirección de correo electrónico del autor original si el Plugin no ha sido desarrollado por el proyecto Checkmk.
Una breve muestra de la salida del agente.
Valores por defecto de los parámetros de check (
factory_settings
).Las funciones auxiliares, si están disponibles.
La función de análisis sintáctico, si está disponible.
La función de descubrimiento.
La función check.
La declaración
check_info
.
3.2. Pautas 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
Evita 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 utilices pestañas.
Oriéntate según el 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 en la muestra varias salidas posibles. Haz que la muestra no sea más larga de lo necesario. Con los chequeos basados en SNMP, proporciona 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 debe proporcionarse un ejemplo que indique la versión para cada uno. Un buen ejemplo de este caso puede encontrarse en el Plugin de check multipath
.
MIBs SNMP
Cuando definas snmp_info
, debes indicar 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
Evita expresiones complejas con lambda
. Se permite lambda
en la función de escaneo lambda oid: …
, y cuando desees invocar funciones existentes con sólo un argumento alterado - por ejemplo:
"inventory_function" : lambda info: inventory_foobar_generic(info, "temperature")
Iterar a través de los datos del agente SNMP
Con los checks que analizan datos SNMP, no se debe utilizar un índice como éste:
for line in info:
if line[1] != '' and line[0] ...
Es mejor desempaquetar 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
Utiliza 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 este modo, el lector tendrá claro que ese resultado procede de una función de análisis sintáctico.
Check con múltiples resultados parciales
Un check que produzca múltiples resultados parciales -por ejemplo, asignaciones actuales y crecimiento- debe devolverlos con yield
. Los checks que sólo 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 (!!)
están obsoletos y ya no pueden utilizarse. Deben sustituirse por yield
.
Claves en check_info[…]
Sólo almacena las claves que vayas a utilizar en tu entrada en check_info
. Las únicas entradas obligatorias son "service_description"
y "check_function"
. Sólo inserta "has_perfdata"
y otras claves con valores booleanos si su valor es True
.
3.3. Plugins de agente
Si tu check plugin requiere un plugin de agente, ten en cuenta las siguientes reglas:
Almacena el Plugin en
~/share/check_mk/agents/plugins
para sistemas tipo Unix, y establece los derechos de ejecución en755
.En Windows, el directorio se llama
~/share/check_mk/agents/windows/plugins
.Los script shell y Python no deben tener extensión de nombre de archivo (omite
.sh
y.py
).Utiliza
#!/bin/sh
en la primera línea de los scripts shell. Utiliza#!/bin/bash
sólo si se requieren funciones de Bash.Utiliza la cabecera estándar del archivo Checkmk con el aviso GPL.
Tu Plugin no debe dañar el sistema de destino, especialmente si el Plugin no es realmente compatible con el sistema.
No olvides la referencia al Plugin en la página man del Plugin check.
Si el componente que el Plugin debe monitorizar no existe realmente en un 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 prefijomk_
. El procedimiento es similar para Windows - el directorio en Windows es%MK_CONFDIR%
.No codifiques Plugin para Windows en PowerShell, ya que no es portable y, en cualquier caso, consume muchos recursos. Utiliza VBScript.
No codifiques Plugin en Java.
3.4. Lo que no debes hacer
No utilices
import
en tu archivo check plugin. Ya se han importado todos los módulos de Python permitidos.No utilices
datetime
para analizar y calcular las especificaciones de tiempo - utilizatime
. Éste puede realizar todas las tareas necesarias, ¡de verdad!Los argumentos que reciben tus funciones no deben modificarlas en modo alguno. Esto se aplica especialmente a
params
yinfo
.Si realmente quieres trabajar con expresiones regulares (¡son lentas!), invócalas con la función
regex()
- no utilicesre
directamente.Naturalmente, no está permitido utilizar
print
, ni enrutar las salidas astdout
, ¡ni comunicarse con el mundo exterior de ninguna manera!La función de escaneo SNMP no puede obtener OID distintos de
.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 OID, de que sólo se obtengan otros OID de un número estrictamente limitado de dispositivos.
4. Comprobar el comportamiento del Plugin
4.1. Excepciones
Tu plugin de check no debe, sino que debe asumir siempre que la salida de un agente es sintácticamente válida. ¡En ningún caso se permite que el plugin intente manejar situaciones de error desconocidas en la propia salida!
¿Por qué es así? Checkmk tiene una función muy refinada para tratar automáticamente este tipo de errores. Para el usuario puede generar completos informes de fallos, y también establece el estado del Plugin en DESCONOCIDO. Esto es mucho más útil que si el check, por ejemplo, se limita a producir un unknown SNMP code 17
.
Por lo general, la función de descubrimiento, análisis y/o comprobación debe 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 se puede convertir (por ejemplo, si es una cadena vacía).
Utiliza estas funciones sólo si el valor vacío o inválido es una condición conocida; de lo contrario, se suprimirán los 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. Ten en cuenta las siguientes reglas que garantizan que Checkmk reaccione de forma coherente:
Los umbrales de 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, debe haber exactamente un espacio en blanco entre el valor y la unidad (por ejemplo,
17.4 V
). La única excepción a esta regla es con%
, donde no hay 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 muestres claves internas, palabras clave, SNMP-internas u otra basura en las salidas de Plugin que no sea de utilidad para el usuario. Utiliza términos significativos y legibles para el ser humano. Utiliza términos que el usuario espere normalmente. Ejemplo: Utiliza
route monitor has failed
en lugar derouteMonitorFail
.Si el item de check tiene una especificación adicional, codifícala 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 para él unos valores por defecto de los umbrales que tengan sentido. Se aplican las siguientes reglas:
Los umbrales por defecto utilizados en el check también deben definirse 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úrate de que tu 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 de las métricas
El check plugin siempre devuelve los datos métricos como
int
ofloat
. No se admiten cadenas.Si quieres que salga la séxtuple de un campo de valor métrico, utiliza
None
en su posición. Ejemplo:[("taple_util", utilization, None, None, 0, size)]
Si no necesitas la entrada al final, simplemente acorta la tupla. No utilices
None
al final.
5.2. Cómo nombrar las métricas
Los nombres de las métricas se componen de letras minúsculas y guiones bajos. Se permiten los números, pero no las letras mayúsculas.
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.
Evita 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 deampere
, osize
en lugar debytes
.
Importante: Utiliza siempre la medida canónica. ¡En serio! Checkmk escala los propios datos 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 por segundo!) |
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
Sólo establece "has_perfdata"
en check_info
a True
si el check emite realmente datos métricos (o puede emitirlos).
5.4. Definición de gráfico y Perfómetro
Las definiciones de los gráficos deben ser como las de ~/web/plugins/metrics/check_mk.py
. No crees definiciones para los gráficos PNP. En Checkmk Raw también se generarán a partir de las definiciones métricas del propio Checkmk.
6. Definición del conjunto de reglas
6.1. Nombre del grupo de chequeo
Los plugins de check 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 check (la entrada "group"
en check_info
). Todas las comprobaciones configuradas con el mismo conjunto de reglas se consolidan a través del grupo.
Si tu Plugin debe configurarse sensatamente con un conjunto de reglas existente, utiliza también un grupo existente.
Si tu Plugin es tan específico que en cualquier caso requiere su propio grupo, crea un grupo propio para él en el que el nombre del grupo haga referencia al Plugin.
Si es previsible que en el futuro otros Plugins puedan utilizar el mismo conjunto de reglas, utiliza un nombre genérico adecuado.
6.2. Valores por defecto de los ValueSpecs
Cuando definas tus definiciones de parámetros(ValueSpecs), utiliza 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 la ValueSpec debe definirse de modo que 5
y 10
se ofrezcan automáticamente como umbrales.
6.3. Elegir 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 utilices, por ejemplo, Integer
en tal caso.
7. Archivos de inclusión
Para una serie de tipos de checks existen implementaciones ya preparadas en archivos de inclusión, que no sólo se pueden utilizar, sino que se deben utilizar. Los archivos de inclusión importantes son:
|
Monitorización de temperaturas |
|
Fases eléctricas de CA (por ejemplo, en USV) |
|
Ventiladores |
|
Interfaces de red |
|
Niveles del sistema de archivos |
|
Monitorización de la RAM (almacenamiento principal) |
|
Procesos del sistema operativo |
Importante: ¡ utiliza los archivos de inclusión existentes sólo si han sido diseñados para el fin que se persigue, y no simplemente porque se ajustan de forma aproximada!
8. Páginas man
Cada plugin de check debe tener una página man. Si has programado varios plugins en un mismo archivo de check plugin, cada uno de ellos debe tener, por supuesto, su propia página man.
La página man está pensada para el usuario! Escribe información que le ayude. 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 del manual consta de varias secciones, algunas de las cuales son opcionales:
8.1. Título
Con la macro title:
determinas 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 fácilmente los checks existentes y, sobre todo, encontrarlos.
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 creado el check y para los que está disponible, por ejemplo
linux
, olinux, 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, utiliza la categoría
active
.
8.3. Entrada de catálogo
Utiliza 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 definirse en la variable catalog_titles
del archivo cmk/utils/man_pages.py
. Actualmente este archivo no puede ampliarse en local/
mediante plugins, por lo que sólo los desarrolladores de Checkmk pueden hacer cambios aquí.
Ten en cuenta las mayúsculas exactas de 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 ayudarte 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 te refieras a una MIB, sino a designaciones de producto. Ejemplo: No es útil que escribas "Este check funciona para todos los dispositivos compatibles con la MIB Foobar-17.11". Escribe con precisión qué líneas de producto o similares son compatibles.
¿Qué aspecto se monitoriza? ¿Qué hace la comprobación?
¿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 enumerarse si no se cumplen normalmente de todos modos (por ejemplo, el montaje de
/proc
en Linux).
No escribas nada que afecte a todas las comprobaciones juntas. Por ejemplo, no repitas cosas generales como la forma de configurar comprobaciones basadas en SNMP.
8.5. Item
Para las comprobaciones que tienen un item (es decir, un %s
en el nombre del servicio), la página man en item:
debe describir cómo está formado. Si el check plugin no utiliza un item, puedes omitir esta línea por completo.
8.6. Descubrimiento de servicios
En inventory:
, escribe 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
:
inventory:
All NFS mounts are found automatically. This is done
by scanning {/proc/mounts}. The file {/etc/fstab} is irrelevant.
Asegúrate de que el texto sea comprensible sin un conocimiento más profundo de una MIB o del código, por lo que no lo escribas:
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".