web-dev-qa-db-ja.com

Pythonデーモンでのロギングおよび/またはstdout / stderrの保守

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

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

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

17
dave mankoff

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

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." )
9
mpounsett

同様の問題が発生しましたが、私の制御が及ばないことが原因で、デーモンのものはロガーを作成するものとは別のものでした。ただし、ロガーには.handlers属性と.parent属性があり、次のような方法でそれを可能にします。

    self.files_preserve = self.getLogFileHandles(self.data.logger)

def getLogFileHandles(self,logger):
    """ Get a list of filehandle numbers from logger
        to be handed to DaemonContext.files_preserve
    """
    handles = []
    for handler in logger.handlers:
        handles.append(handler.stream.fileno())
    if logger.parent:
        handles += self.getLogFileHandles(logger.parent)
    return handles
5
TommyTheKid