Mercurial > kallithea
annotate kallithea/config/middleware/wrapper.py @ 8791:b3d8a3000a7f
lib: cleanup of _get_ip_addr
author | Mads Kiilerich <mads@kiilerich.com> |
---|---|
date | Tue, 10 Nov 2020 17:43:37 +0100 |
parents | f8971422795e |
children | 4f0de9468da3 |
rev | line source |
---|---|
3489
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
1 # -*- coding: utf-8 -*- |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
2 # This program is free software: you can redistribute it and/or modify |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
3 # it under the terms of the GNU General Public License as published by |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
4 # the Free Software Foundation, either version 3 of the License, or |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
5 # (at your option) any later version. |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
6 # |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
7 # This program is distributed in the hope that it will be useful, |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
10 # GNU General Public License for more details. |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
11 # |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
12 # You should have received a copy of the GNU General Public License |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
13 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
4116
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
14 """ |
8771
f8971422795e
scripts: introduce source_format.py to fix up the module name in file headers
Mads Kiilerich <mads@kiilerich.com>
parents:
8684
diff
changeset
|
15 kallithea.config.middleware.wrapper |
f8971422795e
scripts: introduce source_format.py to fix up the module name in file headers
Mads Kiilerich <mads@kiilerich.com>
parents:
8684
diff
changeset
|
16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4116
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
17 |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
18 Wrap app to measure request and response time ... all the way to the response |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
19 WSGI iterator has been closed. |
4116
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
20 |
4211
1948ede028ef
RhodeCode GmbH is not the sole author of this work
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
4208
diff
changeset
|
21 This file was forked by the Kallithea project in July 2014. |
1948ede028ef
RhodeCode GmbH is not the sole author of this work
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
4208
diff
changeset
|
22 Original author and date, and relevant copyright and licensing information is below: |
4116
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
23 :created_on: May 23, 2013 |
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
24 :author: marcink |
4211
1948ede028ef
RhodeCode GmbH is not the sole author of this work
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
4208
diff
changeset
|
25 :copyright: (c) 2013 RhodeCode GmbH, and others. |
4208
ad38f9f93b3b
Correct licensing information in individual files.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
4187
diff
changeset
|
26 :license: GPLv3, see LICENSE.md for more details. |
4116
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
27 """ |
ffd45b185016
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
Bradley M. Kuhn <bkuhn@sfconservancy.org>
parents:
3500
diff
changeset
|
28 |
7811
0a277465fddf
scripts: initial run of import cleanup using isort
Mads Kiilerich <mads@kiilerich.com>
parents:
4918
diff
changeset
|
29 import logging |
3489
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
30 import time |
7811
0a277465fddf
scripts: initial run of import cleanup using isort
Mads Kiilerich <mads@kiilerich.com>
parents:
4918
diff
changeset
|
31 |
8791
b3d8a3000a7f
lib: cleanup of _get_ip_addr
Mads Kiilerich <mads@kiilerich.com>
parents:
8771
diff
changeset
|
32 from kallithea.lib.base import get_ip_addr, get_path_info |
3489
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
33 |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
34 |
7906
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
35 log = logging.getLogger(__name__) |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
36 |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
37 |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
38 class Meter: |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
39 |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
40 def __init__(self, start_response): |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
41 self._start_response = start_response |
7906
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
42 self._start = time.time() |
8325
da39f9548758
middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents:
8177
diff
changeset
|
43 self.status = None |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
44 self._size = 0 |
7906
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
45 |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
46 def duration(self): |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
47 return time.time() - self._start |
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
48 |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
49 def start_response(self, status, response_headers, exc_info=None): |
8325
da39f9548758
middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents:
8177
diff
changeset
|
50 self.status = status |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
51 write = self._start_response(status, response_headers, exc_info) |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
52 def metered_write(s): |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
53 self.measure(s) |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
54 write(s) |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
55 return metered_write |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
56 |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
57 def measure(self, chunk): |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
58 self._size += len(chunk) |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
59 |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
60 def size(self): |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
61 return self._size |
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
62 |
7906
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
63 |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
64 class ResultIter: |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
65 |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
66 def __init__(self, result, meter, description): |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
67 self._result_close = getattr(result, 'close', None) or (lambda: None) |
8177
e26c0616e003
py3: use global next() function instead of .next() method
Mads Kiilerich <mads@kiilerich.com>
parents:
8068
diff
changeset
|
68 self._next = iter(result).__next__ |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
69 self._meter = meter |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
70 self._description = description |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
71 |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
72 def __iter__(self): |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
73 return self |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
74 |
8177
e26c0616e003
py3: use global next() function instead of .next() method
Mads Kiilerich <mads@kiilerich.com>
parents:
8068
diff
changeset
|
75 def __next__(self): |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
76 chunk = self._next() |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
77 self._meter.measure(chunk) |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
78 return chunk |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
79 |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
80 def close(self): |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
81 self._result_close() |
8325
da39f9548758
middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents:
8177
diff
changeset
|
82 log.info("%s responded %r after %.3fs with %s bytes", self._description, self._meter.status, self._meter.duration(), self._meter.size()) |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
83 |
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
84 |
3489
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
85 class RequestWrapper(object): |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
86 |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
87 def __init__(self, app, config): |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
88 self.application = app |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
89 self.config = config |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
90 |
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
91 def __call__(self, environ, start_response): |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
92 meter = Meter(start_response) |
7906
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
93 description = "Request from %s for %s" % ( |
8791
b3d8a3000a7f
lib: cleanup of _get_ip_addr
Mads Kiilerich <mads@kiilerich.com>
parents:
8771
diff
changeset
|
94 get_ip_addr(environ), |
8068
c82ef5ec8dcd
lib: refactor _get_access_path as get_path_info
Mads Kiilerich <mads@kiilerich.com>
parents:
7908
diff
changeset
|
95 get_path_info(environ), |
7906
5240fbde6ddb
wsgi: reintroduce the "wrapper" middleware for logging request timing, but guarded by optional use_wsgi_wrapper=true
Mads Kiilerich <mads@kiilerich.com>
parents:
7811
diff
changeset
|
96 ) |
8350
5da95e8a2d07
wrapper: log clearly when request has been received
Mads Kiilerich <mads@kiilerich.com>
parents:
8325
diff
changeset
|
97 log.info("%s received", description) |
3489
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
98 try: |
7908
19418a4c6c61
wsgi: make WSGI wrapper follow the size of the result and log when it finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7907
diff
changeset
|
99 result = self.application(environ, meter.start_response) |
3489
d997a314d18a
moved time measure of request to separate middleware for better results (the last one in stack)
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
100 finally: |
8325
da39f9548758
middleware: HTTP status code logging in wrapper summaries
Mads Kiilerich <mads@kiilerich.com>
parents:
8177
diff
changeset
|
101 log.info("%s responding %r after %.3fs", description, meter.status, meter.duration()) |
7907
b42ee1bdf082
wsgi: make WSGI wrapper follow the result and log when it actually has finished
Mads Kiilerich <mads@kiilerich.com>
parents:
7906
diff
changeset
|
102 return ResultIter(result, meter, description) |