Registrando a saída de um daemon com o Upstart

34

Eu tenho um daemon personalizado que é gerenciado por upstart no meu servidor Ubuntu. Ele funciona perfeitamente, exceto que eu preciso capturar (log) a saída do daemon. A página oficial de sub-rotinas diz que eu posso usar console logged para fazer isso, mas para qual arquivo ele logou?

Eu também li que console logged é não mais uma estrofe válida . Atualmente estou usando o 0.3.9 (Hardy), mas atualizarei para 0.6.x (Lucid) em alguns meses. Se console logged de fato não funcionar com versões posteriores, o que eu uso em vez disso?

    
por Alex Reisner 18.02.2010 / 00:25

7 respostas

34

Este snippet irá canalizar a saída do seu serviço em logger, enquanto ainda permite que você execute o processo de serviço (substituindo assim o processo shell) então essa novata não fica confusa. Também faz Certifique-se de que o processo do registrador seja reparado no init, não é filho do seu serviço, e evita deixando cruft sentados no sistema de arquivos, mesmo embora precise criar um fifo temporariamente.

script
  mkfifo /tmp/myservice-log-fifo
  ( logger -t myservice </tmp/myservice-log-fifo & )
  exec >/tmp/myservice-log-fifo
  rm /tmp/myservice-log-fifo
  exec myservice 2>/dev/null
end script

Veja como funciona:

  1. mkfifo /tmp/myservice-log-fifo simplesmente faz o arquivo especial fifo (também conhecido como pipe nomeado). Digite man 7 fifo para mais informações.
  2. ( logger ... </tmp/myservice-log-fifo & ) inicia a leitura do registrador a partir do fifo, em segundo plano. Os parênteses fazem com que o processo do registrador seja reparado no init, em vez de permanecer um filho do processo de shell atual.
  3. exec >/tmp/myservice-log-fifo redireciona o stdout do shell atual para o fifo. Agora nós temos um descritor de arquivo aberto para esse fifo, e nós realmente não precisamos mais da entrada do sistema de arquivos ...
  4. rm /tmp/myservice-log-fifo , então vamos removê-lo.
  5. exec myservice 2>/dev/null simplesmente executa o serviço da maneira usual. O Stdout já está indo para o fifo, e isso não mudará quando o novo programa for executado.

UPDATE: set -e não é necessário pois o Upstart executa scripts com esta opção por padrão (veja link )

    
por 29.09.2011 / 02:56
31

Para versões recentes do Ubuntu (12.04+), basta usar

console log

E a saída do daemon (STDOUT & STDERR) será anexada a /var/log/upstart/<service>.log

link

    
por 13.01.2015 / 18:05
11

Se você usar a sub-rotina console output e, em seguida, enviar a saída do seu script para logger ( a interface de comando do shell para o módulo de log do sistema syslog (3)), então isso funcionará.

Por exemplo

console output
exec /my/script | logger

registrará em /var/log/messages

Por exemplo

console output
exec /my/script | logger -t my-script

registrará em /var/log/messages e marcará cada mensagem com my-script

logger --help para opções de uso do registrador.

(Eu estou no Amazon Linux AMI, que é baseado no Centos 5.x; YMMV)

    
por 20.06.2012 / 14:43
9

Eu não consegui que o truque mkfifo funcionasse satisfatoriamente; não parecia capturar stderr, e tentativas de redirecionamento causaram Upstart para salvar sem erros.

Também tem um efeito colateral infeliz de tornar o processo logger pendente como um filho de init , portanto, as informações sobre quem "possui" o criador de logs são perdidas e qualquer um que ainda não tenha conhecimento da mkfifo pode supor que é um processo pendente que pode ser morto.

Em vez disso, acabei com a solução a seguir, que resolve todos esses problemas. Isso faz com que logger se torne um processo filho, preservando o serviço como o processo raiz. Infelizmente, isso exige exec'ing bash , mas parece sujo .

script
  # ... setup commands here, e.g. environment, cd, ...
  exec bash <<EOT
    exec 1> >(logger -t myservice) 2>&1
    exec myservice
EOT
end script

Isso usa um truque que redireciona stdout e stderr para um comando. Já que executamos o serviço dentro do comando bash , isso tem o efeito colateral de substituir o shell e magicamente tornar o bash um processo filho do serviço, como mostrado por ps aufxw :

myservice 
 \_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
    \_ logger -t myservice

Por alguma razão, o comando acima tem que ser empacotado em bash -c . Eu suponho que isso é porque o Upstart apenas finge executar o seu script via Bash, mas na verdade não é. Se alguém puder sugerir uma maneira de evitar o shell extra do bash, isso seria incrível.

    
por 12.02.2015 / 04:17
6

Isso é feio, mas até agora o melhor que encontrei

exec / caminho / para / servidor > > /tmp/upstart.log 2 > & 1

    
por 16.03.2010 / 10:22
3

Você também pode redirecionar a saída para o syslog, por exemplo,

exec $SERVER 2>&1 | logger -t myservice -p local0.info

No entanto, o pipeline pode fazer com que o upstart confunda o PID do processo de registro com o PID do daemon.

    
por 01.04.2010 / 23:30
1

Outra alternativa é usar tee like:

exec $SERVER 2>&1 | tee /dev/stderr | logger -t myservice

para obter o arquivo upstart e a saída do syslog

    
por 16.12.2016 / 14:17