Nesta publicação do blog, lhe mostrarei como com a ajuda de um módulo de frontend personalizado da Zabbix, é possível acrescentar um botão “Exportar à CSV” e usá-lo para obter informação personalizada. Isto pode ser instalado como um módulo de frontend. O requisito é ter PHP 72 ou posterior. Funciona com as versões Zabbix 50 LTS e Zabbix 60 LTS. Como benefício adicional, podemos usar este módulo para melhorar nossa instância da Zabbix, encontrar configurações incorretas, resumir a configuração existente e localizar possíveis gargalos.
Características do módulo
- Definir e armazenar consultas SQL personalizadas no perfil do usuário. Utilizar a tabela “profiles” da base de dados, especificamente as colunas “idx” e “value_str” para armazenar a configuração / dados. Não estamos trocando a estrutura da base de dados, mas utilizando o que já está disponível.
- Exporte uma quantia ilimitada de filas através do botão CSV.
- Compatível com MySQL, PostgreSQL e sintaxe SQL em geral. Utilizar a mesma linguagem que utiliza diretamente no cliente SQL.
- Salientador Baseia-se em um conhecido produto CodeMirror. O módulo da Zabbix continua sendo completamente independente.
- Suporte de hipervínculo para o resultado SQL. É útil para criar um link que possa ser utilizado para aproximar-se do problema. Apenas hipervínculos relacionados com seções da Zabbix (php, triggers.php).
O que não É?
- O módulo não proporciona um ambiente para que os usuários do tipo “Zabbix User” ou “Zabbix Admin” realizem relatórios. Apenas os do tipo “Zabbix Super Admin” podem usar este módulo.
Instalação
A seguir pode encontrar a sequência de comandos utilizados para descarregar e instalar o módulo “Exportar à CSV“.
Navegar ao diretório por defeito para módulos do frontend:
cd /usr/share/zabbix/modules
Selecionar e criar o nome do diretório:
mkdir -p zabbix-module-sqlexplorer
Introduza ao diretório:
cd zabbix-module-sqlexplorer
Descarregue a versão 14 do módulo:
wget https://github.com/gr8b/zabbix-module-sqlexplorer/releases/download/v1.7/v1.7.zip
Extrair o arquivo:
unzip v1.7.zip
Eliminar o arquivo original pois não será necessário:
rm v1.7.zip
Habilitação
Abrir “Administração” => “Geral” => “Módulos” => clicar em “Escanear diretório“. Depois disso, clicar em “Habilitar“:
Uma nova opção de menu está disponível:
Agora podemos fazer uma consulta SQL, ver o resultado na tela e exportar os dados à CSV:
Falemos de 5 casos de uso benéfico que este módulo não possa fornecer. A seguir os engenheiros de suporte técnico da Zabbix compartilham conosco alguns comandos SQL de uso frequente.
1) Assegurar que a compilação de dados básicos funciona
Esta seção seria o mínimo básico a manter. Em um mundo perfeito, cada objeto de host (um dispositivo, um servidor) deve estar on-line as 24 horas por dia, os 7 dias da semana. Para cada categoria (ZBX, SNMP, IPMI, JMX) precisamos usar uma consulta dedicada. Trabalhemos com os 2 tipos de categorias mais populares: ZBX e SNMP.
Hosts com agente da Zabbix inatingível (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;
No resultado, obtemos um objeto do tipo proxy, título do host, uma mensagem de erro e um link para navegar diretamente ao objeto.
Por cada fila no resultado, precisamos: 1) Solucionar o problema. O mais provável é que seja um problema de firewall / DNS / credencial / tempo de espera ou de qualidade de rede; 2) Eliminar o objeto host; ou 3) Desabilitar o objeto host.
Hosts de rede intangíveis (SNMP)
No 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;
No 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;
Recebemos o título do proxy, o objeto host, o motivo pelo qual o host não funciona e um link no qual pode se clicar no objeto.
2) Melhorar a velocidade do frontend
Assegurar-se de que temos o melhor tempo de resposta para todas as seções na GUI. Se as tabelas contém dados “não necessários”, a experiência de usuário sofrerá por isso. Hoje em dia, ninguém quer passar mais do que uns segundos esperando que os dados sejam mostrados na tela.
Quantidade de sessões de usuário
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;
O número total de sessões não deve exceder os 1000; É difícil imaginar o motivo de ser mais de 100. É possível eliminar todos os dados da tabela “sessions” e otimizar/esvaziar a tabela. Isto melhorará a capacidade de resposta e o rendimento geral da GUI da Zabbix.
Não manter muitos problemas abertos
As ferramentas de monitoramento tratam de identificar problemas. Se mantiver muitos problemas abertos, então o frontend será lento. A seguinte consulta mostrará como resultado problemas de triggers (os que recebemos no e-mail) e problemas internos, que refletem o estado da ferramenta de monitoramento.
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 diminuir o número de problemas “internos“, atente especialmente ao ponto n° 5 deste blog post.
3) Identificar exceções
Os administradores de monitoramento podem alterar o intervalo de atualização para os itens em nível de host, podem configurar uma entrada de trigger em nível de host ou instalar uma entrada diferente dentro de uma árvore de templates incorporados. Esta seção destacará todas as exceções.
O intervalo de atualização defere entre os níveis de host/template
A seguinte consulta, mostrará como resultado itens e regras de LLD que têm diferentes intervalos de atualização em nível host, enquanto os compara em nível template. A maior parte do tempo, se realiza de forma acidental, contar com diferentes intervalos de atualização em nível host .
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;
No resultado, a coluna “Source” é um objeto host (um dispositivo) ou um objeto de template. A coluna “Source” está muito relacionada com a coluna “exceptionInstalledOn“. “Source” VS “exceptionInstalledOn” praticamente indica que existe uma relação entre um host e um template ou entre um template e outro template.
A coluna “FrequencyChild” é o campo mais importante, já que descreve uma exceção instalada que difere do objeto original.
O resultado permite navegar diretamente no item onde se destaca o intervalo de atualização.
Características de conexão e entradas de triggers à medida
A consulta mostrará cada anulação configurada entre o host e o objeto de template ou entre o template e o objeto de template principal. Se a incorporação de template é utilizada em vários níveis, destacará se um valor primordial está instalado em algum lugar no meio.
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;
Itens abandonados
Itens que não pertencem a nenhum 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 manter a administração centralizada, seria melhor movimentar e manter a definição do item em nível template.
4) Reportes
É possível resumir as configurações de um item ou host, os itens de coleta de dados habilitados ou desabilitados e os templates vinculados.
Que método de coleta de dados é utilizado?
Para resumir todos os métodos de coleta de dados e sua relação com os da Zabbix Proxy, utilize o seguinte 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 e Templates vinculados
Se um servidor funciona como servidor de base de dados, servidor web e servidor de aplicativos, então deve ter múltiplos templates. A seguinte consulta pode ajudar a detectar os 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 e todos os campos de inventário
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 padrão, são impressas todas as colunas. É possível eliminar as que não sejam necessárias. A informação obtida é útil para usá-la no software de análise, ex., MS EXCEL.
Scripts externos em uso
Ao migrar a uma nova versão de Zabbix, é melhor conhecer todos os scripts externos e assegurar-se de que o novo servidor o suporte. Um script externo é uma solução personalizada para a forma de recoletar dados. Por exemplo, um realizado usando Python 2, talvez não esteja disponível em um sistema operacional mais novo pronto 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) Melhorar sua instância da Zabbix
Esta seção requererá um pouco mais de trabalho. Ser um não perfeccionista será uma vantagem.
Para trabalhar com eventos internos (coleta de dados que não funciona, triggers que não funcionam), devemos pelo menos contar com uma ação interna habilitada. Pode ser uma ação com uma condição que nunca será verdadeira.
Tenha cuidado, se tem uma infraestrutura enorme e atualmente todo está desabilitado, então não o habilite! Ou habilite apenas o número 4 para gerar algumas estatísticas e depois desative. Se mantiver os eventos internos ATIVADOS e muitas coisas não funcionam, afetará o frontend e ficará muito lento. E ficará ainda mais lento a cada dia.
Coleta de dados
O monitoramento se baseia na coleta de dados. Se não ingressar com uma nova informação, então não poderemos detectar se um serviço está funcionando ou não. A seguinte consulta listará todos os itens de coleta de dados que não obtiverem informação.
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;
O resultado nos dará um link, o qual nos leva ao item e poderemos pesquisar. Entre os problemas mais comuns está o timeout, credenciais incorretas ou permissões.
Avaliação de triggers
Quando a informação é coletada, se um item tiver um trigger associado, é possível que seja encontrado um problema com a lógica de avaliação. O resultado da seguinte consulta mostrará porque é importante detectar o referido 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
O propósito das low-level discovery é descobrir todos os elementos que existem em um sistema em particular. Por exemplo, encontrar todos os serviços de um sistema Windows. Se a descoberta não funciona, então elementos adicionais não serão descobertos, o que resulta em falta de itens, triggers e notificações. A seguinte consulta mostrará todas as regras (LLD) erradas e o motivo pelo qual encontra-se o 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;
É tudo por hoje.
Na seção de comentários a seguir, nos informe que tipo de relatório deseja ver na sua empresa.
Apêndice
Problemas conhecidos do módulo:
- Ao vincular tabelas no resultado SQL, se existem várias colunas com o mesmo nome, apenas se imprimirá a primeira coluna. Como solução alternativa, utilizar sempre a diretiva “AS ColumnName” para especificar nomes de coluna únicos no resultado.