web-dev-qa-db-ja.com

Upstartを使用したデーモンの出力のロギング

私のUbuntuサーバーでupstartによって管理されるカスタムデーモンがあります。デーモンの出力をキャプチャ(ログ)する必要があることを除いて、完全に機能します。 公式スタンザページconsole loggedこれを行うには、どのファイルにログを記録しますか?

私も読んだconsole logged有効なスタンザではなくなりました です。現在0.3.9(Hardy)を使用していますが、数か月で0.6.x(Lucid)にアップグレードします。 console logged実際、それ以降のバージョンでは動作しません。代わりに何を使用しますか?

34
Alex Reisner

このスニペットは、サービスの出力をロガーにパイプしますが、サービスプロセスを実行できるため(シェルプロセスを置き換える)、upstartが混乱しないようにします。また、ロガープロセスの親をinitに変更するため、サービスの子ではありません。また、一時的に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

仕組みは次のとおりです。

  1. mkfifo /tmp/myservice-log-fifoは、fifoスペシャルファイル(名前付きパイプ)を作成します。タイプman 7 fifo詳細については。
  2. ( logger ... </tmp/myservice-log-fifo & )は、バックグラウンドでfifoからロガーの読み取りを開始します。括弧は、現在のシェルプロセスの子であるのではなく、ロガープロセスの親をinitに変更します。
  3. exec >/tmp/myservice-log-fifo現在のシェルのstdoutをfifoにリダイレクトします。これで、そのfifoのオープンファイル記述子ができました。実際には、ファイルシステムエントリはもう必要ありません...
  4. rm /tmp/myservice-log-fifoなので削除します。
  5. exec myservice 2>/dev/nullは、通常の方法でサービスを実行するだけです。 Stdoutはすでにfifoを使用しており、新しいプログラムが実行されても変更されません。

UPDATE:set -eは、Upstartがデフォルトでこのオプションでスクリプトを実行するため必要ありません( http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh を参照)

35
Keith Rarick

最近のUbuntuバージョン(12.04以降)の場合は、単に

console log

そして、デーモン出力(STDOUT&STDERR)が/var/log/upstart/<service>.logに追加されます

http://upstart.ubuntu.com/cookbook/#console-log

31
Willem

console outputスタンザ を使用し、スクリプトの出力をlogger(syslog(3)システムログモジュールへのシェルコマンドインターフェイス)にパイプすると、機能します。

例えば

console output
exec /my/script | logger

/var/log/messagesにログを記録します

例えば

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

/var/log/messagesにログを記録し、各メッセージにmy-scriptでタグ付けします

ロガー使用オプションのlogger --help

(私はCentos 5.xベースのAmazon Linux AMIを使用しています。YMMV)

11
Peter Mounce

mkfifoトリックをうまく機能させることができませんでした。 stderrをキャプチャしていないようで、リダイレクトしようとすると、Upstartはエラーなしで保釈されました。

また、loggerプロセスがinitの子として滞留するという残念な副作用もあります。そのため、誰がロガーを「所有」しているかに関する情報が失われ、誰もがmkfifoは、それを強制終了できる未処理のプロセスであると想定する場合があります。

代わりに、私はこれらの問題をすべて解決する次の解決策に終わりました。これにより、loggerがサービスをルートプロセスとして保持しながら、子プロセスになります。残念ながら、それはbashを実行する必要がありますが、looksダーティです。

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

これは、stdoutとstderrをコマンドにリダイレクトするトリックを使用します。 bashコマンド内でサービスを実行するため、ps aufxwに示すように、シェルを置き換えてbashを魔法のようにサービスの子プロセスにするという副作用があります。

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

何らかの理由で、上記のコマンドはbash -cで囲む必要があります。これは、UpstartがBash経由でスクリプトを実行するふりをしているだけで、実際はそうではないためと考えています。誰かが余分なbashシェルを回避する方法を提案できるとしたら、それは素晴らしいことです。

10

これは醜いですが、これまでのところ私が見つけた最高のものです

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

6
Jorge Vargas

また、出力をsyslogにリダイレクトすることもできます。

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

ただし、パイプラインにより、upstartがロギングプロセスのPIDとデーモンのPIDを混同する場合があります。

3
Nikratio

別の代替方法は、次のようなT字を使用することです。

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

upstartファイルとsyslog出力の両方を取得する

1
perl