diff --git a/gunicorn/glogging.py b/gunicorn/glogging.py index a5268cf2..f1e5a0d4 100644 --- a/gunicorn/glogging.py +++ b/gunicorn/glogging.py @@ -93,7 +93,7 @@ class Logger(object): 'r': "%s %s %s" % (environ['REQUEST_METHOD'], environ['RAW_URI'], environ["SERVER_PROTOCOL"]), 's': status, - 'b': str(resp.clength) or '-', + 'b': str(resp.response_length) or '-', 'f': environ.get('HTTP_REFERER', '-'), 'a': environ.get('HTTP_USER_AGENT', '-'), 'T': str(request_time.seconds), diff --git a/gunicorn/http/message.py b/gunicorn/http/message.py index e67930a2..d2b97bf9 100644 --- a/gunicorn/http/message.py +++ b/gunicorn/http/message.py @@ -61,25 +61,25 @@ class Message(object): def set_body_reader(self): chunked = False - clength = None + response_length = None for (name, value) in self.headers: if name == "CONTENT-LENGTH": try: - clength = int(value) + response_length = int(value) except ValueError: - clength = None + response_length = None elif name == "TRANSFER-ENCODING": chunked = value.lower() == "chunked" elif name == "SEC-WEBSOCKET-KEY1": - clength = 8 + response_length = 8 - if clength is not None or chunked: + if response_length is not None or chunked: break if chunked: self.body = Body(ChunkedReader(self, self.unreader)) - elif clength is not None: - self.body = Body(LengthReader(self.unreader, clength)) + elif response_length is not None: + self.body = Body(LengthReader(self.unreader, response_length)) else: self.body = Body(EOFReader(self.unreader)) diff --git a/gunicorn/http/wsgi.py b/gunicorn/http/wsgi.py index 7872104a..c6a0ef70 100644 --- a/gunicorn/http/wsgi.py +++ b/gunicorn/http/wsgi.py @@ -154,7 +154,7 @@ class Response(object): self.must_close = False self.headers = [] self.headers_sent = False - self.clength = None + self.response_length = None self.sent = 0 def force_close(self): @@ -163,7 +163,7 @@ class Response(object): def should_close(self): if self.must_close or self.req.should_close(): return True - if self.clength is not None or self.chunked: + if self.response_length is not None or self.chunked: return False return True @@ -187,7 +187,7 @@ class Response(object): assert isinstance(name, basestring), "%r is not a string" % name lname = name.lower().strip() if lname == "content-length": - self.clength = int(value) + self.response_length = int(value) elif util.is_hoppish(name): if lname == "connection": # handle websocket @@ -203,7 +203,7 @@ class Response(object): # Only use chunked responses when the client is # speaking HTTP/1.1 or newer and there was # no Content-Length header set. - if self.clength is not None: + if self.response_length is not None: return False elif self.req.version <= (1,0): return False @@ -242,12 +242,12 @@ class Response(object): arglen = len(arg) tosend = arglen - if self.clength is not None: - if self.sent >= self.clength: - # Never write more than self.clength bytes + if self.response_length is not None: + if self.sent >= self.response_length: + # Never write more than self.response_length bytes return - tosend = min(self.clength - self.sent, tosend) + tosend = min(self.response_length - self.sent, tosend) if tosend < arglen: arg = arg[:tosend] @@ -287,8 +287,8 @@ class Response(object): fo_offset = respiter.filelike.tell() nbytes = max(os.fstat(fileno).st_size - fo_offset, 0) - if self.clength: - nbytes = min(nbytes, self.clength) + if self.response_length: + nbytes = min(nbytes, self.response_length) if nbytes == 0: return diff --git a/gunicorn/workers/ggevent.py b/gunicorn/workers/ggevent.py index 586d8ec1..24974f14 100644 --- a/gunicorn/workers/ggevent.py +++ b/gunicorn/workers/ggevent.py @@ -7,6 +7,7 @@ from __future__ import with_statement import os import sys +from datetime import datetime # workaround on osx, disable kqueue if sys.platform == "darwin": @@ -131,8 +132,9 @@ class GeventBaseWorker(Worker): self.socket.setblocking(1) pool = Pool(self.worker_connections) self.server_class.base_env['wsgi.multiprocess'] = (self.cfg.workers > 1) - server = self.server_class(self.socket, application=self.wsgi, - spawn=pool, handler_class=self.wsgi_handler) + server = self.server_class( + self.socket, application=self.wsgi, spawn=pool, log=self.log, + handler_class=self.wsgi_handler) server.start() try: while self.alive: @@ -165,8 +167,12 @@ class GeventBaseWorker(Worker): class PyWSGIHandler(pywsgi.WSGIHandler): - def log_request(self, *args): - pass + + def log_request(self): + start = datetime.fromtimestamp(self.time_start) + finish = datetime.fromtimestamp(self.time_finish) + response_time = finish - start + self.server.log.access(self, self.environ, response_time) def get_environ(self): env = super(PyWSGIHandler, self).get_environ() diff --git a/gunicorn/workers/ggevent_wsgi.py b/gunicorn/workers/ggevent_wsgi.py index 9bf79055..fc9b1185 100644 --- a/gunicorn/workers/ggevent_wsgi.py +++ b/gunicorn/workers/ggevent_wsgi.py @@ -8,14 +8,26 @@ from gevent import wsgi class WSGIHandler(wsgi.WSGIHandler): - def log_request(self, *args): - pass + + @property + def status(self): + return ' '.join([str(self.code), self.reason]) + + def log_request(self, length): + self.response_length = length + response_time = datetime.now() - self.time_start + self.server.log.access(self, self.environ, response_time) def prepare_env(self): env = super(WSGIHandler, self).prepare_env() env['RAW_URI'] = self.request.uri + self.environ = env return env - + + def handle(self): + self.time_start = datetime.now() + super(WSGIHandler, self).handle() + class WSGIServer(wsgi.WSGIServer): base_env = BASE_WSGI_ENV