私のUbuntuサーバーでupstartによって管理されるカスタムデーモンがあります。デーモンの出力をキャプチャ(ログ)する必要があることを除いて、完全に機能します。 公式スタンザページ はconsole logged
これを行うには、どのファイルにログを記録しますか?
私も読んだconsole logged
は 有効なスタンザではなくなりました です。現在0.3.9(Hardy)を使用していますが、数か月で0.6.x(Lucid)にアップグレードします。 console logged
実際、それ以降のバージョンでは動作しません。代わりに何を使用しますか?
このスニペットは、サービスの出力をロガーにパイプしますが、サービスプロセスを実行できるため(シェルプロセスを置き換える)、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
仕組みは次のとおりです。
mkfifo /tmp/myservice-log-fifo
は、fifoスペシャルファイル(名前付きパイプ)を作成します。タイプman 7 fifo
詳細については。( logger ... </tmp/myservice-log-fifo & )
は、バックグラウンドでfifoからロガーの読み取りを開始します。括弧は、現在のシェルプロセスの子であるのではなく、ロガープロセスの親をinitに変更します。exec >/tmp/myservice-log-fifo
現在のシェルのstdoutをfifoにリダイレクトします。これで、そのfifoのオープンファイル記述子ができました。実際には、ファイルシステムエントリはもう必要ありません...rm /tmp/myservice-log-fifo
なので削除します。exec myservice 2>/dev/null
は、通常の方法でサービスを実行するだけです。 Stdoutはすでにfifoを使用しており、新しいプログラムが実行されても変更されません。UPDATE:set -e
は、Upstartがデフォルトでこのオプションでスクリプトを実行するため必要ありません( http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh を参照)
最近のUbuntuバージョン(12.04以降)の場合は、単に
console log
そして、デーモン出力(STDOUT&STDERR)が/var/log/upstart/<service>.log
に追加されます
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)
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シェルを回避する方法を提案できるとしたら、それは素晴らしいことです。
これは醜いですが、これまでのところ私が見つけた最高のものです
exec/path/to/server >> /tmp/upstart.log 2>&1
また、出力をsyslogにリダイレクトすることもできます。
exec $SERVER 2>&1 | logger -t myservice -p local0.info
ただし、パイプラインにより、upstartがロギングプロセスのPIDとデーモンのPIDを混同する場合があります。
別の代替方法は、次のようなT字を使用することです。
exec $SERVER 2>&1 | tee /dev/stderr | logger -t myservice
upstartファイルとsyslog出力の両方を取得する