Mercurial > kallithea
changeset 7908:19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
The WSGI protocol allow for explicit writes and for iterator yields, and we
thus have to do accounting in both places.
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Wed, 09 Oct 2019 12:23:21 +0200 |
parents | b42ee1bdf082 |
children | 08b6aa79f213 |
files | kallithea/lib/middleware/wrapper.py |
diffstat | 1 files changed, 20 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/lib/middleware/wrapper.py Sat Oct 19 23:07:12 2019 +0200 +++ b/kallithea/lib/middleware/wrapper.py Wed Oct 09 12:23:21 2019 +0200 @@ -38,12 +38,27 @@ class Meter: - def __init__(self): + def __init__(self, start_response): + self._start_response = start_response self._start = time.time() + self._size = 0 def duration(self): return time.time() - self._start + def start_response(self, status, response_headers, exc_info=None): + write = self._start_response(status, response_headers, exc_info) + def metered_write(s): + self.measure(s) + write(s) + return metered_write + + def measure(self, chunk): + self._size += len(chunk) + + def size(self): + return self._size + class ResultIter: @@ -58,11 +73,12 @@ def next(self): chunk = self._next() + self._meter.measure(chunk) return chunk def close(self): self._result_close() - log.info("%s responded after %.3fs", self._description, self._meter.duration()) + log.info("%s responded after %.3fs with %s bytes", self._description, self._meter.duration(), self._meter.size()) class RequestWrapper(object): @@ -72,13 +88,13 @@ self.config = config def __call__(self, environ, start_response): - meter = Meter() + meter = Meter(start_response) description = "Request from %s for %s" % ( _get_ip_addr(environ), safe_unicode(_get_access_path(environ)), ) try: - result = self.application(environ, start_response) + result = self.application(environ, meter.start_response) finally: log.info("%s responding after %.3fs", description, meter.duration()) return ResultIter(result, meter, description)