Zabbix: monitore tudo em uma fileira (no exemplo do Redis)

O Zabbix é um ótimo produto para administradores de grandes sistemas de software e hardware. É tão bom que pode ser usado não apenas por grandes empresas, mas também por pequenas e médias empresas, e até mesmo em um projeto para pet . Em geral, tenho pouca experiência com o Zabbix e posso recomendá-lo com segurança para uso.


É verdade que não posso dizer que entendo a " filosofia do Zabbix ". Apesar da extensa documentação detalhada em russo, foi difícil para mim mergulhar no mundo do Zabbix - tive a sensação de que os desenvolvedores e eu chamamos as mesmas coisas por nomes diferentes. Talvez porque o Zabbix foi criado por administradores para administradores, mas ainda sou mais desenvolvedor e usuário.


No entanto, para executar o Zabbix e monitorar os principais parâmetros dos sistemas de computador (processador, memória, etc.), as habilidades de um usuário regular do Linux são suficientes. Há um grande número de plug-ins de desenvolvedores de terceiros que ampliam os recursos do Zabbix. Para minhas necessidades, eu precisava configurar o monitoramento do servidor Redis. Examinei um pouco o código dos plug-ins disponíveis e, usando o exemplo deles, descobri que a arquitetura do Zabbix permite que você se conecte simplesmente ao monitoramento de quaisquer parâmetros de sistemas de informação que possam ser expressos em forma numérica.


Sob o gato - um exemplo de um plug-in do Zabbix com minha explicação da terminologia do Zabbix. Para alguns, este exemplo parecerá ingênuo, mas para alguns, será mais fácil se acostumar com os conceitos. De qualquer forma, o Zabbix é grande o suficiente para senti-lo de diferentes ângulos.


Conceitos básicos


Brevemente sobre alguns dos conceitos usados ​​no Zabbix: agentes , itens , gatilhos , ações , notificações , modelos .


Servidor e agentes


Do ponto de vista do usuário, o Zabbix é dividido em duas grandes partes: servidor e agentes. O servidor está localizado em uma máquina, que coleta e armazena dados estatísticos e agentes nas máquinas nas quais os dados são coletados:


Servidor e agentes Zabbix


Opções de monitoramento


Qualquer quantidade que possa ser expressa em forma numérica ou de sequência é chamada na terminologia do Zabbix - um elemento de dados (item). Cada elemento está associado a uma chave exclusiva (nome). Aqui estão exemplos de itens de dados:


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

Os valores desses elementos de dados (parâmetros de monitoramento) são anexados ao tempo; o histórico dos valores dos parâmetros é armazenado no banco de dados do servidor.


Eventos


Quando um evento ocorre no Zabbix, um gatilho é acionado. Por exemplo


  • {system.cpu.load [percpu, avg1] .avg (5m)}> 10 - o valor médio do parâmetro nos últimos 5 minutos excedeu "10"
  • {system.uname.diff (0)}> 0 - o valor atual do parâmetro não é igual ao valor anterior

De fato, gatilhos são fórmulas nas quais os parâmetros de monitoramento (atuais e salvos) atuam como variáveis ​​e produzem true / false na saída.


Ações e alertas


No caso de um evento (gatilho), o servidor pode executar uma ação. Por exemplo, envie um alerta de email para um determinado endereço (" Problema: o host fica inacessível por 5 minutos "). Além disso, uma ação pode ser executada se o gatilho retornar ao seu estado original (" Resolvido: o host está inacessível por 5 minutos "). Todos os eventos (comutação de gatilho) são registrados no lado do servidor.


Padrões


O Zabbix possibilita configurar regras de monitoramento para um host individual, além de criar um modelo de regra (modelo) que pode ser aplicado a vários hosts:


modelos do zabbix


O exemplo mostra que o modelo "Serviço SSH do aplicativo de modelo" descreve um aplicativo (Aplicativos), um parâmetro de monitoramento (Itens), um gatilho (Disparadores). Também estão disponíveis descrições de gráficos, telas, regras de descoberta e scripts da web.


Configurando a Tarefa para o Plug-in


Posição inicial


