Zabbix: supervisa todo en una fila (en el ejemplo de Redis)

Zabbix es un gran producto para administradores de grandes sistemas de software y hardware. Es tan bueno que puede ser utilizado no solo por grandes empresas, sino también por medianas y pequeñas empresas, e incluso en un proyecto pet . En general, tengo poca experiencia con Zabbix y puedo recomendarlo para su uso.


Es cierto que no puedo decir que entiendo la " filosofía de Zabbix ". A pesar de la extensa documentación detallada en ruso, fue difícil para mí sumergirme en el mundo de Zabbix: tuve la sensación de que los desarrolladores y yo llamábamos a las mismas cosas por diferentes nombres. Quizás porque Zabbix fue creado por administradores para administradores, pero todavía soy más un desarrollador y un usuario.


Sin embargo, para ejecutar Zabbix y monitorear los parámetros principales de los sistemas informáticos (procesador, memoria, etc.), las habilidades de un usuario habitual de Linux son suficientes. Hay una gran cantidad de complementos de desarrolladores externos que amplían las capacidades de Zabbix. Para mis necesidades, necesitaba configurar el monitoreo del servidor Redis. Rebusqué un poco en el código de los complementos disponibles y, usando su ejemplo, descubrí que la arquitectura de Zabbix le permite simplemente conectar cualquier parámetro del sistema de información que pueda expresarse en forma numérica al monitoreo.


Under the cat: un ejemplo de un complemento de Zabbix con mi explicación de la terminología de Zabbix. Para algunos, este ejemplo parecerá ingenuo, pero para algunos será más fácil sentirse cómodo con los conceptos. En cualquier caso, Zabbix es lo suficientemente grande como para sentirlo desde diferentes ángulos.


Conceptos basicos


Brevemente sobre algunos de los conceptos que se usan en Zabbix: agentes , elementos , disparadores , acciones , notificaciones , plantillas .


Servidor y Agentes


Desde el punto de vista del usuario, Zabbix se divide en dos grandes partes: servidor y agentes. El servidor está ubicado en una máquina, que recopila y almacena datos estadísticos, y los agentes en esas máquinas de las que se recopilan datos:


Servidor y agentes de Zabbix


Opciones de monitoreo


Cualquier cantidad que se puede expresar en forma numérica o de cadena se llama en la terminología de Zabbix, un elemento de datos (elemento). Cada elemento está asociado con una clave única (nombre). Aquí hay ejemplos de elementos de datos:


  • system.cpu.load [percpu, avg1] : 0.1167
  • system.uname : "Linux supru 4.15.0-50-generic # 54-Ubuntu SMP lun 6 de mayo 18:46:08 UTC 2019 x86_64"

Los valores de estos elementos de datos (parámetros de monitoreo) se adjuntan al tiempo; el historial de valores de parámetros se almacena en la base de datos del servidor.


Eventos


Cuando ocurre un evento en Zabbix, se dispara un disparador. Por ejemplo


  • {system.cpu.load [percpu, avg1] .avg (5m)}> 10 - el valor promedio del parámetro en los últimos 5 minutos ha excedido "10"
  • {system.uname.diff (0)}> 0 : el valor actual del parámetro no es igual al valor anterior

De hecho, los desencadenantes son fórmulas en las que los parámetros de monitoreo (actuales y guardados) actúan como variables, y que producen true / false en la salida.


Acciones y Alertas


En caso de un evento (disparador), el servidor puede realizar una acción. Por ejemplo, envíe una alerta por correo electrónico a una dirección determinada (" Problema: no se puede acceder al host durante 5 minutos "). Además, se puede realizar una acción si el disparador vuelve a su estado original (" Resuelto: el host no se puede alcanzar durante 5 minutos "). Todos los eventos (cambio de activación) se registran en el lado del servidor.


Patrones


Zabbix hace posible configurar reglas de monitoreo para un host individual, así como crear una plantilla de regla (plantilla) que se puede aplicar a varios hosts:


plantillas de zabbix


