Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

A veces es necesario realizar un monitoreo rápido para un nuevo servicio, y no hay infraestructura/experticia disponible. En esta guía, implementaremos en media hora una herramienta para monitorear cualquier servicio web, utilizando únicamente las herramientas integradas de ubuntu: bash, cron y curl. Para la entrega de notificaciones, usaremos telegram.

La "cereza del pastel" será la participación emocional de los usuarios. Comprobado con personas: funciona.

Cuando creamos un chatbot para determinar el nivel de estrés de los usuarios en el servicio de telemedicina Doctor Rядом, necesitábamos monitoreo. En unas pocas horas se realizó un mini-proyecto que no solo funciona excelentemente, sino que también agrega positividad con sus mensajes.

Para empezar, obtenemos el repositorio con los scripts:

git clone https://github.com/rshekhovtsov/msms.git

Entramos en la carpeta msms y trabajamos allí.

Si telegram está bloqueado, usa un proxy. La opción más simple y confiable es torsocks:

sudo apt install tor
sudo apt install torsocks

Como ejemplo, configuraremos en tres pasos el monitoreo de la página de inicio google.com

PASO 1. Creamos un bot en telegram y obtenemos el id del usuario

  • En la barra de búsqueda de contactos en telegram buscamos @botfather:

    Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

  • Lo iniciamos con el botón Start, ingresamos el comando /newbot y respondemos a las preguntas. Hay que tener en cuenta que el name es el nombre del bot que se mostrará a los usuarios, mientras que el username es único y debe terminar en "bot":

    Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

    Entre otras cosas, el bot proporcionará un token secreto para la API HTTP, que debemos copiar y guardar en el archivo telegram-api-key.txt en la carpeta msms.

  • Escribimos en la barra de búsqueda de telegram el nombre de nuestro bot y lo iniciamos.
  • Como toque final, agreguemos nuestro nombre a la lista de destinatarios de las notificaciones de monitoreo:
    sudo chmod +x ./recipients-setup.sh
    torsocks ./recipients-setup.sh

    El script mostrará una lista de las últimas interacciones con el bot, debería haber una línea con nuestro id y nombre en telegram. Tomamos este id y lo guardamos en el archivo services/google-recipients.txt. El formato del archivo: cada línea corresponde a un id. Ejemplo:

    123456789
    987654321

Para agregar un nuevo destinatario, hay que pedirle que inicie el bot en telegram, ejecute recipients-setup.sh y agregue id al archivo.

PASO 2. Configuramos el monitoreo

La descripción del servicio se realiza creando un archivo ini en la carpeta services. Se deben establecer cinco parámetros:

  1. MSMS_SERVICE_NAME: nombre del servicio — se utilizará en las notificaciones y el registro de monitoreo.
  2. MSMS_SERVICE_ENDPOINT: endpoint del servicio al que vamos a acceder con curl.
  3. MSMS_CURL_PARAMS: parámetros adicionales de curl, consulte el ejemplo a continuación.
  4. MSMS_EXPECTED: respuesta esperada del servicio. Se utiliza si la respuesta es corta.
  5. MSMS_EXPECTED_FILE: nombre del archivo con la respuesta esperada del servicio. Si se especifica, sobrescribe MSMS_EXPECTED.
  6. MSMS_RECIPIENTS: archivo con la lista de destinatarios de las notificaciones.

La solicitud a google.com devuelve un html fijo con redirección, lo utilizaremos como respuesta esperada del servidor:

curl google.com > services/google-response.html

Crearemos el archivo services/google.ini:

MSMS_SERVICE_NAME='página principal de google'

# endpoint del servicio
MSMS_SERVICE_ENDPOINT='google.com'

# parámetros de curl
MSMS_CURL_PARAMS='-s --connect-timeout 3 -m 7'

# respuesta esperada del servicio
MSMS_EXPECTED_FILE='google-response.html'

# archivo de lista de destinatarios
MSMS_RECIPIENTS='google-recipients.txt'

En MSMS_CURL_PARAMS se puede especificar todo lo que curl puede hacer, incluyendo:

  1. Desactivar los mensajes de curl para no llenar la consola y el log: -s
  2. Establecer el tiempo de espera de conexión con el servicio que se está verificando (en segundos): --connect-timeout 3
  3. Establecer el tiempo de espera para obtener una respuesta: -m 7
  4. Desactivar la verificación del certificado para SSL (por ejemplo, si se usa un certificado autosignado): --insecure
  5. Especificar el tipo de solicitud http: -X POST
  6. Especificar encabezados: -H "Content-Type: application/json"
  7. Especificar el cuerpo de la solicitud como cadena o archivo. Ejemplo para archivo: -d @request.json

Desactivamos las notificaciones y establecimos tiempos de espera de 3 segundos para la conexión y 7 segundos para obtener la respuesta del servicio.

