mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
add possibility to trace all events of gunicorn. Run gunicorn --spew .
This commit is contained in:
parent
2e40f48d05
commit
3a2e3edb3e
31
NOTICE
31
NOTICE
@ -5,3 +5,34 @@ Gunicorn
|
|||||||
|
|
||||||
Gunicorn is released under the MIT license. See the LICENSE
|
Gunicorn is released under the MIT license. See the LICENSE
|
||||||
file for the complete license.
|
file for the complete license.
|
||||||
|
|
||||||
|
|
||||||
|
gunicorn.debug
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Based on eventlet.debug module under MIT license:
|
||||||
|
|
||||||
|
Unless otherwise noted, the files in Eventlet are under the following MIT license:
|
||||||
|
|
||||||
|
Copyright (c) 2005-2006, Bob Ippolito
|
||||||
|
Copyright (c) 2007-2010, Linden Research, Inc.
|
||||||
|
Copyright (c) 2008-2010, Eventlet Contributors (see Eventlet AUTHORS)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ class Config(object):
|
|||||||
loglevel='info',
|
loglevel='info',
|
||||||
pidfile=None,
|
pidfile=None,
|
||||||
proc_name = None,
|
proc_name = None,
|
||||||
|
spew=False,
|
||||||
timeout=30,
|
timeout=30,
|
||||||
tmp_upload_dir=None,
|
tmp_upload_dir=None,
|
||||||
umask="0",
|
umask="0",
|
||||||
|
|||||||
74
gunicorn/debug.py
Normal file
74
gunicorn/debug.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# -*- coding: utf-8 -
|
||||||
|
#
|
||||||
|
# This file is part of gunicorn released under the MIT license.
|
||||||
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
|
"""The debug module contains utilities and functions for better
|
||||||
|
debugging Gunicorn."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import linecache
|
||||||
|
import re
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
__all__ = ['spew', 'unspew']
|
||||||
|
|
||||||
|
_token_spliter = re.compile('\W+')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Spew(object):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
def __init__(self, trace_names=None, show_values=True):
|
||||||
|
self.trace_names = trace_names
|
||||||
|
self.show_values = show_values
|
||||||
|
|
||||||
|
def __call__(self, frame, event, arg):
|
||||||
|
if event == 'line':
|
||||||
|
lineno = frame.f_lineno
|
||||||
|
if '__file__' in frame.f_globals:
|
||||||
|
filename = frame.f_globals['__file__']
|
||||||
|
if (filename.endswith('.pyc') or
|
||||||
|
filename.endswith('.pyo')):
|
||||||
|
filename = filename[:-1]
|
||||||
|
name = frame.f_globals['__name__']
|
||||||
|
line = linecache.getline(filename, lineno)
|
||||||
|
else:
|
||||||
|
name = '[unknown]'
|
||||||
|
try:
|
||||||
|
src = inspect.getsourcelines(frame)
|
||||||
|
line = src[lineno]
|
||||||
|
except IOError:
|
||||||
|
line = 'Unknown code named [%s]. VM instruction #%d' % (
|
||||||
|
frame.f_code.co_name, frame.f_lasti)
|
||||||
|
if self.trace_names is None or name in self.trace_names:
|
||||||
|
print '%s:%s: %s' % (name, lineno, line.rstrip())
|
||||||
|
if not self.show_values:
|
||||||
|
return self
|
||||||
|
details = []
|
||||||
|
tokens = _token_spliter.split(line)
|
||||||
|
for tok in tokens:
|
||||||
|
if tok in frame.f_globals:
|
||||||
|
details.append('%s=%r' % (tok, frame.f_globals[tok]))
|
||||||
|
if tok in frame.f_locals:
|
||||||
|
details.append('%s=%r' % (tok, frame.f_locals[tok]))
|
||||||
|
if details:
|
||||||
|
print "\t%s" % ' '.join(details)
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
def spew(trace_names=None, show_values=False):
|
||||||
|
"""Install a trace hook which writes incredibly detailed logs
|
||||||
|
about what code is being executed to stdout.
|
||||||
|
"""
|
||||||
|
sys.settrace(Spew(trace_names, show_values))
|
||||||
|
|
||||||
|
|
||||||
|
def unspew():
|
||||||
|
"""Remove the trace hook installed by spew.
|
||||||
|
"""
|
||||||
|
sys.settrace(None)
|
||||||
|
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ import pkg_resources
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from gunicorn.config import Config
|
from gunicorn.config import Config
|
||||||
|
from gunicorn.debug import spew
|
||||||
from gunicorn import util, __version__
|
from gunicorn import util, __version__
|
||||||
|
|
||||||
LOG_LEVELS = {
|
LOG_LEVELS = {
|
||||||
@ -51,7 +52,9 @@ def options():
|
|||||||
op.make_option('--log-file', dest='logfile',
|
op.make_option('--log-file', dest='logfile',
|
||||||
help='Log to a file. - equals stdout. [-]'),
|
help='Log to a file. - equals stdout. [-]'),
|
||||||
op.make_option('-d', '--debug', dest='debug', action="store_true",
|
op.make_option('-d', '--debug', dest='debug', action="store_true",
|
||||||
default=False, help='Debug mode. only 1 worker.')
|
default=False, help='Debug mode. only 1 worker.'),
|
||||||
|
op.make_option('--spew', dest='spew', action="store_true",
|
||||||
|
default=False, help="Install a trace hook")
|
||||||
]
|
]
|
||||||
|
|
||||||
def configure_logging(opts):
|
def configure_logging(opts):
|
||||||
@ -114,6 +117,8 @@ def main(usage, get_app):
|
|||||||
|
|
||||||
app = get_app(parser, opts, args)
|
app = get_app(parser, opts, args)
|
||||||
conf = Config(opts.__dict__, opts.config)
|
conf = Config(opts.__dict__, opts.config)
|
||||||
|
if conf['spew']:
|
||||||
|
spew()
|
||||||
arbiter = conf.arbiter(conf.address, conf.workers, app, config=conf,
|
arbiter = conf.arbiter(conf.address, conf.workers, app, config=conf,
|
||||||
debug=conf['debug'], pidfile=conf['pidfile'])
|
debug=conf['debug'], pidfile=conf['pidfile'])
|
||||||
if conf['daemon']:
|
if conf['daemon']:
|
||||||
@ -149,6 +154,8 @@ def paste_server(app, global_conf=None, host="127.0.0.1", port=None,
|
|||||||
options['default_proc_name'] = options['__file__']
|
options['default_proc_name'] = options['__file__']
|
||||||
|
|
||||||
conf = Config(options)
|
conf = Config(options)
|
||||||
|
if conf['spew']:
|
||||||
|
spew()
|
||||||
arbiter = conf.arbiter(conf.address, conf.workers, app, debug=conf["debug"],
|
arbiter = conf.arbiter(conf.address, conf.workers, app, debug=conf["debug"],
|
||||||
pidfile=conf["pidfile"], config=conf)
|
pidfile=conf["pidfile"], config=conf)
|
||||||
if conf["daemon"] :
|
if conf["daemon"] :
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user