O próprio Zabbix oferece seu próprio plugin para monitorar o status do Redis, mas na minha versão do servidor (4.2.8) eu não consegui usá-lo (plugin para a versão 4.4 e superior). Soluções de terceiros também são oferecidas (cerca de uma dúzia de opções para várias versões do Zabbix, existem apenas as três primeiras na imagem):


Plugins redis para zabbix


Cada um deles tinha suas próprias vantagens e desvantagens, tinha que olhar para dentro para escolher. O melhor, na minha opinião, foi o plugin Shakeeljaveed / zabbix-redis-userparamaters , que consistia em dois arquivos:


  • README.md
  • redis-userparameter.conf

Eu tive que trabalhar um pouco de "canetas", mas no exemplo dele ficou um pouco mais claro como os dados do agente vão para o servidor. Por sugestão do autor Javeed Shakeel, o estado de Redis foi redefinido a cada 2 minutos pela coroa para o /tmp/redismetric :


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

E então cada parâmetro de monitoramento foi extraído pelo agente do /tmp/redismetric usando as ferramentas do próprio sistema operacional. As instruções para isso foram colocadas na configuração do agente Zabbix /etc/zabbix/zabbix_agent.conf.d/userparameter_redis.conf . Por exemplo, é assim que as instruções para recuperar o parâmetro used_memory (uso de memória pelo servidor Redis) são assim:


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

Ou seja, no /tmp/redismetric com a saída do redis-cli INFO , a cadeia de caracteres ( grep -w ... ) é pesquisada pela chave used_memory


 used_memory:7153216 

que é dividido em colunas pelo separador ":" ( cut -d: -f2 ). Na saída, o agente recebe o número 7153216 e o atribui ao parâmetro used_memory .


Resta configurar o servidor por meio da interface baseada na Web para que periodicamente envie solicitações ao agente para receber dados usando o parâmetro used_memory , após o qual os dados começam a ser used_memory no servidor, armazenados no banco de dados, você pode usá-lo para criar gráficos e criar acionadores que respondem a alterações nesse parâmetro.


Finalidade


A tarefa de monitorar o status de qualquer sistema não é apenas a coleta de estatísticas, mas também um aviso sobre a ocorrência de situações que requerem intervenção humana. Como trabalho com o Redis como um usuário muito novato, tive que procurar informações sobre quais parâmetros de "saúde" prestar atenção e o que eles significam. O artigo mais valioso foi " 6 métricas cruciais para o monitoramento de redis que você precisa observar ". Depois de analisá-lo, cheguei à conclusão de que "para a felicidade completa" eu preciso coletar dados para detectar os seguintes eventos:


  • Fragmentação da memória: used_memory_rss / used_memory> 1.5
  • Baixa taxa de acertos do cache: (keyspace_hits) / (keyspace_hits + keyspace_misses) <0.8
  • Conexões rejeitadas: conexões_ rejeitadas> 0
  • Chaves despejadas: evicted_keys> 0

Eu também queria coletar estatísticas sobre parâmetros adicionais (versão Redis, tempo de atividade etc.). Em geral, tendo uma idéia geral de como os dados são coletados pelo agente e transmitidos ao servidor, a Lista de desejos pode ser bastante limitada. Como resultado, obtivemos uma lista de parâmetros para monitoramento de 12 posições.


Crie seu próprio plugin


Opções de monitoramento


O plug-in que analisei assumiu a execução de um comando separado para obter um parâmetro separado (item de dados, item):


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

Ou seja, para obter dados sobre 12 parâmetros, o agente precisará executar vários conjuntos de comandos 12 vezes. E se eu precisar monitorar parâmetros difíceis de extrair por uma cadeia de comandos e precisar escrever um shell script separado ou um programa completo? Para essa "Lista de desejos", o Zabbix oferece uma variante com elementos de dados dependentes. Sua essência é que, no lado do agente, o script forma um conjunto de dados (por exemplo, no formato JSON), que é transmitido ao servidor como um parâmetro de sequência. Em seguida, no lado do servidor, os dados recebidos são analisados ​​e parâmetros elementares individuais são extraídos deles.


Item de dados principal


Descrevi o principal redis.info dados redis.info tipo de sequência com um período de atualização de 1 min, sem salvar o histórico de alterações:


base de itens


Presumivelmente, o seguinte JSON deve ser gerado no lado do 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 } 

