Confie, mas verifique: controle de mensagens não enviadas no Bitrix com notificação ao administrador

fundo



Uma vez, tive a necessidade de verificar a presença de mensagens não enviadas no "1C-Bitrix: Gerenciamento de Site" (doravante Bitrix) e receber notificações sobre isso. Problemas com o envio de correio eram eventos extremamente raros, mas bastante desagradáveis. estes eram geralmente pedidos, confirmações de registro e outras cartas importantes.



A dificuldade era que, se o método de envio de email usado pelo Bitrix parasse de funcionar (provavelmente o motivo disso), o envio de uma notificação usando o mesmo método não seria confiável .



Pesquisando no Google , não encontrei algo gratuito e pronto, mas me deparei com muitas perguntas / respostas sobre mensagens não enviadas do Bitrix - como encontrá-las, quais podem ser as razões de sua aparência etc. Portanto, considerei necessário compartilhar minha solução.



Uma tarefa



  1. Obtenha detalhes sobre a conexão com o banco de dados na configuração do site Bitrix
  2. Conectar ao DB
  3. Verifique o número de e-mails não enviados
  4. Compare a quantidade com o limite
  5. Tome a decisão de enviar uma notificação




Implementação



O script de shell receberá 3 parâmetros:



  1. O caminho para a configuração do site Bitrix (path_to_bxdb_config)
  2. Texto de consulta do banco de dados (single_num_value_query)
  3. Valor máximo permitido (max_num_value)


Para uma operação correta, a consulta ao banco de dados deve retornar um ú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




Um exemplo de chamada do 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






Verificando resultados de execução com códigos de conclusão 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




Tudo funciona como deveria! No primeiro caso, o valor no banco de dados não excede o especificado, o script emite o código 0 após a conclusão. No segundo, o valor no banco de dados excede o especificado, o script termina com um código de erro.



Configurando o monit



Neste artigo, fornecerei um exemplo de uma configuração monit para enviar mensagens para email.

Supõe-se que o monit já esteja instalado e configurado na máquina.



Para aumentar a confiabilidade, na configuração do monitrc, você deve especificar uma conta em um servidor de correio diferente da usada pelo Bitrix para enviar cartas . Além disso, ao configurar e executar scripts adicionais na configuração monit, você pode enviar mensagens para mensageiros instantâneos e redes sociais .



Exemplo de configuração 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 a demonstração, este exemplo possui 2 ciclos configurados (aqui 1 ciclo = 30 s).

Para que o monit não envie alertas falsos, em condições reais, é necessário definir tantos ciclos para que as letras tenham tempo de sair - ele é selecionado empiricamente. Aqui você deve levar em consideração o número médio de mensagens geradas pelo site e a velocidade (tempo) de seu processamento pelo servidor de correio.



Para verificar o trabalho de configuração no terminal, execute:

# systemctl restart monit
# monit status


Nós temos:

Nenhuma mensagem não enviada




Com mensagens não enviadas




É assim que as notificações monit se parecem:

Apareceram mensagens não enviadas!




Todas as mensagens foram enviadas (agora está tudo bem).




O envio de notificações do monit funciona corretamente.



Conclusão



Espero que a solução tenha sido bastante versátil e adequada para outras tarefas.



Isso é tudo! As fontes do artigo podem ser baixadas aqui .



PS Quem não é difícil compartilhar nos comentários - você tem tarefas semelhantes?

Se sim, como eles são resolvidos?



All Articles