18

Pythonでデーモンプロセスを作成するために私が見つけたすべてのレシピには、(Unixの場合)2回フォークしてから、開いているすべてのファイル記述子を閉じることが含まれます。(例については、 http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/を参照してください)。

これはすべて簡単ですが、問題があるようです。私がセットアップしている本番マシンでは、デーモンが異常終了しています-開いているすべてのファイル記述子が閉じられたため、サイレントに。私は現在問題をデバッグするのに苦労していて、これらのエラーをキャッチしてログに記録する適切な方法は何であるか疑問に思っています。

デーモン化後も機能し続けるようにロギングを設定する正しい方法は何ですか?logging.basicConfig()デーモン化した後、もう一度電話をかけますか?キャプチャする正しい方法は何stdoutですかstderr?すべてのファイルが閉じられる理由の詳細がわかりません。理想的には、私のメインコードはただ呼び出すことができdaemon_start(pid_file)、ロギングは引き続き機能します。

4

3 に答える 3

20

python-daemonデーモン化の動作にライブラリを使用しています。

ここで説明するインターフェイス:

ここでの実装:

引数を指定して、デーモン化時に閉じてはならないfiles_preserveファイル記述子を示すことができます。

デーモン化の前後に同じ インスタンスを介してログを記録する必要がある場合は、次のことができます。Handler

  1. basicConfig最初に、またはその他を使用してロギング Handler を設定しますdictConfig
  2. ログのもの
  3. Handlers が依存しているファイル記述子を特定します。Handler残念ながら、これはサブクラスに依存しています。最初にインストールされたものHandlerが の場合、それは;StreamHandlerの値です。logging.root.handlers[0].stream.fileno()2 番目にインストールされHandlerたものが のSyslogHandler場合、値が必要ですlogging.root.handlers[1].socket.fileno()。など。これは面倒です:-(
  4. 手順 3 で決定したファイル記述子のリストと等しいDaemonContextwithを作成して、プロセスをデーモン化します。files_preserve
  5. ロギングを続行します。ダブルフォーク中にログファイルを閉じてはいけません。

@Exelianが提案したように、デーモン化Handlerの前後で実際に異なるインスタンスを使用することもできます。デーモン化の直後に、既存のハンドラーを ( ?delから ing してlogger.root.handlers) 破棄し、同一の新しいハンドラーを作成します。basicConfig@dave-mankoff が指摘した問題のため、単にリコールすることはできません。

于 2012-12-04T05:01:26.113 に答える
10

ログ ハンドラー オブジェクトをルート ロガー オブジェクトとは別に設定し、一度にすべてを行うのではなく、独立したステップとしてハンドラー オブジェクトを追加すると、このコードを簡略化できます。以下はあなたのために働くはずです。

import daemon
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler("./foo.log")
logger.addHandler(fh)

context = daemon.DaemonContext(
   files_preserve = [
      fh.stream,
   ],
)

logger.debug( "Before daemonizing." )
context.open()
logger.debug( "After daemonizing." )
于 2013-03-11T00:07:40.613 に答える