Confíe, pero verifique: control de mensajes no enviados en Bitrix con notificación al administrador

Antecedentes



Una vez tuve la necesidad de verificar la presencia de mensajes no enviados en "1C-Bitrix: Administración del sitio" (en adelante, Bitrix) y recibir notificaciones al respecto. Los problemas con el envío de correo eran extremadamente raros, pero más bien desagradables. generalmente eran pedidos, confirmaciones de registro y otras cartas importantes.



La dificultad era que si el método de envío de correo utilizado por Bitrix dejaba de funcionar (probablemente la razón de esto), entonces enviar una notificación usando el mismo método no sería confiable .



Buscando en Google , no encontré algo gratis y listo, pero encontré muchas preguntas / respuestas sobre los mensajes no enviados de Bitrix: cómo encontrarlos, cuáles podrían ser las razones de su aparición, etc. Por lo tanto, consideré necesario compartir mi solución.



Una tarea



  1. Obtenga detalles para conectarse a la base de datos desde la configuración del sitio de Bitrix
  2. Conectarse a DB
  3. Verifique el número de correos electrónicos no enviados
  4. Compara la cantidad con el límite
  5. Tome la decisión de enviar una notificación.




Implementación



El script de shell recibirá 3 parámetros:



  1. La ruta a la configuración del sitio de Bitrix (path_to_bxdb_config)
  2. Texto de consulta de base de datos (single_num_value_query)
  3. Valor máximo permitido (max_num_value)


Para un funcionamiento correcto, la consulta de la base de datos debe devolver un único valor numérico.



Código de script Check_bx_db_value.sh
#!/bin/bash
#
# Site: https://github.com/AlexeyGogolev/check-bx-db-value
#
mysql="$(which mysql)" #    mysql
php="$(which php)" #    php
declare -A CLParams #    
declare -a CLParams_keys #      
declare -A DBSettings #    
declare -a DBSettings_keys #       
DBSettings_keys=(DBLogin DBPassword DBName)
CLParams_keys=(path_to_bxdb_config single_num_value_query max_num_value)
param_num=0 #   
#   
for key in "${CLParams_keys[@]}" ; do 
    ((param_num++))                 
    CLParams[$key]=${!param_num}    # ${!param_num}  - $1 $2... 
done
#    ,  
if  [ -z "${CLParams[${CLParams_keys[$param_num-1]}]}" ] ; then
    printf "Script compares result returned by <${CLParams_keys[1]}> to given <${CLParams_keys[2]}>.\nIf the result more than the given value, then exit with code 1, else exit 0.\n"
    printf "Usage: \n\t$(basename ${BASH_SOURCE[0]}) " ; for key in "${CLParams_keys[@]}" ; do printf "<$key> "; done ; printf "\n"
    printf "Example: \n\t$(basename ${BASH_SOURCE[0]}) \"/www/ab.cd/bitrix/php_interface/dbconn.php\" \"select count(id) from b_event where SUCCESS_EXEC<>'Y'\" 5\n" 
    exit 10
fi
#        
if ! [ -s "${CLParams[path_to_bxdb_config]}" ] ; then 
    printf "File ${CLParams[path_to_bxdb_config]} doesn't exist or empty.\n"
    exit 20
fi
#          " "
echo ${CLParams[single_num_value_query]} | grep -i -q -E 'delete|update|insert|drop' && printf "query \n${CLParams[single_num_value_query]}\nisn't allowed\n" && exit 30
#     php-config -n --  php.ini , -r --     <?...?>
for key in "${DBSettings_keys[@]}" ; do 
    DBSettings[$key]="$($php -n -r 'include("'${CLParams[path_to_bxdb_config]}'"); print $'$key';')"
done
#   mysql    (  )
export MYSQL_PWD=${DBSettings[DBPassword]}
#     : -N --    ; -B - (batch) -   ""  ; -e  
num_value=`${mysql} -u ${DBSettings[DBLogin]} -N -B -e "use ${DBSettings[DBName]}; ${CLParams[single_num_value_query]}"`
#  
echo "Result of the query (from DB ${DBSettings[DBName]}): ${num_value}, ${CLParams_keys[2]}: ${CLParams[max_num_value]}"
#  
if [ $num_value -gt ${CLParams[max_num_value]} ]; then
    exit 1
fi




Un ejemplo de llamada al script ab_cd_unsent_check.sh
#!/bin/bash
check_bx_db_value.sh \
«/www/ab.cd/bitrix/php_interface/dbconn.php» \
«select count(id) from b_event where SUCCESS_EXEC<>'Y'» \
2






Verificación de resultados de ejecución con códigos de finalización de script
:



$ ./ab_cd_unsent_check.sh && echo "success" || echo "failure"


:



Result of the query (from DB ab_cd): 0, max_num_value: 2
success


.



$ ./ab_cd_unsent_check.sh && echo "success" || echo "failure"


:



Result of the query (from DB ab_cd): 4, max_num_value: 2
failure




¡Todo funciona como deberia! En el primer caso, el valor en la base de datos no excede el especificado, el script emite el código 0 al finalizar. En el segundo, el valor en la base de datos excede el especificado, el script termina con un código de error.



Configurar monit



En este artículo, proporcionaré un ejemplo de una configuración de monitoreo para enviar mensajes a un correo electrónico.

Se supone que monit ya está instalado y configurado en la máquina.



Para aumentar la confiabilidad, en la configuración de monitrc debe especificar una cuenta en un servidor de correo que sea diferente de la utilizada por Bitrix para enviar cartas . Además, al configurar y ejecutar scripts adicionales en la configuración de monit, puede enviar mensajes a mensajeros instantáneos y redes sociales .



Ejemplo de configuración de monit
check program ab_cd_unsent_check with path /home/bitrix/scripts/ab_cd_unsent_check.sh
every 2 cycles
    group mail
if status != 0 then alert


/etc/monit.d/.



Para simplificar la demostración, este ejemplo tiene 2 ciclos establecidos (aquí 1 ciclo = 30 segundos).

Para que Monit no envíe alertas falsas, en condiciones reales, debe establecer tantos ciclos para que las letras tengan tiempo de salir: se selecciona empíricamente. Aquí debe tener en cuenta la cantidad promedio de mensajes generados por el sitio y la velocidad (tiempo) de su procesamiento por el servidor de correo.



Para verificar el trabajo de configuración en la terminal, ejecute:

# systemctl restart monit
# monit status


obtenemos:

No hay mensajes sin enviar




Con mensajes no enviados




Así es como se ven las notificaciones de monit:

¡Mensajes no enviados aparecieron!




Todos los mensajes han sido enviados (ahora todo está bien).




El envío de notificaciones desde monit funciona correctamente.



Conclusión



Espero que la solución sea bastante versátil y adecuada para otras tareas.



¡Eso es todo! Las fuentes del artículo se pueden descargar aquí .



PD: ¿A quién no le resulta difícil compartir los comentarios? ¿Tiene tareas similares?

Si es así, ¿cómo se resuelven?



All Articles