Registrazione dell'output di un demone con Upstart


34

Ho un demone personalizzato che è gestito da upstart sul mio server Ubuntu. Funziona perfettamente, tranne per il fatto che ho bisogno di catturare (registrare) l'output del demone. La pagina ufficiale delle stanze dice che posso usare console loggedper fare questo, ma a quale file accede?

Ho anche letto che nonconsole logged è più una strofa valida . Attualmente sto usando 0.3.9 (Hardy) ma passerò a 0.6.x (Lucido) tra qualche mese. Se console loggedin effetti non funziona con le versioni successive, cosa devo usare invece?


1
Puoi semplicemente aggiornare il tuo demone personalizzato per inviare l'output a syslog o ad un file di registro specificato nel file di configurazione del daemon?
Zoredache,

Risposte:


35

Questo frammento reindirizzerà l'output del tuo servizio nel logger, consentendoti comunque di eseguire il processo di servizio (sostituendo così il processo di shell) in modo che upstart non venga confuso. Inoltre, assicura che il processo del logger sia reintegrato in init, quindi non è un figlio del tuo servizio ed evita di lasciare la cruft nel sistema di file, anche se deve creare temporaneamente un fifo.

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

Ecco come funziona:

  1. mkfifo /tmp/myservice-log-fifocrea semplicemente il file speciale fifo (noto anche come pipe). Digita man 7 fifoper maggiori informazioni.
  2. ( logger ... </tmp/myservice-log-fifo & ) avvia la lettura del logger dal FIFO, in background. Le parentesi causano la reintegrazione del processo del logger in init, anziché rimanere un figlio del processo shell corrente.
  3. exec >/tmp/myservice-log-fiforeindirizza lo stdout della shell corrente al fifo. Ora abbiamo un descrittore di file aperto per quel fifo e in realtà non abbiamo più bisogno della voce del filesystem ...
  4. rm /tmp/myservice-log-fifo quindi lo rimuoveremo.
  5. exec myservice 2>/dev/nullesegue semplicemente il servizio nel solito modo. Stdout sta già andando al Fifo, e questo non cambierà quando il nuovo programma verrà eseguito.

AGGIORNAMENTO: set -e non è necessario poiché Upstart esegue gli script con questa opzione per impostazione predefinita (consultare http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh )


ottima risposta, e non lascia quindici file in giro da nessuna parte.
Ash Berlin-Taylor,

Qual è il set -e?
Peter Mounce,

1
Questo set -eprovoca la chiusura immediata dello script se un comando non riesce. Senza quella riga, lo script continuerebbe a eseguire comandi successivi inutilmente (e forse pericolosamente).
Keith Rarick,

1
Per registrare stderr e stdout, aggiungere la riga exec 2>&1sopra la rmriga e rimuoverla 2>/dev/nulldall'ultima riga.
itsadok


11

Se si utilizza la console output stanza , quindi reindirizzare l'output dello script allo logger(interfaccia del comando shell al modulo registro di sistema syslog (3)), funzionerà.

Per esempio

console output
exec /my/script | logger

accederà a /var/log/messages

Per esempio

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

accederà /var/log/messagese taggerà ogni messaggio conmy-script

logger --help per le opzioni di utilizzo del logger.

(Sono su Amazon Linux AMI, che è basato su Centos 5.x; YMMV)


4
Si scopre che questa non è una buona soluzione. upstart si aggancia al PID logger, non al processo che si desidera effettivamente gestire.
Peter Mounce,

10

Non ho avuto il mkfifotrucco per funzionare in modo soddisfacente; non sembrava catturare stderr e i tentativi di reindirizzamento hanno causato il caos di Upstart senza errori.

Ha anche uno sfortunato effetto collaterale di far loggersospendere il processo da bambino init, quindi le informazioni su chi "possiede" il logger sono perse e chiunque non sia già a conoscenza di ciò mkfifopotrebbe presumere che sia un processo penzolante che può essere ucciso.

Invece ho finito con la seguente soluzione, che risolve tutti questi problemi. Fa logger diventare un processo figlio, preservando il servizio come processo principale. Sfortunatamente, richiede l'esecuzione bash, ma sembra solo sporco.

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

Questo usa un trucco che reindirizza stdout e stderr a un comando. Poiché eseguiamo il servizio all'interno del bashcomando, questo ha l'effetto collaterale di sostituire la shell e rendere magicamente bash un processo figlio del servizio, come mostrato da ps aufxw:

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

Per qualche motivo il comando sopra deve essere racchiuso in a bash -c. Suppongo che ciò avvenga perché Upstart finge solo di eseguire il tuo script tramite Bash, ma in realtà non lo è. Se qualcuno può suggerire un modo per evitare la shell bash extra, sarebbe fantastico.


1
Sì! Sono così felice di averlo trovato. Sembra migliore della variante mkfifo e nel mio caso non avevo bisogno di exec bash -l << EOFperdere lì.
thom_nic

6

Questo è brutto ma finora il migliore che ho trovato

exec / path / to / server >> /tmp/upstart.log 2> & 1


2
La soluzione non è buona quando si tratta di rotazione del registro, poiché l'applicazione sta registrando direttamente nel file. La registrazione tramite syslog evita problemi correlati.
Mark Stosberg,

3

Puoi anche reindirizzare l'output su syslog, ad es

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

Tuttavia, la pipeline può causare upstart per confondere il PID del processo di registrazione con il PID del daemon.


Il demone che confonde il PID è in realtà un demone inutile, dal momento che dovrebbe guardare il processo, quindi rigenerarlo. Qualche idea su come assicurarsi che venga guardato il PID giusto?
Johann Philipp Strathausen,

Penso (ma non ho provato) che vorrai la expect forko la expect daemonstrofa. Oppure, potresti catimmaginare il file pid nel messaggio di registro, suppongo.
Peter Mounce,

1

Un'altra alternativa sta usando tee come:

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

per ottenere sia il file upstart, sia l'output di syslog

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.