def process_response(self, request, response): if django_settings.DEBUG and not self.client.config.debug: return response try: if hasattr(response, "status_code"): transaction_name = None if self.client.config.django_transaction_name_from_route and hasattr( request.resolver_match, "route"): transaction_name = request.resolver_match.route elif getattr(request, "_zuqa_view_func", False): transaction_name = get_name_from_func( request._zuqa_view_func) if transaction_name: transaction_name = build_name_with_http_method_prefix( transaction_name, request) zuqa.set_transaction_name(transaction_name, override=False) zuqa.set_context( lambda: self.client.get_data_from_request( request, constants.TRANSACTION), "request") zuqa.set_context( lambda: self.client.get_data_from_response( response, constants.TRANSACTION), "response") zuqa.set_context(lambda: self.client.get_user_info(request), "user") zuqa.set_transaction_result("HTTP {}xx".format( response.status_code // 100), override=False) except Exception: self.client.error_logger.error( "Exception during timing of request", exc_info=True) return response
async def call(self, module, method, wrapped, instance, args, kwargs): if not hasattr(instance.application, "zuqa_client"): # If tornado was instrumented but not as the main framework # (i.e. in Flower), we should skip it. return await wrapped(*args, **kwargs) # Late import to avoid ImportErrors from zuqa.contrib.tornado.utils import get_data_from_request, get_data_from_response request = instance.request trace_parent = TraceParent.from_headers(request.headers) client = instance.application.zuqa_client client.begin_transaction("request", trace_parent=trace_parent) zuqa.set_context( lambda: get_data_from_request(instance, request, client.config, constants.TRANSACTION), "request") # TODO: Can we somehow incorporate the routing rule itself here? zuqa.set_transaction_name("{} {}".format(request.method, type(instance).__name__), override=False) ret = await wrapped(*args, **kwargs) zuqa.set_context( lambda: get_data_from_response(instance, client.config, constants. TRANSACTION), "response") result = "HTTP {}xx".format(instance.get_status() // 100) zuqa.set_transaction_result(result, override=False) client.end_transaction() return ret
async def handle_request(request, handler): zuqa_client = app.get(CLIENT_KEY) if zuqa_client: request[CLIENT_KEY] = zuqa_client trace_parent = AioHttpTraceParent.from_headers(request.headers) zuqa_client.begin_transaction("request", trace_parent=trace_parent) resource = request.match_info.route.resource name = request.method if resource: # canonical has been added in 3.3, and returns one of path, formatter, prefix for attr in ("canonical", "_path", "_formatter", "_prefix"): if hasattr(resource, attr): name += " " + getattr(resource, attr) break else: name += " unknown route" else: name += " unknown route" zuqa.set_transaction_name(name, override=False) zuqa.set_context( lambda: get_data_from_request(request, zuqa_client.config, constants.TRANSACTION), "request") try: response = await handler(request) zuqa.set_transaction_result("HTTP {}xx".format(response.status // 100), override=False) zuqa.set_context( lambda: get_data_from_response(response, zuqa_client.config, constants.TRANSACTION), "response") return response except Exception as exc: if zuqa_client: zuqa_client.capture_exception( context={ "request": get_data_from_request(request, zuqa_client.config, constants.ERROR) }) zuqa.set_transaction_result("HTTP 5xx", override=False) zuqa.set_context({"status_code": 500}, "response") # some exceptions are response-like, e.g. have headers and status code. Let's try and capture them if isinstance(exc, (Response, HTTPException)): zuqa.set_context( lambda: get_data_from_response(exc, zuqa_client.config, constants.ERROR), # noqa: F821 "response", ) raise finally: zuqa_client.end_transaction()
def process_request_wrapper(wrapped, instance, args, kwargs): response = wrapped(*args, **kwargs) try: if response is not None: request = args[0] zuqa.set_transaction_name( build_name_with_http_method_prefix( get_name_from_middleware(wrapped, instance), request)) finally: return response
def request_started(self, app): if not self.app.debug or self.client.config.debug: trace_parent = TraceParent.from_headers(request.headers) self.client.begin_transaction("request", trace_parent=trace_parent) zuqa.set_context( lambda: get_data_from_request(request, self.client.config, constants.TRANSACTION), "request") rule = request.url_rule.rule if request.url_rule is not None else "" rule = build_name_with_http_method_prefix(rule, request) zuqa.set_transaction_name(rule, override=False)
def test_set_transaction_name(zuqa_client): zuqa_client.begin_transaction("test") zuqa_client.end_transaction("test_name", 200) zuqa_client.begin_transaction("test") zuqa.set_transaction_name("another_name") zuqa_client.end_transaction("test_name", 200) transactions = zuqa_client.events[TRANSACTION] assert transactions[0]["name"] == "test_name" assert transactions[1]["name"] == "another_name"
async def _request_started(self, request: Request): """Captures the begin of the request processing to APM. Args: request (Request) """ trace_parent = TraceParent.from_headers(dict(request.headers)) self.client.begin_transaction("request", trace_parent=trace_parent) await set_context( lambda: get_data_from_request(request, self.client.config, constants.TRANSACTION), "request") zuqa.set_transaction_name("{} {}".format(request.method, request.url.path), override=False)
def process_response_wrapper(wrapped, instance, args, kwargs): response = wrapped(*args, **kwargs) try: request, original_response = args # if there's no view_func on the request, and this middleware created # a new response object, it's logged as the responsible transaction # name if not hasattr( request, "_zuqa_view_func") and response is not original_response: zuqa.set_transaction_name( build_name_with_http_method_prefix( get_name_from_middleware(wrapped, instance), request)) finally: return response
def transaction_name(): zuqa.set_transaction_name("foo") zuqa.set_transaction_result("okydoky") return Response("")
def override_transaction_name_view(request): zuqa.set_transaction_name("foo") zuqa.set_transaction_result("okydoky") return HttpResponse()