Monitoreo del pobre o monitoreo del servidor desde la consola

Todos bienvenidos queridos lectores. En este artículo te contaré acerca de mi "bicicleta", en la que hago un seguimiento de varias cosas sin salir de la consola.

Una vez me encontré con una situación en la que se criaron muchos proyectos y servidores diferentes, y mis manos no llegaron a configurar la supervisión normal.

Y en el mundo moderno, el monitoreo "correcto" implica el despliegue de un montón de software, la configuración de todo esto. Bueno, ya sabes ... acoplable, pila elástica y fuera. Para mí fue una fuerte sobrecarga. Quería uno o dos en producción.

Miré hacia el monitor Simple en una pitón, estaba más cerca de mí en espíritu, pero carecía de algunas características. Y al mismo tiempo quería aprender Go ... bueno, en general, tú mismo sabes cómo suele comenzar todo.

Así que tomé la soldadura Go y armé esta bicicleta .

Cli Monitoring está escrito en Go y es un conjunto de binarios, cada uno de los cuales recibe datos de stdin, realiza una tarea específica y muestra el resultado en stdout.

Hay cuatro tipos de binarios en total: métricas , procesadores , filtros y salidas .

Las métricas , como su nombre lo indica, recopilan cualquier información y generalmente van primero en la cadena.
Los procesadores están en el medio y de alguna manera cambian los datos o realizan otras funciones de utilidad.
Los filtros son casi como procesadores, pero a diferencia de ellos, omiten o no omiten datos, dependiendo de la condición.
Las salidas están a la salida de la cadena y se utilizan para enviar notificaciones a varios servicios.

La cadena completa de comandos generalmente tiene la forma:

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

Cualquier parte de esta cadena puede ser cualquier comando de Linux, siempre que reciba datos en stdin y los envíe a stdout sin almacenamiento en búfer. Solo hay un PERO pequeño relacionado con los saltos de línea, pero más sobre eso más adelante.

El nombre de los archivos binarios se forma como cm_ {type} _ {name} , donde type es uno de tres: m, p, f u o , y name es el nombre del comando.

Por ejemplo, cm_m_cpu es una métrica que genera estadísticas en un procesador en formato json para stdout.

Y el archivo cm_p_debounce es un procesador que solo deja salir un mensaje cada vez en un intervalo dado.

Hay un procesador especial cm_p_message que debe estar delante de la primera salida. Crea un mensaje del formato requerido para su posterior procesamiento por sus salidas.

Para manejar json en la consola y varias condiciones, utilicé la utilidad jq . Esto es algo así como sed, solo para json.

Así es como, por ejemplo, la supervisión de la CPU se ve al 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 

Y así, monitoreando el número de mensajes en la cola 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 

Para que pueda controlar que no se haya escrito nada en el archivo en 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 

No se apresure a cerrar la pantalla, ahora analizaremos lo que está sucediendo aquí en el primer ejemplo.

1) La métrica cm_m_cpu muestra cadenas de una vez por segundo (especificado por el parámetro -i, por defecto un segundo) en formato json. Por ejemplo, {"LoadAvg1": 2.0332031, "LoadAvg2": 1.9018555, "LoadAvg3": 1.8623047}

2) cm_p_nl2eot es uno de los comandos de utilidad que convierte el carácter EOT en el carácter LF. El hecho es que, para evitar problemas con el ajuste de línea, decidí asegurarme de que todos mis archivos binarios lean los datos hasta el carácter ascii EOT (Fin de la transmisión). Esto le permite transferir de forma segura datos de varias líneas entre equipos.

Por lo tanto, cuando se llama a cualquier otro comando, debe estar rodeado de la forma:
cm_p_eot2nl | cualquier otro equipo | cm_p_nl2eot.

3) Lo siguiente es una llamada a la utilidad jq , que verifica el campo LoadAvg1 y si es mayor que 1, luego lo muestra más, si es menos, muestra falso

4) A continuación, tenemos que arrojar todo el mensaje falso de la cadena. Para hacer esto, aplicamos el filtro cm_f_regex , que toma una cadena como entrada, la combina con una expresión regular y, en el caso de una coincidencia, la muestra más. De lo contrario, la cadena simplemente se descarta

Se podría usar grep ordinario, pero en primer lugar amortigua la salida, y la sintaxis completa se vuelve un poco más larga (grep --line-buffered), en segundo lugar cm_f_regex hace que sea muy fácil mostrar coincidencias de grupo. Por ejemplo:

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

Convierte la línea 123-345 en la línea 123/345

5) El procesador cm_p_debounce , en este caso, toma nuestro valor LoadAvg1 y lo muestra más abajo en la cadena solo una vez cada 60 segundos. Esto es necesario para no enviarte spam. Puede configurar cualquier otro intervalo.

6) Casi todo está listo. Solo queda formar un mensaje y enviarlo a telegramas. El mensaje es generado por el comando especial cm_p_message . Simplemente acepta una cadena como entrada, crea json con la gravedad, el mensaje y otros campos y luego la emite para el procesamiento de salida. Si no le pasamos la opción -m, entonces stdin sería el mensaje, es decir El número de mijo es nuestro LoadAvg1. Esto no es muy informativo.

7) El equipo cm_o_telegram simplemente envía el mensaje recibido al telegrama. La configuración de Telegram se almacena en un archivo ini.

Configuracion


Todos los parámetros que aceptan binarios se pueden especificar en el archivo ini. Los parámetros especificados por el argumento de la línea de comando tienen prioridad sobre el archivo ini.

El formato del archivo init es:

[global]
host_name=override host name for this machine

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

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

[debounce]
i=3600


El archivo ini se selecciona en el siguiente orden:

1) El archivo cm.config.ini en el directorio de trabajo actual
2) El archivo /etc/cm/config.ini si no se encuentra el archivo del elemento 1

Producción


En un servidor real, creo un archivo, por ejemplo, cpu.sh, en el que se escribe toda la cadena de comandos necesaria. Luego en la corona prescribo algo como esto:

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

Si algo se cae, el rebaño volverá a levantar el comando. ¡Y eso es todo! La simplicidad de la que no me faltaba.

Esta es una herramienta así, tal vez alguien lo encuentre conveniente. Para mí, la conveniencia es que no hay necesidad de hacer muchas cosas innecesarias solo para monitorear las cosas necesarias. Y todo está convenientemente configurado: clonó el repositorio, agregó la ruta a los binarios en $ PATH y eso es todo.

Por favor no juzgues estrictamente. La herramienta fue escrita para mí, el conjunto de comandos aún no es grande. Pero me complacerá cualquier comentario y sugerencia. Gracias a todos por su atención.

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


All Articles