Atención: especifique los valores de los parámetros entre comillas simples, como en el ejemplo. Desafortunadamente, bash es bastante frágil en este sentido, y una comilla mal colocada podría llevar a errores complicados de diagnosticar.

Hemos configurado el monitoreo. Verificaremos que todo esté bien:

sudo chmod +x ./monitoring.sh
torsocks ./monitoring.sh

El script debería mostrar un mensaje tipo:

2020-01-10 12:14:31
health-check "página principal de google": OK

PASO 3. Configurando el horario

Configurar el horario de monitoreo en cron:

sudo crontab -e

Agregaremos una línea para verificar google.com cada minuto:

*/1 * * * * torsocks /monitoring.sh >> /monitoring.log 2>&1

Agregaremos cada día a las 11:00 una notificación que confirme el funcionamiento del monitoreo. Para ello, pasaremos el parámetro DAILY al script:

0 11 * * * torsocks /monitoring.sh DAILY >> /monitoring.log 2>&1

2>&1 — técnica estándar que redirige errores al flujo de salida principal. Como resultado, también llegarán al registro de monitoreo.

Guardamos los cambios y los recogemos con el equipo:

 sudo service cron reload

Para más información sobre la configuración de cron, se puede leer, por ejemplo, aquí.

Así, cada minuto se ejecutará un script de monitoreo que mediante curl consultará google.com. Si la respuesta obtenida difiere de la esperada, el script enviará una notificación a la lista de destinatarios en telegram. El registro de verificaciones se lleva en el archivo monitoring.log

Si es necesario agregar otro servicio, simplemente creamos un nuevo archivo ini para él en la carpeta services y, si es necesario, formamos una lista de destinatarios por separado. Todo lo demás funcionará automáticamente.

Si el servicio verificado se vuelve inaccesible, la notificación llegará cada minuto. Si no se puede restaurar rápidamente el servicio, se pueden desactivar temporalmente las notificaciones en las propiedades del bot en telegram.

Ahora analicemos en detalle las funcionalidades adicionales y la implementación de los scripts.

Plantillas de mensajes y involucramiento emocional

Para hacer la comunicación con el bot más dinámica, lo llamamos Manechka, le agregamos una imagen de avatar correspondiente y contratamos a profesionales de relaciones públicas para crear los textos de los mensajes. Puedes utilizar nuestros desarrollos o cambiarlos a tu gusto.

Por ejemplo así:

Bot para el monitoreo de servicios web en media hora: telegram + bash + cron
o incluso así:

Bot para el monitoreo de servicios web en media hora: telegram + bash + cron
¿Por qué no?

El nombre del bot y el avatar se establecen a través de @botfather.
Las plantillas de mensajes se encuentran en la carpeta templates:

  • curl-fail.txt: mensaje enviado en caso de que curl devuelva un código de error diferente de cero. Normalmente indica que no se puede acceder al servicio.
  • daily.txt: mensaje diario que confirma que el monitoreo del servicio está funcionando.
  • service-fail.txt: mensaje enviado en caso de que la respuesta del servicio difiera de la esperada.

Analizamos las posibilidades de personalización tomando como ejemplo las plantillas de mensajes integradas.
En las plantillas se utilizan emojis. Desafortunadamente, habr no los muestra.
Para encontrar emojis, es conveniente utilizar la búsqueda en emojipedia.org:

Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

Simplemente copia y pega el símbolo adecuado en el texto de la plantilla (es unicode común).

  1. curl-fail.txt:
    Gatito, ayúdame... 
    No puedo acceder al servicio "$MSMS_SERVICE_NAME" 
    `CURL EXIT CODE: $EXIT_CODE`

    Hemos utilizado el nombre del servicio que hemos establecido (variable MSMS_SERVICE_NAME) y una variable interna del script con el código de salida de curl (EXIT_CODE). También hemos formateado el mensaje utilizando el marcado telegram markdown: los caracteres "`" encierran texto de ancho fijo. Dado que las comillas y los apóstrofes son caracteres reservados de bash, los escapamos con el carácter "". Los nombres de variables se preceden con el signo "$".

    Resultado:

    Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

  2. service-fail.txt:
    Gatito, ayúdame...
    El servicio "$MSMS_SERVICE_NAME" me ha decepcionado
    No está funcionando correctamente, esto es lo que me responde:
    `$RESPONSE`

    Resultado:

    Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

    Aquí usamos otra variable de script: RESPONSE. Contiene la respuesta del servicio.

  3. daily.txt:
    ¡Hola, pequeño!
    Estoy bien, vigilando el servicio:
    "$MSMS_SERVICE_NAME" cada minuto...
    ¿Y tú cómo estás?
    

    Resultado:

    Bot para el monitoreo de servicios web en media hora: telegram + bash + cron

