¿Alguna vez ha querido un botón para exportar datos específicos a CSV, directamente desde el frontend de Zabbix? Mi amigo Gregory y yo hemos resuelto este problema.

En esta publicación de blog, le mostraré cómo con la ayuda de un módulo de frontend personalizado de Zabbix, es posible agregar un botón “Exportar a CSV” y usarlo para obtener información personalizada. Esto se puede instalar como un módulo de frontend. El requisito es tener PHP 7.2 o posterior. Aplica para las versiones Zabbix 5.0 LTS y Zabbix 6.0 LTS. Como beneficio adicional, podemos usar este módulo para pulir nuestra instancia de Zabbix, encontrar configuraciones incorrectas, resumir la configuración existente y localizar posibles cuellos de botella.

Características del módulo

  • Defina y almacene consultas SQL personalizadas en el perfil de usuario. Utiliza la tabla “profiles” de la base de datos, específicamente las columnas “idx” y “value_str” para almacenar la configuración / datos. No estamos cambiando la estructura de la base de datos, sino utilizando lo que ya está disponible.
  • Exporte una cantidad ilimitada de filas a través del botón CSV.
  • Compatible con MySQL, PostgreSQL y sintaxis SQL en general. Utilice el mismo lenguaje que utiliza directamente en el cliente SQL.
  • Resaltador Se basa en un conocido producto CodeMirror. El módulo de Zabbix sigue siendo completamente independiente.
  • Soporte de hipervínculo para el resultado SQL. Es útil para crear un enlace que se pueda utilizar para acercarse al problema. Solo hipervínculos relacionados con secciones de Zabbix (php, triggers.php).

Que no ES?

  • El módulo no proporciona un ambiente para que los usuarios del tipo “Zabbix User” o “Zabbix Admin” realicen informes. Solo del tipo “Zabbix Super Admin” pueden usar este módulo.

Instalación

A continuación puede encontrar la secuencia de comandos utilizados para descargar e instalar el módulo “Exportar a CSV“.

Navegue al directorio por defecto para módulos del frontend:
cd /usr/share/zabbix/modules
Seleccione y cree el nombre del directorio:
mkdir -p zabbix-module-sqlexplorer
Ingrese al directorio:
cd zabbix-module-sqlexplorer
Descargue la versión 1.4 del módulo:
wget https://github.com/gr8b/zabbix-module-sqlexplorer/releases/download/v1.7/v1.7.zip
Extraiga el archivo:
unzip v1.7.zip
Elimine el archivo original ya que no será necesario:
rm v1.7.zip

Habilitación

Abra “Administración” => “General” => “Módulos” => haga clic en “Escanear directorio“. Después de eso, haga clic en “Habilitar“:
Una nueva opción de menú se encontrara disponible:

Ahora podemos ejecutar una consulta SQL, ver el resultado en la pantalla y exportar los datos a CSV:

Hablemos de 5 casos de uso beneficiosos que este módulo no puede brindar. A continuación los ingenieros de soporte técnico de Zabbix nos comparten algunos comandos SQL de uso frecuente.

1) Asegurar que la recopilación de datos básicos funciona

Esta sección sería el mínimo básico a mantener. En un mundo perfecto, cada objeto de host (un dispositivo, un servidor) debe estar en línea las 24 horas del día, los 7 días de la semana. Para cada categoría (ZBX, SNMP, IPMI, JMX) necesitamos usar una consulta dedicada. Trabajemos con los 2 tipos de categorías más populares: ZBX y SNMP.

Hosts con agente de Zabbix inalcanzable (ZBX)

Zabbix 5.0:

SELECT proxy.host AS proxy, hosts.host, hosts.error AS hostError, CONCAT('hosts.php?form=update&hostid=',hosts.hostid) AS goTo FROM hosts LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) WHERE hosts.status=0 AND LENGTH(hosts.error) > 0;

Zabbix 6.0:

SELECT proxy.host AS proxy, hosts.host, interface.error FROM hosts LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) JOIN interface ON (interface.hostid=hosts.hostid) WHERE LENGTH(interface.error) > 0 AND interface.type=1;

En el resultado, obtenemos un objeto del tipo proxy, título del host, un mensaje de error y un link para navegar directamente al objecto.

Por cada fila en el resultado, necesitamos: 1) Solucionar el problema. Lo más probable es que sea un problema de firewall / DNS / credencial / tiempo de espera o de calidad de red; 2) Eliminar el objeto host; o 3) Deshabilitar el objeto host.

Hosts de red inalcanzables (SNMP)

En Zabbix 5.0 utilizar:

SELECT proxy.host AS proxy, hosts.host, hosts.snmp_error AS hostError, CONCAT('hosts.php?form=update&hostid=',hosts.hostid) AS goTo FROM hosts LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) WHERE hosts.status=0 AND LENGTH(hosts.snmp_error) > 0;

En Zabbix 6.0 utilizar:

SELECT proxy.host AS proxy, hosts.host, interface.error, CONCAT('zabbix.php?action=host.edit&hostid=',hosts.hostid) AS goTo FROM hosts LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) JOIN interface ON (interface.hostid=hosts.hostid) WHERE LENGTH(interface.error) > 0 AND interface.type=2;

Recibimos el título del proxy, el objeto host, la razón por la que el host no funciona y un enlace en el que se puede hacer clic al objeto.

2) Mejorar la velocidad del frontend

Asegúrese de que tenemos el mejor tiempo de respuesta para todas las secciones en la GUI. Si las tablas contienen datos “innecesarios”, la experiencia de usuario sufrirá por ello. Hoy en día, nadie quiere pasar más de unos segundos esperando que los datos se muestren en pantalla.

Cantidad de sesiones de usuario

Zabbix 5.0:

SELECT COUNT(*) AS count, users.alias FROM sessions JOIN users ON (users.userid=sessions.userid) GROUP BY 2 ORDER BY 1 DESC;

Zabbix 6.0:

SELECT COUNT(*) AS count, users.username FROM sessions JOIN users ON (users.userid=sessions.userid) GROUP BY 2 ORDER BY 1 DESC;

El número total de sesiones no debe exceder de 1000; Es difícil imaginar por qué debería ser más de 100. Es posible eliminar todos los datos de la tabla “sessions” y optimizar/vaciar la tabla. Esto mejorará la capacidad de respuesta y el rendimiento general de la GUI de Zabbix.

No mantenga demasiados problemas abiertos

Las herramientas de monitoreo se tratan sobre identificar problemas. Si mantiene demasiados problemas abiertos, entonces el frontend será lento. La siguiente consulta mostrara como resultado problemas de triggers (los que recibimos en el correo electrónico) y problemas internos, que reflejan el estado de la herramienta de monitoreo.

SELECT COUNT(*) AS count, CASE WHEN source=0 THEN 'surface' WHEN source>0 THEN 'internal' END AS level, CASE WHEN source=0 AND object=0 THEN 'trigger in a problem state' WHEN source=3 AND object=0 THEN 'cannot evaluate trigger expression' WHEN source=3 AND object=4 THEN 'data collection not working' WHEN source=3 AND object=5 THEN 'low level discovery not perfect' END AS problemCategory FROM problem GROUP BY 2,3 ORDER BY 2 DESC;

Para disminuir el número de problemas “internos“, preste especial atención al punto nr. 5 de este blog post.

3) Identificar excepciones

Los administradores de monitoreo pueden cambiar el intervalo de actualización para los items a nivel de host, pueden configurar un umbral de trigger a nivel de host o instalar un umbral diferente dentro de un árbol de templates anidados. Esta sección resaltará todas las excepciones.

El intervalo de actualización difiere entre los niveles de host/template

