def _handle_exception(request): global in_lambda_ctx global _recorder if not request.exception: return segment = None try: if in_lambda_ctx: try: segment = _recorder.current_subsegment() except SegmentNotFoundException: segment = __create_segment(request, _recorder, lambda_ctx=in_lambda_ctx) else: try: segment = _recorder.current_segment() except SegmentNotFoundException: segment = __create_segment(request, _recorder, lambda_ctx=in_lambda_ctx) except Exception: pass if not segment: return segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace(limit=_recorder._max_trace_back) segment.add_exception(request.exception, stack) if in_lambda_ctx: _recorder.end_subsegment() else: _recorder.end_segment()
def process_exception(self, request, exception): """ Add exception information and fault flag to the current segment. """ segment = xray_recorder.current_segment() segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back) segment.add_exception(exception, stack)
async def end_subsegment_with_exception(session, trace_config_ctx, params): if trace_config_ctx.give_up: return subsegment = xray_recorder.current_subsegment() subsegment.add_exception( params.exception, stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)) if isinstance(params.exception, LOCAL_EXCEPTIONS): subsegment.namespace = LOCAL_NAMESPACE xray_recorder.end_subsegment()
def process_exception(self, request, exception): """ Add exception information and fault flag to the current segment. """ if not environ.get('AWS_EXECUTION_ENV', '').startswith('AWS_Lambda_'): return segment = xray_recorder.current_subsegment() segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back) segment.add_exception(exception, stack)
def _handle_exception(self, exception): if not exception: return segment = None try: segment = self._recorder.current_segment() except Exception: pass if not segment: return segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace(limit=self._recorder._max_trace_back) segment.add_exception(exception, stack) self._recorder.end_segment()
def _process_request(wrapped, engine_instance, args, kwargs): name, sql = _sql_meta(engine_instance, args) if sql is not None: subsegment = xray_recorder.begin_subsegment(name, namespace='remote') else: subsegment = None try: res = wrapped(*args, **kwargs) except Exception: if subsegment is not None: exception = sys.exc_info()[1] stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back) subsegment.add_exception(exception, stack) raise finally: if subsegment is not None: subsegment.set_sql(sql) xray_recorder.end_subsegment() return res
def _teardown_request(self, exception): segment = None try: if self.in_lambda_ctx: segment = self._recorder.current_subsegment() else: segment = self._recorder.current_segment() except Exception: pass if not segment: return if exception: segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace(limit=self._recorder._max_trace_back) segment.add_exception(exception, stack) if self.in_lambda_ctx: self._recorder.end_subsegment() else: self._recorder.end_segment()
async def record_subsegment_async(self, wrapped, instance, args, kwargs, name, namespace, meta_processor): subsegment = self.begin_subsegment(name, namespace) exception = None stack = None return_value = None try: return_value = await wrapped(*args, **kwargs) return return_value except Exception as e: exception = e stack = stacktrace.get_stacktrace(limit=self._max_trace_back) raise finally: # No-op if subsegment is `None` due to `LOG_ERROR`. if subsegment is not None: end_time = time.time() if callable(meta_processor): meta_processor( wrapped=wrapped, instance=instance, args=args, kwargs=kwargs, return_value=return_value, exception=exception, subsegment=subsegment, stack=stack, ) elif exception: if subsegment: subsegment.add_exception(exception, stack) self.end_subsegment(end_time)
async def middleware(request, handler): """ Main middleware function, deals with all the X-Ray segment logic """ # Create X-Ray headers xray_header = construct_xray_header(request.headers) # Get name of service or generate a dynamic one from host name = calculate_segment_name(request.headers['host'].split(':', 1)[0], xray_recorder) sampling_req = { 'host': request.headers['host'], 'method': request.method, 'path': request.path, 'service': name, } sampling_decision = calculate_sampling_decision( trace_header=xray_header, recorder=xray_recorder, sampling_req=sampling_req, ) # Start a segment segment = xray_recorder.begin_segment( name=name, traceid=xray_header.root, parent_id=xray_header.parent, sampling=sampling_decision, ) segment.save_origin_trace_header(xray_header) # Store request metadata in the current segment segment.put_http_meta(http.URL, str(request.url)) segment.put_http_meta(http.METHOD, request.method) if 'User-Agent' in request.headers: segment.put_http_meta(http.USER_AGENT, request.headers['User-Agent']) if 'X-Forwarded-For' in request.headers: segment.put_http_meta(http.CLIENT_IP, request.headers['X-Forwarded-For']) segment.put_http_meta(http.X_FORWARDED_FOR, True) elif 'remote_addr' in request.headers: segment.put_http_meta(http.CLIENT_IP, request.headers['remote_addr']) else: segment.put_http_meta(http.CLIENT_IP, request.remote) try: # Call next middleware or request handler response = await handler(request) except HTTPException as exc: # Non 2XX responses are raised as HTTPExceptions response = exc raise except Exception as err: # Store exception information including the stacktrace to the segment response = None segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace(limit=xray_recorder.max_trace_back) segment.add_exception(err, stack) raise finally: if response is not None: segment.put_http_meta(http.STATUS, response.status) if 'Content-Length' in response.headers: length = int(response.headers['Content-Length']) segment.put_http_meta(http.CONTENT_LENGTH, length) header_str = prepare_response_header(xray_header, segment) response.headers[http.XRAY_HEADER] = header_str xray_recorder.end_segment() return response
async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response: """ Main middleware function, deals with all the X-Ray segment logic """ # Create X-Ray headers headers = request.headers xray_header = construct_xray_header(headers) # Get name of service or generate a dynamic one from host name = calculate_segment_name(headers["host"].split(":", 1)[0], self._recorder) sampling_req = { "host": headers["host"], "method": request.method, "path": request.url.path, "service": name, } sampling_decision = calculate_sampling_decision( trace_header=xray_header, recorder=self._recorder, sampling_req=sampling_req) # Start a segment if self.in_lambda_ctx: segment = self._recorder.begin_subsegment(name) else: segment = self._recorder.begin_segment( name=name, traceid=xray_header.root, parent_id=xray_header.parent, sampling=sampling_decision, ) # Store request metadata in the current segment segment.save_origin_trace_header(xray_header) segment.put_http_meta(http.URL, str(request.url)) segment.put_http_meta(http.METHOD, request.method) if "User-Agent" in request.headers: segment.put_http_meta(http.USER_AGENT, request.headers["User-Agent"]) if "X-Forwarded-For" in request.headers: segment.put_http_meta(http.CLIENT_IP, request.headers["X-Forwarded-For"]) segment.put_http_meta(http.X_FORWARDED_FOR, True) elif "remote_addr" in request.headers: segment.put_http_meta(http.CLIENT_IP, request.headers["remote_addr"]) else: segment.put_http_meta(http.CLIENT_IP, f"{request.client[0]}:{request.client[1]}") try: # Call next middleware or request handler response = await call_next(request) segment.put_http_meta(http.STATUS, response.status_code) if "Content-Length" in response.headers: length = int(response.headers["Content-Length"]) segment.put_http_meta(http.CONTENT_LENGTH, length) header_str = prepare_response_header(xray_header, segment) response.headers[http.XRAY_HEADER] = header_str except HTTPException as exc: segment.put_http_meta(http.STATUS, exc.status_code) raise except Exception as err: # Store exception information including the stacktrace to the segment segment.put_http_meta(http.STATUS, 500) stack = stacktrace.get_stacktrace( limit=xray_recorder.max_trace_back) segment.add_exception(err, stack) raise finally: if self.in_lambda_ctx: self._recorder.end_subsegment() else: self._recorder.end_segment() return response
def wrapper(*a, **ka): headers = request.headers xray_header = construct_xray_header(headers) name = calculate_segment_name(request.urlparts[1], self._recorder) sampling_req = { 'host': request.urlparts[1], 'method': request.method, 'path': request.path, 'service': name, } sampling_decision = calculate_sampling_decision( trace_header=xray_header, recorder=self._recorder, sampling_req=sampling_req, ) if self._in_lambda_ctx: segment = self._recorder.begin_subsegment(name) else: segment = self._recorder.begin_segment( name=name, traceid=xray_header.root, parent_id=xray_header.parent, sampling=sampling_decision, ) segment.save_origin_trace_header(xray_header) segment.put_http_meta(http.URL, request.url) segment.put_http_meta(http.METHOD, request.method) segment.put_http_meta(http.USER_AGENT, headers.get('User-Agent')) client_ip = request.environ.get( 'HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR') if client_ip: segment.put_http_meta(http.CLIENT_IP, client_ip) segment.put_http_meta(http.X_FORWARDED_FOR, True) else: segment.put_http_meta(http.CLIENT_IP, request.remote_addr) try: rv = callback(*a, **ka) except Exception as resp: segment.put_http_meta(http.STATUS, getattr(resp, 'status_code', 500)) stack = stacktrace.get_stacktrace( limit=self._recorder._max_trace_back) segment.add_exception(resp, stack) if self._in_lambda_ctx: self._recorder.end_subsegment() else: self._recorder.end_segment() raise resp segment.put_http_meta(http.STATUS, response.status_code) origin_header = segment.get_origin_trace_header() resp_header_str = prepare_response_header(origin_header, segment) response.set_header(http.XRAY_HEADER, resp_header_str) cont_len = response.headers.get('Content-Length') if cont_len: segment.put_http_meta(http.CONTENT_LENGTH, int(cont_len)) if self._in_lambda_ctx: self._recorder.end_subsegment() else: self._recorder.end_segment() return rv