Métricas sobre cualquier tabla
Si un número se puede calcular con un select, puede ser un ítem de Zabbix. En este ejemplo, una tabla de pedidos se convierte en ítems, una gráfica y una alerta por canal de venta, escribiendo solo SQL y unas líneas de XML.
Los datos
Una tienda online guarda cada pedido en una tabla llamada orders. Cada fila tiene la hora de creación, el canal de venta (web, tienda física, app móvil) y el importe.
Queremos saber, para cada canal, cuántos pedidos han entrado en la última hora, verlo en una gráfica y recibir una alerta si un canal deja de vender.
El usuario de base de datos que usa Databbix solo necesita permiso de lectura sobre esta tabla.
| id | created | channel | amount |
|---|---|---|---|
| 10421 | 2026-09-30 12:58:02 | web | 49.90 |
| 10422 | 2026-09-30 12:58:40 | store | 120.00 |
| 10423 | 2026-09-30 12:59:11 | web | 15.50 |
| 10424 | 2026-09-30 12:59:37 | app | 32.00 |
| 10425 | 2026-09-30 13:00:05 | web | 78.25 |
La consulta
Las consultas se escriben en ficheros XML. Cree uno propio, por ejemplo /etc/databbix/query-shop.xml, para que las actualizaciones del paquete no lo sobrescriban.
select="FILTER": la sentencia devuelve una fila por canal y cada ítem de Zabbix se queda con su fila.<parameter column="channel">: el parámetro de la clave del ítem,[web], se compara con la columnachannel.<item>: cada ítem toma el valor de una columna. Una consulta alimenta tantos ítems como columnas devuelva: aquí, número de pedidos e importe.default="0": si un canal no tiene pedidos en la última hora, no tiene fila, y el ítem vale0en lugar de «no soportado». Justo eso es lo que permite la alerta.maxCache="60": el resultado se reutiliza durante 60 segundos.
La primera consulta es un descubrimiento: lista los canales para que Zabbix cree los ítems de cada uno automáticamente, también los de canales nuevos en el futuro.
<?xml version="1.0" encoding="UTF-8"?> <Queries engine="Database" query="2.5.0"> <!-- Un ítem por canal de venta, creado por Zabbix --> <query name="ShopChannels" module="SHOP" discovery="yes"> <sql><![CDATA[ select code as channel from sales_channels where active ]]></sql> <item name="shop.channel.discovery"/> <field name="CHANNEL" column="channel"/> </query> <!-- Pedidos e importe por canal, última hora --> <query name="ShopOrders" module="SHOP" select="FILTER" maxCache="60"> <sql><![CDATA[ select channel, count(*) as orders, sum(amount) as amount from orders where created > now() - interval '1 hour' group by channel ]]></sql> <parameter column="channel" order="1" type="STRING"/> <item name="shop.orders.count" column="orders" default="0"/> <item name="shop.orders.amount" column="amount" default="0"/> </query> </Queries>
El monitor
Un fichero de monitor conecta con la base de datos e indica qué host de Zabbix recibe los valores. Name tiene que coincidir con el Host name del host en Zabbix.
Guárdelo en /etc/databbix/dbs/ y reinicie el servicio: Databbix arranca un monitor por fichero.
[General] Name = SHOPDB Engine = Database QueryFile = /etc/databbix/query-shop.xml [Zabbix] Server = zabbix.example.com Port = 10051 [Data] Module = SHOP [Database] DBDriver = PGsql ConnectionString = host=shopdb dbname=shop UserName = zabbix Password = ********
Pruébelo
Antes de tocar Zabbix, queryexplorer carga la misma configuración y calcula cualquier clave de ítem a demanda, igual que lo haría el monitor. Si el XML o la conexión tienen algún problema, lo dice en el momento.
Fíjese en la última línea: el canal kiosk no tiene pedidos, así que el ítem toma su valor por defecto.
$ sudo -u databbix /opt/trustserver/bin/queryexplorer -l -f shopdb.conf QueryExplorer> get shop.orders.count[web] Item: shop.orders.count[web], value: 312 QueryExplorer> get shop.orders.amount[web] Item: shop.orders.amount[web], value: 15840.35 QueryExplorer> get shop.orders.count[kiosk] Item: shop.orders.count[kiosk], value: 0
En Zabbix
En el host SHOPDB (o, mejor, en una plantilla), cree:
- Una regla de descubrimiento de tipo Zabbix agent (active) con clave
shop.channel.discovery. - Dos prototipos de ítem, también Zabbix agent (active):
shop.orders.count[{#CHANNEL}]yshop.orders.amount[{#CHANNEL}]. - Un prototipo de disparador que salte cuando un canal deje de vender.
A partir de ahí tiene el histórico de cada canal, gráficas, paneles y alertas, con las mismas herramientas que usa para sus servidores.
Una caída a cero en una métrica de negocio suele ser la primera señal de un fallo técnico: una pasarela de pago caída, un despliegue roto, un certificado caducado. En la gráfica de arriba, la alerta saltó mientras todos los servidores seguían en verde.
# Nombre Ningún pedido {#CHANNEL} en la última hora # Expresión last(/SHOPDB/shop.orders.count[{#CHANNEL}])=0 # Ítems resultantes shop.orders.count[web] shop.orders.amount[web] shop.orders.count[store] shop.orders.amount[store] shop.orders.count[app] shop.orders.amount[app]
La misma receta, cualquier métrica
Cambie el SQL y tendrá otro indicador. Algunas ideas que funcionan igual:
Facturas pendientes
Facturas aún no enviadas a Hacienda o al cliente, por empresa, con alerta cuando crece la cola.
Stock bajo mínimos
Número de productos por debajo de su punto de pedido, por almacén.
Pagos fallidos
Transacciones rechazadas en los últimos minutos, por medio de pago.
Trabajos y colas atascados
Procesos batch en error, mensajes esperando en una tabla de integración, antigüedad del registro pendiente más viejo.
Niveles de servicio
Tiempo medio entre que se crea un ticket o un pedido y se atiende, por equipo.
Frescura de los datos
Minutos desde que un ETL o un proceso de replicación cargó la última fila.
El motor Database en el manual Guía práctica: crear una consulta nueva