2017-01-07 2 views
0

В Tornado Exception инкапсулируется в Будущее, а вызывающая функция async должна дать Будущему распаковать Исключение. Как получить сообщение журнала, чтобы правильно распечатать имя функции и строку, где исключение происходит, если у меня есть длинная цепочка вызовов асинхронных функций?Правильное ведение журнала для исключения в сопрограмме Python3 + Tornado4.3 + собственный модуль ведения журнала

Например, в коде ниже:

FORMAT = '%(asctime)s - %(levelname)s - %(filename)s : %(lineno)s'\ 
     ' - %(funcName)20s() - %(message)s\n' 

logging.basicConfig(format=FORMAT) 

... 

@gen.coroutine 
def layer_2(): 
    return(yield async_func()) 

@gen.coroutine 
def layer_1(): 
    return(yield layer_2()) 

@gen.coroutine 
def main(): 
    try: 
     yield layer_1() 
    except Exception as e: 
     logging.warning('Error: {}'.format(str(e)) 

Если есть Исключение возникает в async_func() сообщение журнала lineno и funcName принадлежат main(), не async_func().

Есть ли какие-либо решения, кроме try и catch каждые yield заявление? Благодаря!

Редактировать 1: Я понял, что ответ на мой вопрос может не иметь ничего общего с Торнадо, но я просто включаю его здесь, потому что это мое дело.

ответ

3

Я вижу, что вы используете Python 3, а в Python 3 исключения из Futures имеют автоматическое отслеживание. Используйте logging.exception печатать:

@gen.coroutine 
def main(): 
    try: 
     yield layer_1() 
    except Exception as e: 
     logging.exception(e) 

Там нет ничего загадочного происходит в logging. Вы можете напечатать TraceBack себя:

@gen.coroutine 
def main(): 
    try: 
     yield layer_1() 
    except Exception as e: 
     import traceback 
     traceback.print_exc() 

По сравнению с TRACEBACK из обычного стека вызовов функций, это отслеживающий имеют некоторые дополнительные вещи в нем: звонки на gen.Runner.run, часть сопрограммной реализации смерча. Но он служит своей цели: вы можете видеть, что main находится в верхней части стека, а внизу находится async_func.

Это работает на Python 3, потому что каждое исключение имеет прикрепленный к нему Traceback, а Tornado правильно привязывает трассировку сопрограммы к исключению, поскольку он разматывает стек во время обработки исключений. For some history, see the docs on Future.

И, наконец, если вы замените gen.coroutine на async def, вы получите хорошие чистые трассировки, реализованные самим интерпретатором Python 3.5.

+0

А это очень полезно! Спасибо! Я думаю, что это второй вопрос, который вы мне помогли! –

Смежные вопросы