El ejemplo muestra que la plantilla "Servicio de plantilla de aplicación SSH" describe una aplicación (Aplicaciones), un parámetro de monitoreo (Elementos), un disparador (Disparadores). También están disponibles descripciones para gráficos, pantallas, reglas de descubrimiento y scripts web.


Establecer la tarea para el complemento


Posición inicial


El propio Zabbix ofrece su propio complemento para monitorear el estado de Redis, pero en mi versión del servidor (4.2.8) no pude usarlo (complemento para la versión 4.4 y superior). También se ofrecen soluciones de terceros (aproximadamente una docena de opciones para varias versiones de Zabbix, solo están las tres primeras en la imagen):


Complementos de redis para zabbix


Cada uno de ellos tenía sus propias ventajas y desventajas, tenía que mirar hacia adentro para elegir. Lo mejor, en mi opinión, fue el complemento Shakeeljaveed / zabbix-redis-userparamaters , que constaba de dos archivos:


  • README.md
  • redis-userparameter.conf

Tuve que trabajar un poco "bolígrafos", pero en su ejemplo se hizo un poco más claro cómo los datos del agente van al servidor. A sugerencia del autor Javeed Shakeel, la corona restableció el estado de Redis cada 2 minutos en el /tmp/redismetric :


 */2 * * * * /usr/bin/redis-cli info > /tmp/redismetric 

Y luego cada parámetro de monitoreo fue extraído por el agente del /tmp/redismetric usando las herramientas del sistema operativo en sí. Las instrucciones para esto se colocaron en la configuración del agente Zabbix /etc/zabbix/zabbix_agent.conf.d/userparameter_redis.conf . Por ejemplo, así es como se ve la instrucción para recuperar el parámetro used_memory (uso de memoria por parte del servidor Redis):


 UserParameter=used_memory,grep -w 'used_memory' /tmp/redismetric | cut -d: -f2 

Es decir, en el /tmp/redismetric con la salida de redis-cli INFO , la cadena ( grep -w ... ) busca la cadena ( grep -w ... )


 used_memory:7153216 

que luego se divide en columnas mediante el separador ":" ( cut -d: -f2 ). En la salida, el agente recibe el número 7153216 y lo asigna al parámetro used_memory .


Queda por configurar el servidor a través de la interfaz basada en la web para que envíe periódicamente solicitudes al agente para recibir datos utilizando el parámetro used_memory , después de lo cual los datos comienzan a used_memory en el servidor, almacenados en la base de datos, puede usarlos para crear gráficos y crear activadores que respondan a los cambios a este parámetro.


Propósito


La tarea de monitorear el estado de cualquier sistema no es solo la recopilación de estadísticas, sino también una advertencia sobre la ocurrencia de situaciones que requieren intervención humana. Como trabajo con Redis como un usuario muy novato, tuve que buscar información sobre a qué parámetros de "salud" prestar atención y qué significan. El artículo más valioso fue " 6 métricas de monitoreo de Redis cruciales que debe observar ". Después de analizarlo, llegué a la conclusión de que "para la felicidad completa" necesito recopilar datos para detectar los siguientes eventos:


  • Fragmentación de memoria: used_memory_rss / used_memory> 1.5
  • Bajo índice de aciertos de caché: (keyspace_hits) / (keyspace_hits + keyspace_misses) <0.8
  • Conexiones rechazadas: rechazadas_conexiones> 0
  • Claves desalojadas: evicted_keys> 0

También quería recopilar estadísticas sobre parámetros adicionales (versión de Redis, tiempo de actividad, etc.). En general, teniendo una idea general de cómo el agente recopila los datos y los transmite al servidor, la lista de deseos puede ser muy limitada. Como resultado, obtuvimos una lista de parámetros para el monitoreo desde 12 posiciones.


Crea tu propio complemento


Opciones de monitoreo


El complemento que analicé asumió la ejecución de un comando separado para obtener un parámetro separado (elemento de datos, elemento):


 grep -w 'used_memory' /tmp/redismetric | cut -d: -f2 

