def __call__(self, env, start_response): start_response_args = [None] input_proxy = InputProxy(env['wsgi.input']) env['wsgi.input'] = input_proxy def my_start_response(status, headers, exc_info=None): start_response_args[0] = (status, list(headers), exc_info) def iter_response(iterable): if start_response_args[0]: start_response(*start_response_args[0]) bytes_sent = 0 try: for chunk in iterable: if chunk: bytes_sent += len(chunk) yield chunk finally: self.publish_sample(env, input_proxy.bytes_received, bytes_sent) try: iterable = self.app(env, my_start_response) except Exception: self.publish_sample(env, input_proxy.bytes_received, 0) raise else: return iter_response(iterable)
def __call__(self, env, start_response): start_response_args = [None] input_proxy = InputProxy(env['wsgi.input']) env['wsgi.input'] = input_proxy start_time = time.time() def my_start_response(status, headers, exc_info=None): start_response_args[0] = (status, list(headers), exc_info) def iter_response(iterable): iterator = iter(iterable) try: chunk = iterator.next() while not chunk: chunk = iterator.next() except StopIteration: chunk = '' for h, v in start_response_args[0][1]: if h.lower() in ('content-length', 'transfer-encoding'): break else: if not chunk: start_response_args[0][1].append(('content-length', '0')) elif isinstance(iterable, list): start_response_args[0][1].append( ('content-length', str(sum(len(i) for i in iterable)))) start_response(*start_response_args[0]) bytes_sent = 0 client_disconnect = False try: while chunk: bytes_sent += len(chunk) yield chunk chunk = iterator.next() except GeneratorExit: # generator was closed before we finished client_disconnect = True raise finally: status_int = int(start_response_args[0][0].split(' ', 1)[0]) self.log_request( env, status_int, input_proxy.bytes_received, bytes_sent, time.time() - start_time, client_disconnect or input_proxy.client_disconnect) try: iterable = self.app(env, my_start_response) except Exception: self.log_request(env, 500, input_proxy.bytes_received, 0, time.time() - start_time, input_proxy.client_disconnect) raise else: return iter_response(iterable)
def __call__(self, env, start_response): if self.req_already_logged(env): return self.app(env, start_response) self.mark_req_logged(env) start_response_args = [None] input_proxy = InputProxy(env['wsgi.input']) env['wsgi.input'] = input_proxy start_time = time.time() def my_start_response(status, headers, exc_info=None): start_response_args[0] = (status, list(headers), exc_info) def status_int_for_logging(client_disconnect=False, start_status=None): # log disconnected clients as '499' status code if client_disconnect or input_proxy.client_disconnect: ret_status_int = 499 elif start_status is None: ret_status_int = int(start_response_args[0][0].split(' ', 1)[0]) else: ret_status_int = start_status return ret_status_int def iter_response(iterable): iterator = iter(iterable) #获取可迭代对象的迭代器 try: chunk = next(iterator) while not chunk: chunk = next(iterator) except StopIteration: chunk = '' for h, v in start_response_args[0][1]: if h.lower() in ('content-length', 'transfer-encoding'): break else: if not chunk: start_response_args[0][1].append(('Content-Length', '0')) elif isinstance(iterable, list): start_response_args[0][1].append( ('Content-Length', str(sum(len(i) for i in iterable)))) resp_headers = dict(start_response_args[0][1]) start_response(*start_response_args[0]) req = Request(env) # Log timing information for time-to-first-byte (GET requests only) method = self.method_from_req(req) if method == 'GET': status_int = status_int_for_logging() policy_index = get_policy_index(req.headers, resp_headers) metric_name = self.statsd_metric_name(req, status_int, method) metric_name_policy = self.statsd_metric_name_policy( req, status_int, method, policy_index) if metric_name: self.access_logger.timing_since( metric_name + '.first-byte.timing', start_time) if metric_name_policy: self.access_logger.timing_since( metric_name_policy + '.first-byte.timing', start_time) bytes_sent = 0 client_disconnect = False try: while chunk: bytes_sent += len(chunk) yield chunk chunk = next(iterator) except GeneratorExit: # generator was closed before we finished client_disconnect = True raise finally: status_int = status_int_for_logging(client_disconnect) self.log_request(req, status_int, input_proxy.bytes_received, bytes_sent, start_time, time.time(), resp_headers=resp_headers) close_method = getattr(iterable, 'close', None) if callable(close_method): close_method() try: iterable = self.app(env, my_start_response) except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() req = Request(env) status_int = status_int_for_logging(start_status=500) self.log_request(req, status_int, input_proxy.bytes_received, 0, start_time, time.time()) six.reraise(exc_type, exc_value, exc_traceback) else: return iter_response(iterable)
def __call__(self, env, start_response): start_response_args = [None] input_proxy = InputProxy(env['wsgi.input']) env['wsgi.input'] = input_proxy start_time = time.time() def my_start_response(status, headers, exc_info=None): start_response_args[0] = (status, list(headers), exc_info) def status_int_for_logging(client_disconnect=False, start_status=None): # log disconnected clients as '499' status code if client_disconnect or input_proxy.client_disconnect: return 499 elif start_status is None: return int(start_response_args[0][0].split(' ', 1)[0]) return start_status def iter_response(iterable): iterator = iter(iterable) try: chunk = iterator.next() while not chunk: chunk = iterator.next() except StopIteration: chunk = '' for h, v in start_response_args[0][1]: if h.lower() in ('content-length', 'transfer-encoding'): break else: if not chunk: start_response_args[0][1].append(('content-length', '0')) elif isinstance(iterable, list): start_response_args[0][1].append( ('content-length', str(sum(len(i) for i in iterable)))) start_response(*start_response_args[0]) req = Request(env) # Log timing information for time-to-first-byte (GET requests only) method = self.method_from_req(req) if method == 'GET' and not self.req_already_logged(req): status_int = status_int_for_logging() metric_name = self.statsd_metric_name(req, status_int, method) if metric_name: self.access_logger.timing_since( metric_name + '.first-byte.timing', start_time) bytes_sent = 0 client_disconnect = False try: while chunk: bytes_sent += len(chunk) yield chunk chunk = iterator.next() except GeneratorExit: # generator was closed before we finished client_disconnect = True raise finally: status_int = status_int_for_logging(client_disconnect) self.log_request(req, status_int, input_proxy.bytes_received, bytes_sent, time.time() - start_time) try: iterable = self.app(env, my_start_response) except Exception: req = Request(env) status_int = status_int_for_logging(start_status=500) self.log_request(req, status_int, input_proxy.bytes_received, 0, time.time() - start_time) raise else: return iter_response(iterable)
def __call__(self, env, start_response): if self.req_already_logged(env): return self.app(env, start_response) self.mark_req_logged(env) start_response_args = [None] input_proxy = InputProxy(env['wsgi.input']) env['wsgi.input'] = input_proxy start_time = time.time() def my_start_response(status, headers, exc_info=None): start_response_args[0] = (status, list(headers), exc_info) def status_int_for_logging(start_status, client_disconnect=False): # log disconnected clients as '499' status code if client_disconnect or input_proxy.client_disconnect: return 499 return start_status def iter_response(iterable): iterator = reiterate(iterable) content_length = None for h, v in start_response_args[0][1]: if h.lower() == 'content-length': content_length = int(v) break elif h.lower() == 'transfer-encoding': break else: if isinstance(iterator, list): content_length = sum(len(i) for i in iterator) start_response_args[0][1].append( ('Content-Length', str(content_length))) req = Request(env) method = self.method_from_req(req) if method == 'HEAD': content_length = 0 if content_length is not None: iterator = enforce_byte_count(iterator, content_length) wire_status_int = int(start_response_args[0][0].split(' ', 1)[0]) resp_headers = dict(start_response_args[0][1]) start_response(*start_response_args[0]) # Log timing information for time-to-first-byte (GET requests only) ttfb = 0.0 if method == 'GET': policy_index = get_policy_index(req.headers, resp_headers) metric_name = self.statsd_metric_name(req, wire_status_int, method) metric_name_policy = self.statsd_metric_name_policy( req, wire_status_int, method, policy_index) ttfb = time.time() - start_time if metric_name: self.access_logger.timing( metric_name + '.first-byte.timing', ttfb * 1000) if metric_name_policy: self.access_logger.timing( metric_name_policy + '.first-byte.timing', ttfb * 1000) bytes_sent = 0 client_disconnect = False start_status = wire_status_int try: for chunk in iterator: bytes_sent += len(chunk) yield chunk except StopIteration: # iterator was depleted return except GeneratorExit: # generator was closed before we finished client_disconnect = True raise except Exception: start_status = 500 raise finally: status_int = status_int_for_logging(start_status, client_disconnect) self.log_request(req, status_int, input_proxy.bytes_received, bytes_sent, start_time, time.time(), resp_headers=resp_headers, ttfb=ttfb, wire_status_int=wire_status_int) iterator.close() try: iterable = self.app(env, my_start_response) except Exception: req = Request(env) status_int = status_int_for_logging(500) self.log_request(req, status_int, input_proxy.bytes_received, 0, start_time, time.time()) raise else: return iter_response(iterable)