WSGI middleware for logging the status.
| 263 | |
| 264 | |
| 265 | class LogMiddleware: |
| 266 | """WSGI middleware for logging the status.""" |
| 267 | |
| 268 | def __init__(self, app): |
| 269 | self.app = app |
| 270 | self.format = '%s - - [%s] "%s %s %s" - %s' |
| 271 | |
| 272 | f = BytesIO() |
| 273 | |
| 274 | class FakeSocket: |
| 275 | def makefile(self, *a): |
| 276 | return f |
| 277 | |
| 278 | # take log_date_time_string method from BaseHTTPRequestHandler |
| 279 | self.log_date_time_string = BaseHTTPRequestHandler( |
| 280 | FakeSocket(), None, None |
| 281 | ).log_date_time_string |
| 282 | |
| 283 | def __call__(self, environ, start_response): |
| 284 | def xstart_response(status, response_headers, *args): |
| 285 | out = start_response(status, response_headers, *args) |
| 286 | self.log(status, environ) |
| 287 | return out |
| 288 | |
| 289 | return self.app(environ, xstart_response) |
| 290 | |
| 291 | def log(self, status, environ): |
| 292 | outfile = environ.get("wsgi.errors", web.debug) |
| 293 | req = environ.get("PATH_INFO", "_") |
| 294 | protocol = environ.get("ACTUAL_SERVER_PROTOCOL", "-") |
| 295 | method = environ.get("REQUEST_METHOD", "-") |
| 296 | host = "{}:{}".format( |
| 297 | environ.get("REMOTE_ADDR", "-"), |
| 298 | environ.get("REMOTE_PORT", "-"), |
| 299 | ) |
| 300 | |
| 301 | time = self.log_date_time_string() |
| 302 | |
| 303 | msg = self.format % (host, time, protocol, method, req, status) |
| 304 | print(utils.safestr(msg), file=outfile) |