Eu tenho um aplicativo crítico que é executado como um serviço pelo systemd.
Ele está configurado para reiniciar assim que houver uma falha.
Como enviar um email se o aplicativo reiniciar?
Eu tenho um aplicativo crítico que é executado como um serviço pelo systemd.
Ele está configurado para reiniciar assim que houver uma falha.
Como enviar um email se o aplicativo reiniciar?
Respostas:
Primeiro, você precisa de dois arquivos: um executável para enviar o correio e um .service para iniciar o executável. Neste exemplo, o executável é apenas um script de shell usando sendmail:
/usr/local/bin/systemd-email:
#!/bin/bash
/usr/bin/sendmail -t <<ERRMAIL
To: $1
From: systemd <root@$HOSTNAME>
Subject: $2
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8
$(systemctl status --full "$2")
ERRMAIL
Qualquer que seja o executável que você use, provavelmente deve levar pelo menos dois argumentos, como este script shell: o endereço para o qual enviar e o arquivo da unidade para obter o status. O .serviceque criamos passará estes argumentos:
/etc/systemd/system/status-email-user@.service:
[Unit]
Description=status email for %i to user
[Service]
Type=oneshot
ExecStart=/usr/local/bin/systemd-email address %i
User=nobody
Group=systemd-journal
Onde usuário é o usuário que está sendo enviado por email e endereço é o endereço de email desse usuário. Embora o destinatário seja codificado, o arquivo da unidade a ser reportado é passado como um parâmetro de instância, portanto, este serviço pode enviar email para muitas outras unidades. Nesse ponto, você pode começar status-email-user@dbus.servicea verificar se pode receber os e-mails.
Em seguida, basta editar o serviço para o qual você deseja e-mails e adicionar OnFailure=status-email-user@%n.serviceà [Unit]seção. %npassa o nome da unidade para o modelo.
ExecStartPosté a escolha certa: também seria acionada após um início "normal", não apenas em caso de falha, certo ?
A solução proposta por @gf_ funcionou bem para nossa situação executando o clickhouse no CentOS7. O Clickhouse trava um pouco regularmente sobre nós, portanto, é necessário reiniciar automaticamente e ser notificado quando a reinicialização ocorrer. Embora pareça um pouco complicado adicionar um segundo serviço ao systemd, isso é necessário devido ao design do systemd.
Dito isto, essa solução, quando combinada com a reinicialização automática, parou de funcionar quando implantamos no CentOS8. Isso ocorre porque o systemd v239 enviado no C8 introduziu uma alteração na OnFailure=semântica quando combinada com uma configuração não padrão de Restart=( Restart=on-failureno nosso caso). O novo OnFailure=comportamento só aciona o serviço one-shot se a reinicialização falhar completamente, não apenas após uma falha. Esse comportamento mais recente reiniciaria com satisfação o serviço, mas não receberíamos o email porque OnFailure=não estava mais sendo chamado.
Observe nossa expectativa principal: queríamos que o systemd reiniciasse o processo E envie uma notificação por email. A atualização da v239 fez com que nossa solução anterior citada por gf_ não funcionasse mais. Felizmente, conseguimos fazer isso funcionar.
Nossa solução é usar ExecStopPostpara chamar o script de notificação por email. Isso funciona bem, mas agora surgiu um novo problema: uma notificação por email foi enviada quando o serviço da clickhouse foi iniciado normalmente, como na inicialização do servidor. Embora não seja um grande negócio, o ideal é que queremos receber notificações por email apenas em caso de falhas. Conseguimos isso adicionando o seguinte código ao nosso script de email:
# Don't do anything if the service intentionally stopped successfully.
if [ $SERVICE_RESULT == "success" ]; then
exit
fi
... $SERVICE_RESULTé uma variável de ambiente fornecida pelo systemd ao processo de destino de ExecStopPost. Ao verificar um successresultado, presumimos que essa chamada veio de uma inicialização ou desligamento normal e não fazemos nada. Em qualquer outro valor, como signal, o script continuaria enviando um email. Os possíveis valores dessa variável estão indicados na documentação .
Obrigado a gf_ pela solução inicial. Espero que as pessoas achem minha atualização útil para o CentOS8. Mais alguns links que me ajudaram:
Você pode tentar usar a opção de serviço systemd ExecStartPost.
A descrição está disponível aqui:
https://www.freedesktop.org/software/systemd/man/systemd.service.html
Pode haver mais declarações dessa opção no arquivo de definição de serviço. É acionado um por um.
Você também terá alguns exemplos em seu sistema.
Você pode criar um script de shell para verificar o status do serviço e enviar email durante a inicialização do servidor. Este link pode ajudá-lo