Um alerta que chega só por e-mail é um incidente sem dono. A integração entre o Zabbix e o GLPI existe para transformar cada problema detetado num pedido rastreável - com número, responsável, categoria, prioridade e SLA - e para o fechar sozinho quando o Zabbix confirma a recuperação. O segredo não está em "criar o pedido": está em não criar quarenta.
O que a integração tem de entregar
Uma ponte Zabbix para GLPI que aguenta produção precisa de quatro garantias, não apenas de "publicar um pedido":
- Idempotência: um problema abre um pedido, não um por cada passo de escalonamento.
- Correlação problema/recuperação: o evento de recovery tem de encontrar e fechar exatamente o pedido que abriu.
- Mapeamento de severidade: a severidade do Zabbix passa a prioridade do GLPI de forma consistente, não ao critério de cada analista.
- Contexto suficiente: host, IP, trigger, hora e mensagem no corpo, para o analista agir sem abrir o Zabbix.
Arquitetura: onde o webhook se torna pedido
O Zabbix dispara por uma Action; a Action executa uma operação de média do tipo Webhook; o Webhook é um script JavaScript nativo do Zabbix que faz um POST para um endpoint do lado do GLPI. Do lado do GLPI usamos o receiver do módulo Automações, que valida a assinatura HMAC, aplica o mapa de campos e cria (ou fecha) o pedido. Evitamos chamar a API REST do GLPI diretamente a partir do Zabbix porque cada chamada exigiria o par app-token/user-token e um par initSession/killSession - sob uma tempestade de alertas isso martela a API e ainda esgota sessões.
Artefacto: o Media Type webhook do Zabbix
Os parâmetros mapeiam macros do evento; o script monta o payload e trata o código HTTP. Problema e recuperação usam o mesmo Media Type - o campo event_value distingue-os (1 = problema, 0 = recuperação):
// Zabbix -> Media type -> Webhook -> Parametros
// endpoint = https://glpi.cliente.com/plugins/nextool/automations/webhook/zabbix
// event_id = {EVENT.ID} // estavel no par problema/recovery
// event_value = {EVENT.VALUE} // 1 = problema, 0 = recuperacao
// host_name = {HOST.NAME}
// host_ip = {HOST.IP}
// trigger_name = {TRIGGER.NAME}
// severity = {TRIGGER.SEVERITY}
// occurred = {EVENT.DATE} {EVENT.TIME}
// message = {ALERT.MESSAGE}
// hmac = {$NEXTOOL_HMAC} // macro secreta, nunca no corpo do alerta
var p = JSON.parse(value);
var req = new HttpRequest();
req.addHeader('Content-Type: application/json');
req.addHeader('X-Nextool-Signature: ' + p.hmac);
var payload = JSON.stringify({
event_id: p.event_id,
recovery: p.event_value === '0',
host: p.host_name,
host_ip: p.host_ip,
trigger: p.trigger_name,
severity: p.severity,
occurred: p.occurred,
message: p.message
});
var resp = req.post(p.endpoint, payload);
var code = req.getStatus();
if (code < 200 || code >= 300) {
Zabbix.log(3, '[nextool] falha HTTP ' + code + ': ' + resp);
throw 'Envio para o GLPI falhou: HTTP ' + code;
}
return resp;
Mapa de severidade Zabbix para prioridade GLPI
O Zabbix tem seis severidades; o GLPI, cinco prioridades. Fixamos o mapa no receiver para não o deixar ao critério de cada analista:
| Severidade Zabbix | Prioridade GLPI | Abre pedido? |
|---|---|---|
| Not classified / Information | - | Não (só registo) |
| Warning | Baixa | Sim |
| Average | Média | Sim |
| High | Alta | Sim |
| Disaster | Muito alta | Sim + aciona o piquete |
Deduplicação e fecho automático
Este é o ponto que separa uma integração de brincar de uma que sobrevive em produção. Ao abrir o pedido, o receiver grava o tickets_id do GLPI como tag do evento no Zabbix (ou numa tabela de correlação indexada por event_id). Quando o Zabbix envia o recovery com o mesmo event_id, o receiver localiza esse pedido e adiciona um seguimento de recuperação - ou fecha-o, conforme a política do cliente. Sem essa chave, o recovery não sabe qual dos pedidos fechar e vai acumulando pedidos abertos de problemas já resolvidos.
Erros comuns que corrigimos na manutenção
Na manutenção do dia a dia, o incidente mais comum não é o alerta que nunca se torna pedido - é o alerta que se torna quarenta. Uma interface em flapping às 3h da madrugada abriu dezenas de pedidos idênticos porque a Action disparava a cada passo de escalonamento e o receiver não deduplicava. A correção tem dois lados: no Zabbix, dependência de trigger, histerese na expressão de recovery e operação de média só no primeiro passo; no GLPI, idempotência por event_id. Outros dois erros recorrentes: enviar a categoria do pedido como texto livre (o GLPI espera um itilcategories_id numérico - um texto novo não corresponde e o pedido fica sem categoria) e colocar o segredo HMAC no corpo do alerta em vez de numa macro protegida como {$NEXTOOL_HMAC}.
Métodos de integração comparados
| Método | Sem código? | Dedup/recovery | Quando usar |
|---|---|---|---|
| Módulo Automações (receiver) | Sim (mapa por JSONPath) | Nativo por event_id | Padrão para a maioria dos clientes |
| API REST do GLPI direta | Não | É o utilizador que a implementa | Sem o módulo; poucos hosts |
| Script externo (Python/Bash) | Não | O utilizador implementa e mantém | Regras de negócio fora do padrão |
Se a sua operação já corre Zabbix mas os alertas morrem numa caixa de e-mail que ninguém lê, a NexTool implementa esta ponte com o módulo Automações e mantém as regras afinadas na manutenção - triggers, mapa de severidade e política de fecho. Conheça o módulo Automações.
Este conteúdo foi produzido com o apoio de inteligência artificial e revisto pela equipa da Nextool Solutions.