scrub repetitive gen.py, coroutine.py frames from coroutine tracebacks

when logging exceptions
This commit is contained in:
Min RK
2015-02-26 17:02:15 -08:00
parent 7486f1f20d
commit 0439a3f79c
2 changed files with 43 additions and 2 deletions

View File

@@ -26,7 +26,7 @@ import tornado.httpserver
import tornado.options
from tornado.httpclient import HTTPError
from tornado.ioloop import IOLoop, PeriodicCallback
from tornado.log import LogFormatter, app_log, access_log, gen_log
from tornado.log import app_log, access_log, gen_log
from tornado import gen, web
import IPython
@@ -47,6 +47,7 @@ from .handlers.static import CacheControlStaticFilesHandler
from . import orm
from ._data import DATA_FILES_PATH
from .log import CoroutineLogFormatter
from .traitlets import URLPrefix
from .utils import (
url_path_join,
@@ -350,7 +351,7 @@ class JupyterHub(Application):
handlers = List()
_log_formatter_cls = LogFormatter
_log_formatter_cls = CoroutineLogFormatter
http_server = None
proxy_process = None
io_loop = None

40
jupyterhub/log.py Normal file
View File

@@ -0,0 +1,40 @@
"""logging utilities"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import traceback
from tornado.log import LogFormatter
def coroutine_traceback(typ, value, tb):
"""Scrub coroutine frames from a traceback
Coroutine tracebacks have a bunch of identical uninformative frames at each yield point.
This removes those extra frames, so tracebacks should be easier to read.
This might be a horrible idea.
Returns a list of strings (like traceback.format_tb)
"""
all_frames = traceback.extract_tb(tb)
useful_frames = []
for frame in all_frames:
if frame[0] == '<string>' and frame[2] == 'raise_exc_info':
continue
# start out conservative with filename + function matching
# maybe just filename matching would be sufficient
elif frame[0].endswith('tornado/gen.py') and frame[2] in {'run', 'wrapper'}:
continue
elif frame[0].endswith('tornado/concurrent.py') and frame[2] == 'result':
continue
useful_frames.append(frame)
tb_list = ['Traceback (most recent call last):\n']
tb_list.extend(traceback.format_list(useful_frames))
tb_list.extend(traceback.format_exception_only(typ, value))
return tb_list
class CoroutineLogFormatter(LogFormatter):
"""Log formatter that scrubs coroutine frames"""
def formatException(self, exc_info):
return ''.join(coroutine_traceback(*exc_info))