após o qual esse texto deve ser redis.info ao servidor como um redis.info dados redis.info , mas não salvo, mas serve como base para outros elementos de dados (parâmetros de monitoramento).


Item de dados dependente


O parâmetro de teste redis.info.version depende de redis.info e armazena seus valores no banco de dados por 90 dias. A frequência do monitoramento de parâmetros depende do elemento base ( redis.info ):


item dependente (base)


O redis.info.version parâmetro redis.info.version é recuperado do valor redis.info usando as instruções JSONPath:


item dependente (pré-processo)


Um esquema semelhante descreve os elementos de dados dependentes restantes (parâmetros de monitoramento), que são transmitidos na forma de JSON. Aqui está um exemplo da descrição do parâmetro numérico redis.info.used_memory :


item de número dependente (base)


Tudo é bastante transparente, com exceção do Trend storage period de Units e Trend storage period . Não entendi o segundo ponto, deixei-o por padrão e as unidades de medida são explicadas na documentação . Nesse caso, o valor de redis.info.used_memory é medido em bytes e minimizado em kilo / mega / giga /...- bytes na interface da web.


A fórmula para extrair um valor de JSON é: JSONPath = $.used_memory


Item de dados computados


Para calcular a fragmentação da memória, a relação used_memory_rss / used_memory é usada e, com base nisso, é determinado um gatilho que dispara quando a taxa excede 1,5. O Zabbix possui um tipo de elemento de dados calculado:


item de cálculo


O valor do parâmetro redis.info.used_memory_ratio calculado a cada minuto com base nos últimos valores de dois outros parâmetros ( redis.info.used_memory_rss e redis.info.used_memory ), é armazenado no banco de dados por 90 dias, etc.


Triggers


Aqui está um exemplo de um gatilho que dispara quando a memória está muito fragmentada:



Nada incomum, exceto o formato de expressão usado na fórmula de alteração do estado do acionador. O Zabbix possui um designer de formulários, você pode usá-lo ou consultar a documentação / exemplos (a lista de gatilhos está disponível na interface da web em " Configuração / Modelos / $ {TemplateName} / Gatilhos ").


Um gatilho pode ser baseado em qualquer elemento de dados (item), independentemente do seu tipo (principal, dependente, calculado).


Configuração do agente


Geração JSON


Para obter os valores dos parâmetros de monitoramento e a formação do JSON, eu 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 esse script no arquivo /var/lib/zabbix/user_parameter/redis/get_info.sh no servidor com Redis, no qual o agente Zabbix já está instalado. O usuário sob o qual o agente Zabbix é zabbix (geralmente zabbix ) deve ter permissão para executar o arquivo get_info.sh .


Arquivo userparameter_XXX.conf


No lado do agente, parâmetros de monitoramento adicionais são userparameter_*.conf no parâmetro do userparameter_*.conf arquivos no diretório userparameter_*.conf . Portanto, para que o agente descubra como ele precisa coletar dados no parâmetro redis.info , criei o arquivo /etc/zabbix/zabbix_agentd.d/userparameter_redis.conf com o seguinte conteúdo:


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

Ou seja, para obter dados no parâmetro redis.info agente deve executar o script /var/lib/zabbix/user_parameter/redis/get_info.sh e transferir o resultado da execução para o servidor.


Após reiniciar o agente Zabbix ( sudo service zabbix-agent restart ), torna-se possível coletar dados para o parâmetro redis.info e enviá-los ao servidor.


Sumário


Compreender o Zabbix veio até mim (e ainda vem) bastante difícil. No entanto, considero uma ótima ferramenta, especialmente após a simplicidade de adicionar meus próprios parâmetros de monitoramento (elementos de dados) abertos para mim. Em geral, basta adicionar um arquivo ao servidor com o agente ( userparameter_XXX.conf ) com um comando shell para coletar dados e configurar o servidor Zabbix para receber esses dados pela interface da web. E é isso - você pode acumular dados, criar gráficos, analisar alterações e criar um gatilho que responda a essas alterações.


O código do modelo, o arquivo userparameter_redis.conf e o script get_info.sh podem ser visualizados no projeto flancer32 / zabbix_plugin_redis .


Obrigado a todos que leram até o fim e, especialmente, àqueles que encontraram algo útil para si na publicação.

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


All Articles