Monitoramento de pobre homem ou monitoramento de servidor a partir do console

Todos são bem-vindos, queridos leitores. Neste artigo, vou falar sobre a minha "bicicleta", na qual monitoro várias coisas sem sair do console.

Certa vez, encontrei uma situação em que muitos projetos e servidores foram criados e minhas mãos não chegaram à configuração do monitoramento normal.

E no mundo moderno, o monitoramento "correto" implica a implantação de um monte de software, a configuração de tudo isso. Bem, você sabe lá ... estivador, pilha elástica e foi embora. Para mim, foi uma sobrecarga forte. Eu queria um ou dois em produção.

Eu olhei para o monitor Simples em python, era o mais próximo de mim em espírito, mas faltam alguns recursos. E, ao mesmo tempo, eu queria aprender Go ... bem, em geral, você mesmo sabe como geralmente tudo começa.

Então peguei a solda Go e montei essa bicicleta .

O Cli Monitoring é escrito em Go e é um conjunto de binários, cada um dos quais recebe dados do stdin, executa alguma tarefa específica e exibe o resultado no stdout.

Existem quatro tipos de binários no total: métricas , processadores , filtros e saídas .

As métricas , como o nome indica, coletam todos os dados e geralmente vão primeiro na cadeia.
Os processadores estão no meio e, de alguma forma, alteram os dados ou executam outras funções utilitárias.
Os filtros são quase como processadores, mas diferentemente deles, eles pulam ou não pulam dados, dependendo da condição.
As saídas estão na saída da cadeia e são usadas para enviar notificações para vários serviços.

Toda a cadeia de comandos geralmente tem a forma:

some_metric | processor_1 | processor_2 ... | cm_p_message | output_1 | output_2 ...

Qualquer parte dessa cadeia pode ser qualquer comando do Linux, desde que receba dados no stdin e os envie ao stdout sem buffer. Há apenas um pequeno, MAS relacionado a quebras de linha, mas mais sobre isso posteriormente.

O nome dos binários é formado como cm_ {type} _ {name} , em que type é um dos três: m, p, f ou o e name é o nome do comando.

Por exemplo, cm_m_cpu é uma métrica que gera estatísticas em um processador no formato json para stdout.

E o arquivo cm_p_debounce é um processador que apenas envia uma mensagem a cada vez em um determinado intervalo.

Há um processador cm_p_message especial que deve estar na frente da primeira saída. Ele cria uma mensagem do formato necessário para processamento subsequente por suas saídas.

Para manipular o json no console e em várias condições, usei o utilitário jq . Isso é algo como sed, apenas para json.

É assim que, por exemplo, o monitoramento da CPU se parece no final.

 cm_m_cpu | cm_p_eot2nl | jq -cM --unbuffered 'if .LoadAvg1 > 1 then .LoadAvg1 else false end' | cm_p_nl2eot | cm_f_regex -e '\d+' | cm_p_debounce -i 60 | cm_p_message -m 'Load average is {stdin}' | cm_o_telegram 

E, portanto, monitorando o número de mensagens na fila RabbitMQ

 while true; do rabbitmqctl list_queues -p queue_name | grep -Po --line-buffered '\d+'; sleep 60; done | jq -cM '. > 10000' --unbuffered | cm_p_nl2eot | cm_f_true | cm_p_message -m 'There are more than 10000 tasks in rabbit queue' | cm_o_opsgenie 

Assim, você pode monitorar que nada foi gravado no arquivo em 10 segundos

 tail -f out.log | cm_p_nl2eot | cm_p_watchdog -i 10 | cm_p_debounce -i 3600 | cm_p_message -m 'No write to out.log for 10 seconds' -s 'alert' | cm_o_telegram 

Não se apresse em fechar a tela, agora analisaremos o que está acontecendo aqui no primeiro exemplo.