Pasemos a la implementación de scripts.

Script de monitoreo

monitoring.sh realiza un auto-descubrimiento simple: toma todos los archivos ini de la carpeta services y para cada uno ejecuta el script principal con la lógica de verificación y envío de notificaciones:

#!/bin/bash
cd $(dirname "$0")/services

for service_ini  in $(ls *.ini); do
    bash ../msms.sh "$1" "$service_ini"
done

Para generar un mensaje diario sobre el estado del monitoreo, se puede pasar el parámetro DAILY al script.

Tenga en cuenta que al iniciar el script, la carpeta actual cambia a services. Esto permite que los archivos ini indiquen rutas a archivos relativas a services.

Script de verificación y envío de notificaciones

msms.sh contiene la lógica principal para verificar el servicio y enviar notificaciones.

Trabajo con Telegram:

# telegram endpoint
TG_API_URL="https://api.telegram.org/bot$(cat ../telegram-api-key.txt)/sendMessage"

#################################################################
# send message to telegram
# parameter: message text
#################################################################
function send_message {
    for chat_id  in $(cat ../$MSMS_RECIPIENTS); do
	curl -s -X POST --connect-timeout 10 $TG_API_URL -d chat_id=$chat_id -d parse_mode="Markdown" -d text="$1"
	echo
    done
}

Formamos la URL para acceder a la REST API de Telegram, usando la clave secreta guardada en el archivo.

La función send_message utiliza curl para enviar mensajes a esta REST API, extrayendo los id de los receptores del archivo que hemos especificado en el ini. En los datos enviados indicamos que utilizamos el formato de mensajes: parse_mode="Markdown".

Imprimiremos la fecha y hora actual y cargaremos el archivo ini.

echo $(date '+%Y-%m-%d %H:%M:%S')

# cargar variables desde el archivo .ini:
. $2

Cadena mágica . $2 ejecuta el archivo ini pasado como segundo parámetro como un script normal, almacenando los valores establecidos en él en las variables de entorno.

Cargaremos la respuesta esperada desde el archivo, si se ha establecido el parámetro MSMS_EXPECTED_FILE:

if [ -n "$MSMS_EXPECTED_FILE" ]; then
 MSMS_EXPECTED="$(cat "$MSMS_EXPECTED_FILE")"
fi

Realizaremos la verificación del servicio enviando notificaciones si es necesario:

RESPONSE="$(eval curl $MSMS_CURL_PARAMS "$MSMS_SERVICE_ENDPOINT")"
EXIT_CODE=$?
if [[ $EXIT_CODE != 0 ]]; then
    echo health-check "$MSMS_SERVICE_NAME" FALLÓ: CURL EXIT CON $EXIT_CODE
    MESSAGE="$(cat ..\/templates\/curl-fail.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
elif [[ "$RESPONSE" != "$MSMS_EXPECTED" ]]; then
    echo health-check "$MSMS_SERVICE_NAME" FALLÓ: "$RESPONSE"
    MESSAGE="$(cat ..\/templates\/service-fail.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
else
    echo health-check "$MSMS_SERVICE_NAME": OK
fi

Primero asignamos a la variable RESPONSE el resultado de ejecutar el comando curl para este servicio.

Expresión EXIT_CODE=$? asigna a la variable el resultado de la última ejecución del comando, es decir, curl. Si es necesario enviar una notificación, se lee la plantilla del archivo correspondiente y se envía a los destinatarios a través de send_message.

El último bloque procesa el parámetro DAILY:

if test "$1" = "DAILY"; then
    echo health-check "$MSMS_SERVICE_NAME" DAILY
    MESSAGE="$(cat ..\/templates\/daily.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
fi

Se envía un mensaje que confirma el funcionamiento del propio monitoreo.

Obtención de la lista de IDs de usuarios

recipients-setup.sh hace una llamada a la API de telegram para obtener los últimos mensajes dirigidos al bot:

curl -s https:\/\/api.telegram.org\/bot$(cat telegram-api-key.txt)\/getUpdates 
| python recipients-setup.py

Aquí se utiliza la magia de python para una salida más bonita de la lista. No es obligatorio, se puede simplemente obtener el ID necesario del json que devolverá el comando:

torsocks curl -s https:\/\/api.telegram.org\/bot$(cat telegram-api-key.txt)\/getUpdates

Conclusión

Así, puedes usar scripts y plantillas de mensajes preparados, configurando solo los servicios monitoreados y las listas para las notificaciones; puedes crear una "personalidad" nueva para el bot; o puedes hacer tu propia solución basada en la propuesta.

Como opciones para el desarrollo futuro, se sugiere configurar y gestionar el monitoreo dentro del propio bot, pero aquí ya no hay forma de esquivar el python. Si alguien llega a hacerlo antes que yo, saben dónde enviar el pull request 🙂

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster