def _start_span(tracer, handler, start_time) -> _TraceContext: span, token = _start_internal_or_server_span( tracer=tracer, span_name=_get_operation_name(handler, handler.request), start_time=start_time, context_carrier=handler.request.headers, context_getter=textmap.default_getter, ) if span.is_recording(): attributes = _get_attributes_from_request(handler.request) for key, value in attributes.items(): span.set_attribute(key, value) span.set_attribute("tornado.handler", _get_full_handler_name(handler)) if span.is_recording() and span.kind == trace.SpanKind.SERVER: custom_attributes = _collect_custom_request_headers_attributes( handler.request.headers) if len(custom_attributes) > 0: span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 ctx = _TraceContext(activation, span, token) setattr(handler, _HANDLER_CONTEXT_KEY, ctx) # finish handler is called after the response is sent back to # the client so it is too late to inject trace response headers # there. propagator = get_global_response_propagator() if propagator: propagator.inject(handler, setter=response_propagation_setter) return ctx
def _before_traversal(event): request = event.request request_environ = request.environ span_name = otel_wsgi.get_default_span_name(request_environ) enabled = request_environ.get(_ENVIRON_ENABLED_KEY) if enabled is None: _logger.warning( "Opentelemetry pyramid tween 'opentelemetry.instrumentation.pyramid.trace_tween_factory'" "was not called. Make sure that the tween is included in 'pyramid.tweens' if" "the tween list was created manually") return if not enabled: # Tracing not enabled, return return start_time = request_environ.get(_ENVIRON_STARTTIME_KEY) tracer = trace.get_tracer(__name__, __version__) if request.matched_route: span_name = request.matched_route.pattern else: span_name = otel_wsgi.get_default_span_name(request_environ) span, token = _start_internal_or_server_span( tracer=tracer, span_name=span_name, start_time=start_time, context_carrier=request_environ, context_getter=otel_wsgi.wsgi_getter, ) if span.is_recording(): attributes = otel_wsgi.collect_request_attributes(request_environ) if request.matched_route: attributes[ SpanAttributes.HTTP_ROUTE] = request.matched_route.pattern for key, value in attributes.items(): span.set_attribute(key, value) if span.kind == trace.SpanKind.SERVER: custom_attributes = ( otel_wsgi.collect_custom_request_headers_attributes( request_environ)) if len(custom_attributes) > 0: span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 request_environ[_ENVIRON_ACTIVATION_KEY] = activation request_environ[_ENVIRON_SPAN_KEY] = span if token: request_environ[_ENVIRON_TOKEN] = token
def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ req_attrs = collect_request_attributes(environ) active_requests_count_attrs = _parse_active_request_count_attrs( req_attrs) duration_attrs = _parse_duration_attrs(req_attrs) span, token = _start_internal_or_server_span( tracer=self.tracer, span_name=get_default_span_name(environ), start_time=None, context_carrier=environ, context_getter=wsgi_getter, attributes=req_attrs, ) if span.is_recording() and span.kind == trace.SpanKind.SERVER: custom_attributes = collect_custom_request_headers_attributes( environ) if len(custom_attributes) > 0: span.set_attributes(custom_attributes) if self.request_hook: self.request_hook(span, environ) response_hook = self.response_hook if response_hook: response_hook = functools.partial(response_hook, span, environ) start = default_timer() self.active_requests_counter.add(1, active_requests_count_attrs) try: with trace.use_span(span): start_response = self._create_start_response( span, start_response, response_hook, duration_attrs) iterable = self.wsgi(environ, start_response) return _end_span_after_iterating(iterable, span, token) except Exception as ex: if span.is_recording(): span.set_status(Status(StatusCode.ERROR, str(ex))) span.end() if token is not None: context.detach(token) raise finally: duration = max(round((default_timer() - start) * 1000), 0) self.duration_histogram.record(duration, duration_attrs) self.active_requests_counter.add(-1, active_requests_count_attrs)
def __call__(self, env, start_response): # pylint: disable=E1101 if self._otel_excluded_urls.url_disabled(env.get("PATH_INFO", "/")): return super().__call__(env, start_response) start_time = _time_ns() span, token = _start_internal_or_server_span( tracer=self._otel_tracer, span_name=otel_wsgi.get_default_span_name(env), start_time=start_time, context_carrier=env, context_getter=otel_wsgi.wsgi_getter, ) if span.is_recording(): attributes = otel_wsgi.collect_request_attributes(env) for key, value in attributes.items(): span.set_attribute(key, value) if span.is_recording() and span.kind == trace.SpanKind.SERVER: custom_attributes = ( otel_wsgi.collect_custom_request_headers_attributes(env) ) if len(custom_attributes) > 0: span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() env[_ENVIRON_SPAN_KEY] = span env[_ENVIRON_ACTIVATION_KEY] = activation def _start_response(status, response_headers, *args, **kwargs): response = start_response( status, response_headers, *args, **kwargs ) activation.__exit__(None, None, None) if token is not None: context.detach(token) return response try: return super().__call__(env, _start_response) except Exception as exc: activation.__exit__( type(exc), exc, getattr(exc, "__traceback__", None), ) if token is not None: context.detach(token) raise
def _before_request(): if excluded_urls and excluded_urls.url_disabled(flask.request.url): return flask_request_environ = flask.request.environ span_name = get_default_span_name() span, token = _start_internal_or_server_span( tracer=tracer, span_name=span_name, start_time=flask_request_environ.get(_ENVIRON_STARTTIME_KEY), context_carrier=flask_request_environ, context_getter=otel_wsgi.wsgi_getter, ) if request_hook: request_hook(span, flask_request_environ) if span.is_recording(): attributes = otel_wsgi.collect_request_attributes( flask_request_environ) if flask.request.url_rule: # For 404 that result from no route found, etc, we # don't have a url_rule. attributes[ SpanAttributes.HTTP_ROUTE] = flask.request.url_rule.rule for key, value in attributes.items(): span.set_attribute(key, value) if span.is_recording() and span.kind == trace.SpanKind.SERVER: custom_attributes = ( otel_wsgi.collect_custom_request_headers_attributes( flask_request_environ)) if len(custom_attributes) > 0: span.set_attributes(custom_attributes) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 flask_request_environ[_ENVIRON_ACTIVATION_KEY] = activation flask_request_environ[_ENVIRON_SPAN_KEY] = span flask_request_environ[_ENVIRON_TOKEN] = token
def process_request(self, request): # request.META is a dictionary containing all available HTTP headers # Read more about request.META here: # https://docs.djangoproject.com/en/3.0/ref/request-response/#django.http.HttpRequest.META if self._excluded_urls.url_disabled(request.build_absolute_uri("?")): return is_asgi_request = _is_asgi_request(request) if not _is_asgi_supported and is_asgi_request: return # pylint:disable=W0212 request._otel_start_time = time() request_meta = request.META if is_asgi_request: carrier = request.scope carrier_getter = asgi_getter collect_request_attributes = asgi_collect_request_attributes else: carrier = request_meta carrier_getter = wsgi_getter collect_request_attributes = wsgi_collect_request_attributes span, token = _start_internal_or_server_span( tracer=self._tracer, span_name=self._get_span_name(request), start_time=request_meta.get( "opentelemetry-instrumentor-django.starttime_key" ), context_carrier=carrier, context_getter=carrier_getter, ) attributes = collect_request_attributes(carrier) active_requests_count_attrs = _parse_active_request_count_attrs( attributes ) duration_attrs = _parse_duration_attrs(attributes) request.META[ self._environ_active_request_attr_key ] = active_requests_count_attrs request.META[self._environ_duration_attr_key] = duration_attrs self._active_request_counter.add(1, active_requests_count_attrs) if span.is_recording(): attributes = extract_attributes_from_object( request, self._traced_request_attrs, attributes ) if is_asgi_request: # ASGI requests include extra attributes in request.scope.headers. attributes = extract_attributes_from_object( types.SimpleNamespace( **{ name.decode("latin1"): value.decode("latin1") for name, value in request.scope.get("headers", []) } ), self._traced_request_attrs, attributes, ) if span.is_recording() and span.kind == SpanKind.SERVER: attributes.update( asgi_collect_custom_request_attributes(carrier) ) else: if span.is_recording() and span.kind == SpanKind.SERVER: custom_attributes = ( wsgi_collect_custom_request_headers_attributes(carrier) ) if len(custom_attributes) > 0: span.set_attributes(custom_attributes) for key, value in attributes.items(): span.set_attribute(key, value) activation = use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 request_start_time = default_timer() request.META[self._environ_timer_key] = request_start_time request.META[self._environ_activation_key] = activation request.META[self._environ_span_key] = span if token: request.META[self._environ_token] = token if _DjangoMiddleware._otel_request_hook: _DjangoMiddleware._otel_request_hook( # pylint: disable=not-callable span, request )
async def __call__(self, scope, receive, send): """The ASGI application Args: scope: A ASGI environment. receive: An awaitable callable yielding dictionaries send: An awaitable callable taking a single dictionary as argument. """ if scope["type"] not in ("http", "websocket"): return await self.app(scope, receive, send) _, _, url = get_host_port_url_tuple(scope) if self.excluded_urls and self.excluded_urls.url_disabled(url): return await self.app(scope, receive, send) span_name, additional_attributes = self.default_span_details(scope) span, token = _start_internal_or_server_span( tracer=self.tracer, span_name=span_name, start_time=None, context_carrier=scope, context_getter=asgi_getter, ) attributes = collect_request_attributes(scope) attributes.update(additional_attributes) active_requests_count_attrs = _parse_active_request_count_attrs( attributes ) duration_attrs = _parse_duration_attrs(attributes) if scope["type"] == "http": self.active_requests_counter.add(1, active_requests_count_attrs) try: with trace.use_span(span, end_on_exit=True) as current_span: if current_span.is_recording(): for key, value in attributes.items(): current_span.set_attribute(key, value) if current_span.kind == trace.SpanKind.SERVER: custom_attributes = ( collect_custom_request_headers_attributes(scope) ) if len(custom_attributes) > 0: current_span.set_attributes(custom_attributes) if callable(self.server_request_hook): self.server_request_hook(current_span, scope) otel_receive = self._get_otel_receive( span_name, scope, receive ) otel_send = self._get_otel_send( current_span, span_name, scope, send, duration_attrs, ) start = default_timer() await self.app(scope, otel_receive, otel_send) finally: if scope["type"] == "http": duration = max(round((default_timer() - start) * 1000), 0) self.duration_histogram.record(duration, duration_attrs) self.active_requests_counter.add( -1, active_requests_count_attrs ) if token: context.detach(token)