Como enviar um email se um serviço systemd for reiniciado?

8

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?

Greg
fonte
2
Não sei como fazer isso com o systemd, mas com o monit você pode assistir a um processo e enviar uma notificação se o ID do processo mudar.
Zoredache

Respostas:

16

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/[email protected]:

[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 [email protected]a 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.

Fonte: wiki archlinux: temporizadores systemd MAILTO

gf_
fonte
Mas o @Dave não requer outro serviço. Ele deseja que o serviço que ele já usa seja capaz de enviar email a cada inicialização / reinicialização. Para isso, existe a opção ExecStartPost.
Jaroslav Kucera
@JaroslavKucera Acho que isso é uma decisão do OP ... :) Além disso, não tenho certeza se ExecStartPosté a escolha certa: também seria acionada após um início "normal", não apenas em caso de falha, certo ?
gf_
Estou interessado em saber por que essa votação foi votada - por favor, levante suas vozes e fale!
Gf_
Porque a pergunta não é sobre outro serviço, mas a modificação do serviço existente. Sim, o ExecStartPost acionaria o envio de email mesmo no início normal. Não estou ciente de nada que funcione apenas na reinicialização.
Jaroslav Kucera
@JaroslavKucera Bem, parece que o OP discorda, mas é claro, mantenha sua opinião.
Gf_ # 30/17
2

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:

  1. /superuser/1360346/how-to-send-an-email-alert-when-a-linux-service-has-stopped
  2. /unix/422933/confusing-systemd-behaviour-with-onfailure-and-restart
  3. /unix/197636/run-an-arbitrary-command-when-a-service-fails
Antony Nguyen
fonte
-1

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

/ubuntu/814/how-to-run-scripts-on-start-up

billcyz
fonte
1
Esta questão não é sobre a inicialização, mas sobre a reinicialização de um serviço, o que pode acontecer algum tempo após a inicialização. Portanto, não tenho certeza se sua resposta é de alguma ajuda.
gf_ 30/09/19