La siguiente consulta, mostrara como resultado ítems y reglas de LLD que cuentan con diferentes intervalos de actualización a nivel host, mientras que los compara a nivel template. La mayoría del tiempo, contar con diferentes intervalos de actualización a nivel host es realizado de forma accidental.

SELECT h2.host AS Source, i2.name AS itemName, i2.key_ AS itemKey, i2.delay AS OriginalUpdateFrequency,h1.host AS exceptionInstalledOn, i1.delay AS FrequencyChild, CASE WHEN i1.flags=1 THEN 'LLD rule' WHEN i1.flags IN (0,4) THEN 'data collection' END AS itemCategory , CASE WHEN i1.flags=1 THEN CONCAT('host_discovery.php?form=update&context=host&itemid=',i1.itemid) WHEN i1.flags IN (0,4) THEN CONCAT('items.php?form=update&context=host&hostid=',h1.hostid,'&itemid=',i1.itemid) END AS goTo FROM items i1 JOIN items i2 ON (i2.itemid=i1.templateid) JOIN hosts h1 ON (h1.hostid=i1.hostid) JOIN hosts h2 ON (h2.hostid=i2.hostid) WHERE i1.delay <> i2.delay;

En el resultado, la columna “Source” es un objeto host (un dispositivo) o un objeto de template. La columna “Source” está fuertemente relacionada con la columna “exceptionInstalledOn“. “Source” VS “exceptionInstalledOn” prácticamente indica que hay una relación entre un host y un template o entre un template y otra template.

La columna “FrequencyChild” es el campo más importante, ya que describe una excepción instalada que difiere del objeto original.

El resultado permite navegar directamente al item donde se destaca el intervalo de actualización.

Características de conexión y umbrales de triggers a medida

La consulta mostrará cada anulación configurada entre el host y el objeto de template o entre el template y el objeto de template principal. Si el anidamiento de template se utiliza en varios niveles, se resaltará si un valor primordial si está instalado en algún lugar en el medio.

SELECT hm1.macro AS Macro, child.host AS owner, hm2.value AS defaultValue, parent.host AS OverrideInstalled, hm1.value AS OverrideValue FROM hosts parent, hosts child, hosts_templates rel, hostmacro hm1, hostmacro hm2 WHERE parent.hostid=rel.hostid AND child.hostid=rel.templateid AND hm1.hostid = parent.hostid AND hm2.hostid = child.hostid AND hm1.macro = hm2.macro AND parent.flags=0 AND child.flags=0 AND hm1.value <> hm2.value;

Items abandonados

Items que no pertenecen a ningún template

SELECT hosts.host, items.key_,CONCAT('items.php?form=update&context=host&itemid=',items.itemid) AS goTo FROM items JOIN hosts ON (hosts.hostid=items.hostid) WHERE hosts.status=0 AND hosts.flags=0 AND items.status=0 AND items.templateid IS NULL AND items.flags=0;

Para mantener la administración centralizada, sería mejor mover y mantener la definición del item a nivel template

4) Reportes

Es posible resumir las configuraciones de un item o host, los ítems de recolección de datos habilitados o deshabilitados y los templates vinculados.

Que método de recolección de datos es utilizado?

Para resumir todos los métodos de recolección de datos y su relación con los Zabbix Proxy, utilice el siguiente comando:

SELECT proxy.host AS proxy, CASE items.type WHEN 0 THEN 'Zabbix agent' WHEN 1 THEN 'SNMPv1 agent' WHEN 2 THEN 'Zabbix trapper' WHEN 3 THEN 'Simple check' WHEN 4 THEN 'SNMPv2 agent' WHEN 5 THEN 'Zabbix internal' WHEN 6 THEN 'SNMPv3 agent' WHEN 7 THEN 'Zabbix agent (active) check' WHEN 8 THEN 'Aggregate' WHEN 9 THEN 'HTTP test (web monitoring scenario step)' WHEN 10 THEN 'External check' WHEN 11 THEN 'Database monitor' WHEN 12 THEN 'IPMI agent' WHEN 13 THEN 'SSH agent' WHEN 14 THEN 'TELNET agent' WHEN 15 THEN 'Calculated' WHEN 16 THEN 'JMX agent' WHEN 17 THEN 'SNMP trap' WHEN 18 THEN 'Dependent item' WHEN 19 THEN 'HTTP agent' WHEN 20 THEN 'SNMP agent' WHEN 21 THEN 'Script item' END AS type,COUNT(*) FROM items JOIN hosts ON (hosts.hostid=items.hostid) LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) WHERE hosts.status=0 AND items.status=0 GROUP BY proxy.host, items.type ORDER BY 1,2,3 DESC;

Dispositivos y Templates vinculados

Si un servidor funciona como servidor de base de datos, servidor web y servidor de aplicaciones, entonces debe contar con múltiples templates. La siguiente consulta puede ayudar a detectar los templates vinculados.

MySQL:

SELECT proxy.host AS proxy, hosts.host, GROUP_CONCAT(template.host SEPARATOR ', ') AS templates FROM hosts JOIN hosts_templates ON (hosts_templates.hostid=hosts.hostid) LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) LEFT JOIN hosts template ON (hosts_templates.templateid=template.hostid) WHERE hosts.status IN (0,1) AND hosts.flags=0 GROUP BY 1,2 ORDER BY 1,3,2;

PostgreSQL:

SELECT proxy.host AS proxy, hosts.host, ARRAY_TO_STRING(ARRAY_AGG(template.host),', ') AS templates FROM hosts JOIN hosts_templates ON (hosts_templates.hostid=hosts.hostid) LEFT JOIN hosts proxy ON (hosts.proxy_hostid=proxy.hostid) LEFT JOIN hosts template ON (hosts_templates.templateid=template.hostid) WHERE hosts.status IN (0,1) AND hosts.flags=0 GROUP BY 1,2 ORDER BY 1,3,2;
Dispositivos y todos los campos de inventario
SELECT h.host,i.type,i.type_full,i.name,i.alias,i.os,i.os_full,i.os_short,i.serialno_a,i.serialno_b,i.tag,i.asset_tag,i.macaddress_a,i.macaddress_b,i.hardware,i.hardware_full,i.software,i.software_full,i.software_app_a,i.software_app_b,i.software_app_c,i.software_app_d,i.software_app_e,i.contact,i.location,i.location_lat,i.location_lon,i.notes,i.chassis,i.model,i.hw_arch,i.vendor,i.contract_number,i.installer_name,i.deployment_status,i.url_a,i.url_b,i.url_c,i.host_networks,i.host_netmask,i.host_router,i.oob_ip,i.oob_netmask,i.oob_router,i.date_hw_purchase,i.date_hw_install,i.date_hw_expiry,i.date_hw_decomm,i.site_address_a,i.site_address_b,i.site_address_c,i.site_city,i.site_state,i.site_country,i.site_zip,i.site_rack,i.site_notes,i.poc_1_name,i.poc_1_email,i.poc_1_phone_a,i.poc_1_phone_b,i.poc_1_cell,i.poc_1_screen,i.poc_1_notes,i.poc_2_name,i.poc_2_email,i.poc_2_phone_a,i.poc_2_phone_b,i.poc_2_cell,i.poc_2_screen,i.poc_2_notes FROM host_inventory i, hosts h WHERE i.hostid=h.hostid AND h.flags=0;

Por defecto, se imprimen todas las columnas. Es posible eliminar las que no seas necesarias. La información obtenida es útil para usarla en software de análisis, ej., MS EXCEL.

Scripts externos en uso