Es decir, para obtener datos sobre 12 parámetros, el agente tendrá que ejecutar varios conjuntos de comandos 12 veces. ¿Y si necesito monitorear parámetros que son difíciles de extraer por una cadena de comandos y necesito escribir un script de shell separado o un programa completo? Para tal "Lista de deseos", Zabbix ofrece una variante con elementos de datos dependientes. Su esencia es que, en el lado del agente, el script forma un conjunto de datos (por ejemplo, en formato JSON), que se transmite al servidor como un parámetro de cadena. Luego, en el lado del servidor, los datos recibidos se analizan y los parámetros elementales individuales se extraen de ellos.


Elemento de datos principal


Describí el principal redis.info datos redis.info tipo de cadena con un período de actualización de 1 minuto, sin guardar el historial de cambios:


artículo base


Presumiblemente, el siguiente JSON debería generarse en el lado del agente:


 { "version": "4.0.9", "uptime": 1897336, "used_memory": 1054943416, "used_memory_rss": 1138159616, "keyspace_hits": 75810274, "keyspace_misses": 13545949, "connected_clients": 15, "rdb_last_save_time": 1580126954, "total_connections_received": 1258614, "rejected_connections": 0, "expired_keys": 60270, "evicted_keys": 0 } 

después de lo cual este texto debe redis.info al servidor como un redis.info datos redis.info , pero no guardarse, sino que sirve como base para otros elementos de datos (parámetros de monitoreo).


Elemento de datos dependiente


El parámetro de prueba redis.info.version depende de redis.info y almacena sus valores en la base de datos durante 90 días. La frecuencia del monitoreo de parámetros depende del elemento base ( redis.info ):


elemento dependiente (base)


El redis.info.version parámetro redis.info.version se recupera del valor redis.info utilizando las instrucciones JSONPath:


elemento dependiente (preproceso)


Un esquema similar describe los elementos de datos dependientes restantes (parámetros de monitoreo), que se transmiten en forma de JSON. Aquí hay un ejemplo de la descripción del parámetro numérico redis.info.used_memory :


elemento de número dependiente (base)


Todo es bastante transparente, con la excepción de las Units y Trend storage period . No entendí el segundo punto, lo dejé por defecto y las unidades de medida se explican en la documentación . En este caso, el valor de redis.info.used_memory se mide en bytes y se minimiza a kilo / mega / giga /...- bytes en la interfaz web.


La fórmula para extraer un valor de JSON es: JSONPath = $.used_memory


Elemento de datos calculados


Para calcular la fragmentación de la memoria, se utiliza la relación used_memory_rss / used_memory y, sobre la base de esto, se determina un disparador que se activa cuando la relación excede 1.5. Zabbix tiene un tipo de elemento de datos calculado:


artículo calc


El valor del parámetro redis.info.used_memory_ratio calcula cada minuto en función de los últimos valores de otros dos parámetros ( redis.info.used_memory_rss y redis.info.used_memory ), se almacena en la base de datos durante 90 días, etc.


Disparadores


Aquí hay un ejemplo de un disparador que se dispara cuando la memoria está demasiado fragmentada:



Nada inusual, excepto el formato de expresión utilizado en la fórmula de cambio de estado del disparador. Zabbix tiene un constructor de formularios, puede usarlo o consultar la documentación / ejemplos (la lista de disparadores está disponible a través de la interfaz web en " Configuración / Plantillas / $ {TemplateName} / Triggers ").


Un activador puede basarse en cualquier elemento de datos (elemento), independientemente de su tipo (principal, dependiente, calculado).


Configuración del agente


Generación JSON


