web-dev-qa-db-ja.com

デバッグ:コンソール出力とUpstartスクリプト

pythonコード内のトレースバックを見つけるために、どのようにupstartスクリプトの出力を端末に送信しますか?かつてほんの数秒であったトレースバックなしで、私は永遠に物事をするようになりました。エラーを追跡するために、いくつかのファイル書き込み呼び出しを行う必要があります。トレースバックで2番目に見つけたのは、数分でした。これは悲惨です。これは数週間続いていますが、うんざりです。これについて話してください。再びデバッガなしでアセンブリを使用しているように感じます。

16
bambuntu

Upstart 1.4以降を使用する場合、console logをUpstartジョブに入れると、stdout/stderrへのすべての出力は/var/log/upstart/<job>.logになります。その後、tail -f /var/log/upstart/<job>.log &を実行して、出力をターミナルに表示できます。

27
Tuminoid

pstart Cookbook には、デバッグ手法に関するセクション全体があります。できる最も簡単なことは、カーネル引数に--debugを追加することです。これにより、upstartの冗長性が高まり、すべてがsyslogにダンプされます。はい、デバッグは複雑です。これは、並列化されたinitシステムを作成するために必要な正味の複雑さを反映しています。改善の余地があると確信しています。

2
ppetraki

pythonデーモンを作成すると、すべての例外をキャッチして、ログファイルにスローします。デバッグだけでなく、本番でも使用しています。毎朝実行する小さなスクリプトを使用して、ログ内の動揺する何かを探します。

もちろん、デーモンを実行し続けるのにも役立ちます。

いくつかのサンプルコード(面白くない部分を削除します):

import logging

if __== "__main__":
    logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s',
                    filename=LOG_FILE,
                    filemode='w')
    logging.info("Sincrod inicializado")
    if not DEBUG:
        daemonize()
    while True:
        try:
            actua()
        except:
            logging.error(sys.exc_info())
        if (datetime.datetime.now().hour > NOITE_EMPEZA\
         and datetime.datetime.now().hour < NOITE_REMATA):
            time.sleep(INTERVALO_NOITE)
        else:
            time.sleep(INTERVALO_DIA)

ここで、actua()は実際のデーモンです(ログにも書き込みます)。また、設定ファイルにDEBUG変数があります。これがTrueの場合、コンソールで実行されるようにデーモンをフォークしません。

デーモン

デーモンは、Windowsサービスに相当するUNIXです。これらは、他のプロセスから独立したバックグラウンドで実行されるプロセスです。つまり、彼らの父親は通常initであり、どのttyからも切り離されています。それらは独立しているため、出力を配置するための事前定義された場所はありません。

デーモンを作成するための多くのpythonライブラリとスニペットがあります。上記の例では、Steinar KnutsensバージョンとJeff Kuncesバージョンのアイデアを組み合わせた独自の関数を使用しています。それは可能な限り簡単です、私はフォーク 2回 に注意してください。

def daemonize():
    """Forks this process creating a daemon and killing the original one"""
    if (not os.fork()):
        # get our own session and fixup std[in,out,err]
        os.setsid()
        sys.stdin.close()
        sys.stdout = NullDevice()
        sys.stderr = NullDevice()
        if (not os.fork()):
            # hang around till adopted by init
            ppid = os.getppid()
            while (ppid != 1):
                time.sleep(0.5)
                ppid = os.getppid()
        else:
            # time for child to die
            os._exit(0)
    else:
        # wait for child to die and then bail
        os.wait()
        sys.exit()
2
Javier Rivera