2017-08-11 6 views
0

私はapschedulerの竜巻スケジューラーを使用しています。タスクが呼び出されるたびに、例外を記録する必要があります。例外を処理するために、私は将来のオブジェクトを取得し、適切なアクションをとるデコレータを作成しました。それはうまくいきますが、将来のコールバック関数の中にはログインしていません。私はPdbをコールバックの内部でやったことがあり、ロガーインスタンスのプロパティは期待通りですが、それでもファイルには全くログインしていません。 コードは、tornado.concurrent.Futureのコールバックでログが機能しない

です。私はpython2.7を使用しています

答えて

1

ラッパーには将来の復帰がありません - これがなければ、非同期呼び出しがあるとioloopは続行しません。私はそれを簡単にするためにデコレータから()を削除した、あなたが述べたかもしれませんが、いくつかのは、非同期呼び出し

@handle_exceptions 
@gen.coroutine 
def run_task(job_id): 
    logger.info('executing job {}'.format(job_id)) 
    yield gen.sleep(1) 
    raise Exception('blah') 

を追加してみましょう。ネストする必要はありません。

def handle_exceptions(fn): 
    @wraps(fn) 
    def wrapper(*args, **kwargs): 
     future = fn(*args, **kwargs) 
     future.add_done_callback(handle_callback) 
     return future # <<< we need this 
    return wrapper 

次に、ハンドラのコールバックがすぐに再レイズます例外をFuture.result()を呼んでいる:だからデコレータは次のようになります。私は、それ自体でロギングに関するあらゆる情報を提供していない質問ので

import logging 
from functools import wraps, partial 
from tornado import gen, ioloop 

logger = logging.getLogger() 
logger.setLevel(logging.INFO) 


def handle_callback(result): 
    exc_info = result.exc_info() 
    if exc_info: 
     logger.error('EXCEPTION %s', exc_info) 


def handle_exceptions(fn): 
    @wraps(fn) 
    def wrapper(*args, **kwargs): 
     future = fn(*args, **kwargs) 
     future.add_done_callback(handle_callback) 
     return future 
    return wrapper 


@handle_exceptions 
@gen.coroutine 
def run_task(job_id): 
    logger.info('executing job {}'.format(job_id)) 
    yield gen.sleep(1) 
    raise Exception('blah') 


ioloop.IOLoop.instance().run_sync(partial(run_task, 123)) 

def handle_callback(result): 
    exc_info = result.exc_info() 
    if exc_info: 
     logger.error('EXCEPTION %s', exc_info) 

簡単な例で一緒にこれを置く:だから、最初の場所で例外があるかどうかを確認する方が良いでしょうレベルを変更して標準を使用しました。 コード出力:

INFO:root:executing job 123 
ERROR:root:EXCEPTION (<type 'exceptions.Exception'>, Exception('blah',), <traceback object at 0x7f807df07dd0>) 
Traceback (most recent call last): 
    File "test.py", line 31, in <module> 
    ioloop.IOLoop.instance().run_sync(partial(run_task, 123)) 
    File "/tmp/so/lib/python2.7/site-packages/tornado/ioloop.py", line 458, in run_sync 
    return future_cell[0].result() 
    File "/tmp/so/lib/python2.7/site-packages/tornado/concurrent.py", line 238, in result 
    raise_exc_info(self._exc_info) 
    File "/tmp/so/lib/python2.7/site-packages/tornado/gen.py", line 1069, in run 
    yielded = self.gen.send(value) 
    File "test.py", line 28, in run_task 
    raise Exception('blah') 
Exception: blah 

他の問題がある場合は、私はそれは、ロギングの設定/セットアップに近い関連推測。

+0

しかし私は、(呼び出し元の) 'yield'を(呼び出し先の)' gen.Return'と組み合わせて使うことにしました。そして、 'except try'ブロックで例外を処理することができます。通常の 'sync'実行と同じくらい良いでしょうか?参考用 - > https://gist.github.com/pranav93/3c34d6cfc2b5d8956625e4cd66bdfa34 – pnv

関連する問題