Para obtener los valores de los parámetros de monitoreo y la formación de JSON, uso este script de shell:


 #!/bin/bash ## =========================================================================== # Script to generate Redis monitoring data in JSON format # for 'zabbix-agent'. ## =========================================================================== # collect working variables/data BIN_REDIS=$(whereis -b redis-cli | cut -d" " -f2) # /usr/bin/redis-cli DATA_INFO=$(${BIN_REDIS} INFO | tr -d '\r') # get info and remove trailing '\r' from output ## # Extract stats and save it into env. vars. ## # find lines with 'grep', cut second field after ":" and put it into env. variable: ITEM_VERSION=$(grep "^redis_version:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_UPTIME=$(grep "^uptime_in_seconds:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_USED_MEMORY=$(grep "^used_memory:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_USED_MEMORY_RSS=$(grep "^used_memory_rss:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_KEYSPACE_HITS=$(grep "^keyspace_hits:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_KEYSPACE_MISSES=$(grep "^keyspace_misses:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_CONNECTED_CLIENTS=$(grep "^connected_clients:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_RDB_LAST_SAVE_TIME=$(grep "^rdb_last_save_time:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_TOTAL_CONNECTIONS_RECEIVED=$(grep "^total_connections_received:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_REJECTED_CONNECTIONS=$(grep "^rejected_connections:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_EXPIRED_KEYS=$(grep "^expired_keys:" <<<"${DATA_INFO}" | cut -d: -f2) ITEM_EVICTED_KEYS=$(grep "^evicted_keys:" <<<"${DATA_INFO}" | cut -d: -f2) # compose output JSON for Zabbix server: echo -n "{" echo -n "\"version\": \"${ITEM_VERSION}\"," echo -n "\"uptime\": ${ITEM_UPTIME}," echo -n "\"used_memory\": ${ITEM_USED_MEMORY}," echo -n "\"used_memory_rss\": ${ITEM_USED_MEMORY_RSS}," echo -n "\"keyspace_hits\": ${ITEM_KEYSPACE_HITS}," echo -n "\"keyspace_misses\": ${ITEM_KEYSPACE_MISSES}," echo -n "\"connected_clients\": ${ITEM_CONNECTED_CLIENTS}," echo -n "\"rdb_last_save_time\": ${ITEM_RDB_LAST_SAVE_TIME}," echo -n "\"total_connections_received\": ${ITEM_TOTAL_CONNECTIONS_RECEIVED}," echo -n "\"rejected_connections\": ${ITEM_REJECTED_CONNECTIONS}," echo -n "\"expired_keys\": ${ITEM_EXPIRED_KEYS}," echo -n "\"evicted_keys\": ${ITEM_EVICTED_KEYS}" echo -n "}" 

/var/lib/zabbix/user_parameter/redis/get_info.sh este script en el archivo /var/lib/zabbix/user_parameter/redis/get_info.sh en el servidor con Redis, en el que el agente Zabbix ya está instalado. El usuario con el que se zabbix agente Zabbix (generalmente zabbix ) debe tener permiso para ejecutar el archivo get_info.sh .


Archivo userparameter_XXX.conf


En el lado del agente, los parámetros de supervisión adicionales se userparameter_*.conf en los userparameter_*.conf en el directorio userparameter_*.conf . Por lo tanto, para que el agente descubra cómo necesita recopilar datos sobre el parámetro redis.info , creé el archivo /etc/zabbix/zabbix_agentd.d/userparameter_redis.conf con el siguiente contenido:


 UserParameter=redis.info,/var/lib/zabbix/user_parameter/redis/get_info.sh 

Es decir, para obtener datos sobre el parámetro redis.info agente debe ejecutar el script /var/lib/zabbix/user_parameter/redis/get_info.sh y transferir el resultado de la ejecución al servidor.


Después de reiniciar el agente Zabbix ( sudo service zabbix-agent restart ), es posible recopilar datos para el parámetro redis.info y enviarlos al servidor.


Resumen


Entender Zabbix vino a mí (y todavía viene) bastante difícil. Sin embargo, lo considero una gran herramienta, especialmente después de que se me abrió la simplicidad de agregar mis propios parámetros de monitoreo (elementos de datos). En general, es suficiente agregar un archivo al servidor con el agente ( userparameter_XXX.conf ) con un comando de shell para recopilar datos y configurar el servidor Zabbix para recibir estos datos a través de la interfaz web. Y eso es todo: puede acumular datos, crear gráficos, analizar cambios y crear un activador que responda a estos cambios.


El código de la plantilla, el archivo userparameter_redis.conf y el script get_info.sh se pueden ver en el proyecto flancer32 / zabbix_plugin_redis .


Gracias a todos los que leyeron hasta el final, y especialmente a aquellos que encontraron algo útil para ellos en la publicación.

Source: https://habr.com/ru/post/485538/


All Articles