mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
log HTTP errors in access log. close #317
This commit is contained in:
parent
1c27d369b4
commit
5f11713678
@ -21,6 +21,5 @@ def app(environ, start_response):
|
||||
('Content-Length', str(len(data))),
|
||||
('X-Gunicorn-Version', __version__)
|
||||
]
|
||||
|
||||
start_response(status, response_headers)
|
||||
return iter([data])
|
||||
|
||||
@ -273,7 +273,7 @@ def validate_post_request(val):
|
||||
elif largs == 2:
|
||||
return wrap_post_request(val)
|
||||
else:
|
||||
raise TypeError("Value must have an arity of: 3")
|
||||
raise TypeError("Value must have an arity of: 3")
|
||||
|
||||
|
||||
|
||||
|
||||
@ -157,7 +157,7 @@ class Logger(object):
|
||||
|
||||
status = resp.status.split(None, 1)[0]
|
||||
atoms = {
|
||||
'h': environ['REMOTE_ADDR'],
|
||||
'h': environ.get('REMOTE_ADDR', '-'),
|
||||
'l': '-',
|
||||
'u': '-', # would be cool to get username from basic auth header
|
||||
't': self.now(),
|
||||
|
||||
@ -39,10 +39,9 @@ class FileWrapper:
|
||||
return data
|
||||
raise IndexError
|
||||
|
||||
def create(req, sock, client, server, cfg):
|
||||
resp = Response(req, sock)
|
||||
|
||||
environ = {
|
||||
def default_environ(req, sock, cfg):
|
||||
return {
|
||||
"wsgi.input": req.body,
|
||||
"wsgi.errors": sys.stderr,
|
||||
"wsgi.version": (1, 0),
|
||||
@ -58,6 +57,12 @@ def create(req, sock, client, server, cfg):
|
||||
"SERVER_PROTOCOL": "HTTP/%s" % ".".join(map(str, req.version))
|
||||
}
|
||||
|
||||
|
||||
def create(req, sock, client, server, cfg):
|
||||
resp = Response(req, sock)
|
||||
|
||||
environ = default_environ(req, sock, cfg)
|
||||
|
||||
# authors should be aware that REMOTE_HOST and REMOTE_ADDR
|
||||
# may not qualify the remote addr:
|
||||
# http://www.ietf.org/rfc/rfc3875
|
||||
|
||||
@ -125,8 +125,9 @@ def load_class(uri, default="sync", section="gunicorn.workers"):
|
||||
|
||||
return pkg_resources.load_entry_point("gunicorn",
|
||||
section, uri)
|
||||
except ImportError:
|
||||
raise RuntimeError("class uri invalid or not found")
|
||||
except ImportError, e:
|
||||
raise RuntimeError("class uri invalid or not found: [%s]",
|
||||
str(e))
|
||||
klass = components.pop(-1)
|
||||
mod = __import__('.'.join(components))
|
||||
for comp in components[1:]:
|
||||
|
||||
@ -26,6 +26,7 @@ class AsyncWorker(base.Worker):
|
||||
raise NotImplementedError()
|
||||
|
||||
def handle(self, client, addr):
|
||||
req = None
|
||||
try:
|
||||
parser = http.RequestParser(self.cfg, client)
|
||||
try:
|
||||
@ -38,6 +39,8 @@ class AsyncWorker(base.Worker):
|
||||
self.handle_request(req, client, addr)
|
||||
except StopIteration, e:
|
||||
self.log.debug("Closing connection. %s", e)
|
||||
except Exception, e:
|
||||
self.handle_error(req, client, addr, e)
|
||||
except socket.error, e:
|
||||
if e[0] not in (errno.EPIPE, errno.ECONNRESET):
|
||||
self.log.exception("Socket error processing request.")
|
||||
@ -47,14 +50,14 @@ class AsyncWorker(base.Worker):
|
||||
else:
|
||||
self.log.debug("Ignoring EPIPE")
|
||||
except Exception, e:
|
||||
self.handle_error(client, e)
|
||||
self.handle_error(req, client, addr, e)
|
||||
finally:
|
||||
util.close(client)
|
||||
|
||||
def handle_request(self, req, sock, addr):
|
||||
request_start = datetime.now()
|
||||
try:
|
||||
self.cfg.pre_request(self, req)
|
||||
request_start = datetime.now()
|
||||
resp, environ = wsgi.create(req, sock, addr, self.address, self.cfg)
|
||||
self.nr += 1
|
||||
if self.alive and self.nr >= self.max_requests:
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
# This file is part of gunicorn released under the MIT license.
|
||||
# See the NOTICE for more information.
|
||||
|
||||
from datetime import datetime
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
@ -11,11 +12,10 @@ import traceback
|
||||
|
||||
from gunicorn import util
|
||||
from gunicorn.workers.workertmp import WorkerTmp
|
||||
|
||||
from gunicorn.http.errors import InvalidHeader, InvalidHeaderName, \
|
||||
InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, \
|
||||
LimitRequestLine, LimitRequestHeaders
|
||||
|
||||
from gunicorn.http.wsgi import default_environ, Response
|
||||
|
||||
class Worker(object):
|
||||
|
||||
@ -125,7 +125,8 @@ class Worker(object):
|
||||
self.alive = False
|
||||
sys.exit(0)
|
||||
|
||||
def handle_error(self, client, exc):
|
||||
def handle_error(self, req, client, addr, exc):
|
||||
request_start = datetime.now()
|
||||
if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod,
|
||||
InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,)):
|
||||
|
||||
@ -157,6 +158,16 @@ class Worker(object):
|
||||
reason = "Internal Server Error"
|
||||
mesg = ""
|
||||
|
||||
if req is not None:
|
||||
request_time = datetime.now() - request_start
|
||||
environ = default_environ(req, client, self.cfg)
|
||||
environ['REMOTE_ADDR'] = addr[0]
|
||||
environ['REMOTE_PORT'] = str(addr[1])
|
||||
resp = Response(req, client)
|
||||
resp.status = "%s %s" % (status_int, reason)
|
||||
resp.response_length = len(mesg)
|
||||
self.log.access(resp, req, environ, request_time)
|
||||
|
||||
if self.debug:
|
||||
tb = traceback.format_exc()
|
||||
mesg += "<h2>Traceback:</h2>\n<pre>%s</pre>" % tb
|
||||
|
||||
@ -65,6 +65,7 @@ class SyncWorker(base.Worker):
|
||||
raise
|
||||
|
||||
def handle(self, client, addr):
|
||||
req = None
|
||||
try:
|
||||
parser = http.RequestParser(self.cfg, client)
|
||||
req = parser.next()
|
||||
@ -77,7 +78,7 @@ class SyncWorker(base.Worker):
|
||||
else:
|
||||
self.log.debug("Ignoring EPIPE")
|
||||
except Exception, e:
|
||||
self.handle_error(client, e)
|
||||
self.handle_error(req, client, addr, e)
|
||||
finally:
|
||||
util.close(client)
|
||||
|
||||
@ -113,7 +114,7 @@ class SyncWorker(base.Worker):
|
||||
raise
|
||||
except Exception, e:
|
||||
# Only send back traceback in HTTP in debug mode.
|
||||
self.handle_error(client, e)
|
||||
self.handle_error(req, client, addr, e)
|
||||
return
|
||||
finally:
|
||||
try:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user