def objgraph(self, request): import objgraph limit = int(request.args.get('limit', 10)) types = objgraph.most_common_types(limit=limit, shortnames=False) leaking = objgraph.most_common_types( limit=limit, objects=objgraph.get_leaking_objects(), shortnames=False, ) # html only links limits = [ 'Number of items: ', Link('{}', request.path + '?limit={}', 10).html(), Link('{}', request.path + '?limit={}', 20).html(), Link('{}', request.path + '?limit={}', 50).html(), ] return info_response( request, 'Python Objects', Content( 'Python Objects for Worker pid {}'.format(os.getpid()), 'h1', ), Content(' '.join(limits), 'p', text=False, escape=False), Content('Most Common Objects', 'h2'), Table(types), Content('Leaking Objects (no referrer)', 'h2'), Table(leaking), )
def workers(self, request): """Information about workers resource usage.""" import psutil arbiter = psutil.Process(os.getppid()) workers = arbiter.children() workers.sort(key=lambda p: p.pid) rows = [format_psutil_row('Gunicorn Master', arbiter)] for i, worker in enumerate(workers): rows.append(format_psutil_row('Worker {}'.format(i), worker)) master = arbiter.as_dict(MASTER_FIELDS) master['cmdline'] = ' '.join(master['cmdline']) environ = master.pop('environ') config = talisker.get_config() clean_environ = [(k, v) for k, v in sorted(environ.items()) if k in config.METADATA] sorted_master = [(k, master[k]) for k in MASTER_FIELDS if k in master] return info_response( request.environ, 'Workers', Content('Workers', 'h2'), Table(rows, headers=HEADERS, id='workers'), Content('Process Information', 'h2'), Table(sorted_master, id='process_info'), Content('Process Environment (whitelist)', 'h2'), Table(clean_environ, id='process_env'), )
def workers(self, request): """Information about workers resource usage.""" import psutil arbiter = psutil.Process(os.getppid()) workers = arbiter.children() workers.sort(key=lambda p: p.pid) rows = [format_psutil_row('Gunicorn Master', arbiter)] for i, worker in enumerate(workers): rows.append(format_psutil_row('Worker {}'.format(i), worker)) master = arbiter.as_dict(MASTER_FIELDS) master['cmdline'] = ' '.join(master['cmdline']) environ = master.pop('environ') if 'SENTRY_DSN' in environ: environ['SENTRY_DSN'] = sanitize_url(environ['SENTRY_DSN']) clean_environ = [ (k, v) for k, v in sorted(environ.items()) if k in TALISKER_ENV_VARS ] sorted_master = [(k, master[k]) for k in MASTER_FIELDS if k in master] return info_response( request, 'Workers', Content('Workers', 'h2'), Table(rows, headers=HEADERS), Content('Process Information', 'h2'), Table(sorted_master), Content('Process Environment (whitelist)', 'h2'), Table(clean_environ), )
def talisker_error_response(environ, headers, exc_info): """Returns WSGI iterable to be returned as an error response. This error response uses Talisker's built in rendering support to be able to render content in json (default), html, or text. Returns a tuple of (content_type, iterable).""" exc_type, exc, tb = exc_info config = talisker.get_config() tb = Content('[traceback hidden]', tag='p', id='traceback') rid = environ['REQUEST_ID'] id_info = [('Request-Id', rid)] wsgi_environ = [] request_headers = [] for k, v in environ.items(): if k.startswith('HTTP_'): request_headers.append((k[5:].replace('_', '-').title(), v)) else: wsgi_environ.append((k, v)) if config.devel: title = '{}: {}'.format(exc_type.__name__, exc) lines = traceback.format_exception(*exc_info) tb = PreformattedText(''.join(lines), id='traceback') else: title = 'Server Error: {}'.format(exc_type.__name__) content = [ Content(title, tag='h1', id='title'), Table(id_info, id='id'), tb, Table( sorted(request_headers), id='request_headers', headers=['Request Headers', ''], ), Table( sorted(wsgi_environ), id='wsgi_env', headers=['WSGI Environ', ''], ), Table( headers, id='response_headers', headers=['Response Headers', ''], ), ] return render_best_content_type(environ, title, content)
def packages(self, request): """List of python packages installed.""" import pkg_resources rows = [] for p in sorted( pkg_resources.working_set, key=lambda p: p.project_name): rows.append(( p.project_name, p._version, p.location, Link( 'PyPI', 'https://pypi.org/project/{}/{}/', p.project_name, p._version, ), )) return info_response( request, 'Python Packages', Table( rows, headers=['Package', 'Version', 'Location', 'PyPI Link'], ) )
def test_table(): rows = [ ['a', 'b', 'c'], ['d', 'e', Link('foo', '/foo')], ] table = Table(rows, headers=['1', '2', '3']) assert table.html() == textwrap.dedent(""" <table> <thead> <tr> <th>1</th> <th>2</th> <th>3</th> </tr> </thead> <tbody> <tr> <td>a</td> <td>b</td> <td>c</td> </tr> <tr> <td>d</td> <td>e</td> <td><a href="/foo">foo</a></td> </tr> </tbody> </table> """).strip() # Add # characters to stop editors striping eol whitespace! assert table.text() == textwrap.dedent(""" 1 2 3 # ----------# a b c # d e /foo# ----------# """).replace('#', '').lstrip()
def test_table(): rows = [ ['a', 'b', 'c'], ['d', 'e', Link('foo', '/foo')], ] table = Table(rows, headers=['1', '2', '3'], id='table') assert table.html() == textwrap.dedent(""" <table> <thead> <tr> <th>1</th> <th>2</th> <th>3</th> </tr> </thead> <tbody> <tr> <td>a</td> <td>b</td> <td>c</td> </tr> <tr> <td>d</td> <td>e</td> <td><a href="/foo">foo</a></td> </tr> </tbody> </table> """).strip() # Add # characters to stop editors striping eol whitespace! assert table.text() == textwrap.dedent(""" 1 2 3 # ----------# a b c # d e /foo# ----------# """).replace('#', '').lstrip() id, obj = table._json() assert id == 'table' assert obj == [ {'1': 'a', '2': 'b', '3': 'c'}, {'1': 'd', '2': 'e', '3': {'href': '/foo', 'text': 'foo'}}, ] # special case in json for 2 column tables table2 = Table(list(dict(a=1, b=2).items()), id='table') assert table2._json() == ('table', {'a': 1, 'b': 2})
def index(self, request): methods = [] base = request.host_url.rstrip('/') for url, funcname in self.urlmap.items(): if funcname is None: continue if url in self.no_index: continue try: func = getattr(self, funcname) except AttributeError: pass else: methods.append(( Link(url, self.prefix + url, host=base), str(func.__doc__), )) return info_response( request, 'Status', Table(methods), )
def config(self, request): config = talisker.get_config() rows = [] for name, meta in config.metadata().items(): if meta.default is None: is_default = '' else: is_default = meta.default == meta.value rows.append(( name, meta.value, '' if meta.raw is None else repr(meta.raw), is_default, )) return info_response( request.environ, 'Config', Content('Config', 'h2'), Table( rows, headers=['Name', 'Value', 'Raw Value', 'Is Default'], id='config', ))
def test_table(): rows = [ ['a', 'b', 'c'], ['d', 'e', Link('foo', '/foo')], ] table = Table(rows, headers=['1', '2', '3'], id='table') assert table.html() == textwrap.dedent(""" <table> <thead> <tr> <th>1</th> <th>2</th> <th>3</th> </tr> </thead> <tbody> <tr> <td>a</td> <td>b</td> <td>c</td> </tr> <tr> <td>d</td> <td>e</td> <td><a href="/foo">foo</a></td> </tr> </tbody> </table> """).strip() # Add # characters to stop editors striping eol whitespace! assert table.text() == textwrap.dedent(""" 1 2 3 # ----------# a b c # d e /foo# ----------# """).replace('#', '').lstrip() id, obj = table._json() assert id == 'table' assert obj == [ { '1': 'a', '2': 'b', '3': 'c' }, { '1': 'd', '2': 'e', '3': { 'href': '/foo', 'text': 'foo' } }, ] # special case in json for 2 column tables table2 = Table(list(dict(a=1, b=2).items()), id='table') assert table2._json() == ('table', {'a': 1, 'b': 2})