1) A métrica cm_m_cpu exibe uma vez por segundo (especificada pelo parâmetro -i, por padrão um segundo) cadeias de caracteres no formato json. Por exemplo, {"LoadAvg1": 2.0332031, "LoadAvg2": 1.9018555, "LoadAvg3": 1.8623047}

2) cm_p_nl2eot é um dos comandos do utilitário que converte o caractere EOT no caractere LF. O fato é que, para evitar problemas com quebra de linha, decidi me certificar de que todos os meus binários leiam dados até o caractere ascii EOT (Fim da transmissão). Isso permite transferir com segurança dados de várias linhas entre equipes.

Portanto, quando quaisquer outros comandos são chamados, eles devem estar cercados no formato:
cm_p_eot2nl | qualquer outra equipe | cm_p_nl2eot.

3) Em seguida, é uma chamada para o utilitário jq , que verifica o campo LoadAvg1 e se é maior que 1, em seguida, exibe mais, se menor, exibe false

4) Em seguida, precisamos lançar a mensagem inteira falsa da cadeia. Para fazer isso, aplicamos o filtro cm_f_regex , que recebe uma string como entrada, a corresponde a uma expressão regular e, no caso de uma correspondência, a exibe mais. Caso contrário, a cadeia é simplesmente descartada

O grep comum pode ser usado, mas primeiro armazena o buffer e a sintaxe completa fica um pouco mais longa (grep --line-buffered); segundo, cm_f_regex facilita a exibição de correspondências de grupo. Por exemplo:

cm_f_regex -e '(\d+)-(\d+)' -o '{1}/{2}'

Converte a linha 123-345 para a linha 123/345

5) O processador cm_p_debounce , nesse caso, pega nosso valor LoadAvg1 e o exibe mais abaixo na cadeia apenas uma vez a cada 60 segundos. Isso é necessário para não enviar spam. Você pode definir qualquer outro intervalo.

6) Quase tudo está pronto. Resta apenas formar uma mensagem e enviá-la para telegramas. A mensagem é gerada pelo comando especial cm_p_message . Ele simplesmente aceita uma string como entrada, cria json com os campos Gravidade, Mensagem e outros e a envia para o processamento de saída. Se não passássemos a opção -m, stdin seria a mensagem, ou seja, número de milho é o nosso LoadAvg1. Isso não é muito informativo.

7) A equipe cm_o_telegram simplesmente envia a mensagem recebida ao telegrama. As configurações do telegrama são armazenadas em um arquivo ini.

Configuração


Todos os parâmetros que aceitam binários podem ser especificados no arquivo ini. Os parâmetros especificados pelo argumento da linha de comandos têm precedência sobre o arquivo ini.

O formato do arquivo init é:

[global]
host_name=override host name for this machine

[telegram]
cid=....
token=....

[opsgenie]
apiToken=...
apiEndpoint=...
......

[debounce]
i=3600


O próprio arquivo ini é selecionado na seguinte ordem:

1) O arquivo cm.config.ini no diretório de trabalho atual
2) O arquivo /etc/cm/config.ini se o arquivo do item 1 não for encontrado

Produção


Em um servidor real, crio um arquivo, por exemplo, cpu.sh, no qual toda a cadeia de comandos necessária é gravada. Então, na coroa, prescrevo algo como isto:

*/5 * * * * flock -n /etc/cm/cpu.lock /etc/cm/cpu.sh > /dev/null

Se algo cair, o re-raise novamente. E isso é tudo! A simplicidade da qual não me faltava.

Essa é uma ferramenta, talvez alguém ache conveniente. Para mim, a conveniência é que não há necessidade de fazer muitas coisas desnecessárias apenas para monitorar as coisas necessárias. E tudo está convenientemente configurado: clonou o repositório, adicionou o caminho aos binários em $ PATH e é isso.

Por favor, não julgue estritamente. A ferramenta foi escrita para mim, o conjunto de comandos ainda não é grande. Mas terei prazer em receber comentários e sugestões. Obrigado a todos pela atenção.

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


All Articles