Al migrar a una nueva versión de Zabbix, es mejor estar al tanto de todos los scripts externos y asegurarse de que el nuevo servidor lo soporte. Un script externo es una solución personalizada para la forma de recopilar datos. Por ejemplo, uno realizado usando Python 2, quizás no esté disponible en un sistema operativo más nuevo listo para usar.

SELECT items.key_,COUNT(*) FROM items JOIN hosts ON (hosts.hostid=items.hostid) WHERE hosts.status=0 AND items.status=0 AND items.type=10 GROUP BY 1 ORDER BY 2;

 

5) Pulir su instancia de Zabbix

Esta sección requerirá un poco más de trabajo. Ser un no-perfeccionista será una ventaja.

Para trabajar con eventos internos (recolección de datos que no funciona, triggers que no funcionan), debemos al menos contar con una acción interna habilitada. Puede ser una acción con una condición que nunca será verdadera.

Tenga cuidado, si tiene una infraestructura enorme y actualmente todo está deshabilitado, ¡entonces no lo habilite! O habilite solo el numero 4 para generar algunas estadísticas y luego desactívelo. Si mantiene los eventos internos ACTIVADOS y muchas cosas no funcionan, afectara al frontend y se verá muy lento. Y se volverá aún más lento cada día.

Recolección de datos

El monitoreo se basa en la recolección de datos. Si no ingresa nueva información, entonces no podremos detectar si un servicio se encuentra en funcionamiento o no. La siguiente consulta listara todos los ítems de recolección de datos que no obtienen información.

SELECT hosts.name, items.key_ AS keyName, problem.name AS error, CONCAT('items.php?form=update&itemid=',objectid) AS goTo FROM problem JOIN items ON (items.itemid=problem.objectid) JOIN hosts ON (hosts.hostid=items.hostid) WHERE problem.source>0 AND problem.object=4;

El resultado nos brindara un link, el cual nos lleva al item y podremos investigar. Entre los problemas más comunes ser encuentra el timeout, credenciales incorrectas o permisos.

Evaluación de triggers

Cuando la información es recolectada, si un item cuenta con un trigger asociado, es posible que se encuentre un problema con la lógica de evaluación. El resultado de la siguiente consulta mostrara porque es importante detectar dicho problema.

SELECT DISTINCT CONCAT('triggers.php?form=update&triggerid=',problem.objectid) AS goTo, hosts.name AS hostName, triggers.description AS triggerTitle, problem.name AS error FROM problem JOIN triggers ON (triggers.triggerid=problem.objectid) JOIN functions ON (functions.triggerid=triggers.triggerid) JOIN items ON (items.itemid=functions.itemid) JOIN hosts ON (hosts.hostid=items.hostid) WHERE problem.source > 0 AND problem.object=0;

Low-level discovery

El propósito de las low-level discovery es descubrir todos los elementos que existen en un sistema en particular. Por ejemplo, encontrar todos los servicios de un sistema Windows. Si el descubrimiento no funciona, entonces elementos adicionales no serán descubiertos, los que resulta en falta de ítems, triggers y notificaciones. La siguiente consulta mostrara todos las reglas (LLD) erróneas y la razón por la cual se encuentra el problema:

SELECT hosts.name AS hostName, items.key_ AS itemKey, problem.name AS LLDerror, CONCAT('host_discovery.php?form=update&itemid=',problem.objectid) AS goTo FROM problem JOIN items ON (items.itemid=problem.objectid) JOIN hosts ON (hosts.hostid=items.hostid) WHERE problem.source > 0 AND problem.object=5;

Eso es todo por hoy.

En la sección de comentarios a continuación, háganos saber qué tipo de informe desea ver su empresa.

Apéndice

Problemas conocidos del modulo:
  • Al vincular tablas en el resultado SQL, si hay varias columnas con el mismo nombre, solo se imprimirá la primera columna. Como solución alternativa, utilice siempre la directiva “AS ColumnName” para especificar nombres de columna únicos en el resultado.
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x