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


34

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

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


1
カスタムデーモンを更新して、出力をsyslog、またはデーモンの構成ファイルで指定されたログファイルに送信するだけでいいですか?
ゾレダチェ

回答:


35

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

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


すばらしい答えであり、fifoファイルをどこにも残さないでください。
アッシュベルリンテイラー

set -eですか?
ピーターマンス

1
これset -eにより、コマンドが失敗した場合にスクリプトがすぐに終了します。その行がないと、スクリプトは後続のコマンドを無駄に(そしておそらく危険なまでに)実行し続けます。
キースラリック

1
stderrおよびstdoutをログに記録するには、行のexec 2>&1上にrm行を追加2>/dev/nullし、最後の行から削除します。
-itsadok

31

最新のUbuntuバージョン(12.04以降)の場合は、単に使用します

console log

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

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


2
それはきれいでいいでしょうが、残念ながらCentOS 6.xでは動作しません。CentOS6.xはこれをサポートしないupstartの古代バージョンをまだ出荷しています。
クリスティアン・マヘルアン-スタンチュ

11

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 ロガー使用オプション用。

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


4
これは良い解決策ではないことがわかりました。upstartはlogger、実際に管理するプロセスではなく、のPIDにラッチします。
ピーター

10

私はmkfifo満足に動作するためのトリックを得られませんでした。stderrをキャプチャーしていないようで、リダイレクトしようとすると、Upstartはエラーなしで保釈されました。

また、loggerプロセスをの子として持ちこたえるという不幸な副作用もあるinitため、ロガーを「所有」してmkfifoいるユーザーに関する情報は失われます。

代わりに、これらの問題をすべて解決する次のソリューションになりました。これは、原因となるlogger ルートプロセスとしてサービスを維持しながら、子プロセスになること。残念ながら、exec'ing bashが必要ですが、見た目は汚いだけです。

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コマンド内でサービスを実行するため、次のように、シェルを置き換えて魔法のようにbashをサービスの子プロセスにするという副作用がありますps aufxw

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

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


1
はい!これを見つけてとてもうれしいです。mkfifoバリアントよりも見栄えが良く、私の場合exec bash -l << EOFは損失がありません。
thom_nic

6

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

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


2
アプリケーションはファイルに直接ログを記録しているため、ログのローテーションに関しては解決策はよくありません。syslogを介したログ記録により、関連する問題を回避できます。
マークストースバーグ

3

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

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

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


PIDを混乱させるデーモンは実際には役に立たないデーモンです。プロセスを監視し、それを再起動することになっているからです。適切なPIDが監視されていることを確認する方法についてのアイデアはありますか?
ヨハンフィリップストラトハウゼン

私は、あなたがしたいと思う(しかし、試していない)、expect forkまたはexpect daemonスタンザを。またはcat、それ以外の場合は、pidファイルをログメッセージに含めることもできます。
ピーターMounce

1

別の選択肢は、次のようなティーを使用することです:

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.