def _before_flask_request(): environ = flask.request.environ span_name = (flask.request.endpoint or otel_wsgi.get_default_span_name(environ)) token = context.attach( propagators.extract(otel_wsgi.get_header_from_environ, environ)) tracer = trace.get_tracer(__name__, __version__) attributes = otel_wsgi.collect_request_attributes(environ) if flask.request.url_rule: # For 404 that result from no route found, etc, we # don't have a url_rule. attributes["http.route"] = flask.request.url_rule.rule span = tracer.start_span( span_name, kind=trace.SpanKind.SERVER, attributes=attributes, start_time=environ.get(_ENVIRON_STARTTIME_KEY), ) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() environ[_ENVIRON_ACTIVATION_KEY] = activation environ[_ENVIRON_SPAN_KEY] = span environ[_ENVIRON_TOKEN] = token
async def _opentracing_middleware( request: Request, handler: Callable[[Request], Awaitable[StreamResponse]], ) -> StreamResponse: tracer = get_tracer(__name__) attach(extract(_headers_getter, request)) with tracer.start_as_current_span( request.path, kind=SpanKind.SERVER, attributes={ "component": "http", "http.method": request.method, "http.scheme": request.scheme, "http.host": request.host, }, ) as span: try: response = await handler(request) except HTTPException as e: code = _utils.status_to_canonical_code(e.status) span.set_status(Status(code)) span.set_attribute("http.status_text", e.reason) raise else: code = _utils.status_to_canonical_code(response.status) span.set_status(Status(code)) span.set_attribute("http.status_text", response.reason) return response
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 environ = request.META token = attach(extract(get_header_from_environ, environ)) tracer = get_tracer(__name__, __version__) attributes = collect_request_attributes(environ) for attr in self._traced_request_attrs: value = getattr(request, attr, None) if value is not None: attributes[attr] = str(value) span = tracer.start_span( self._get_span_name(request), kind=SpanKind.SERVER, attributes=attributes, start_time=environ.get( "opentelemetry-instrumentor-django.starttime_key"), ) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() request.META[self._environ_activation_key] = activation request.META[self._environ_span_key] = span request.META[self._environ_token] = token
def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ parent_span = propagators.extract(get_header_from_environ, environ) span_name = get_default_span_name(environ) span = self.tracer.start_span( span_name, parent_span, kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(environ), ) try: with self.tracer.use_span(span): start_response = self._create_start_response( span, start_response) iterable = self.wsgi(environ, start_response) return _end_span_after_iterating(iterable, span, self.tracer) except: # noqa # TODO Set span status (cf. https://github.com/open-telemetry/opentelemetry-python/issues/292) span.end() raise
def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ tracer = trace.tracer() parent_span = propagators.extract(get_header_from_environ, environ) span_name = get_default_span_name(environ) span = tracer.start_span( span_name, parent_span, kind=trace.SpanKind.SERVER ) try: with tracer.use_span(span): add_request_attributes(span, environ) start_response = self._create_start_response( span, start_response ) iterable = self.wsgi(environ, start_response) return _end_span_after_iterating(iterable, span, tracer) except: # noqa span.end() raise
def __call__(self, environ, start_response): """The WSGI application Args: environ: A WSGI environment. start_response: The WSGI start_response callable. """ tracer = trace.tracer() path_info = environ["PATH_INFO"] or "/" parent_span = propagators.extract(get_header_from_environ, environ) with tracer.start_span(path_info, parent_span, kind=trace.SpanKind.SERVER) as span: self._add_request_attributes(span, environ) start_response = self._create_start_response(span, start_response) iterable = self.wsgi(environ, start_response) try: for yielded in iterable: yield yielded finally: if hasattr(iterable, "close"): iterable.close()
def test_propagation(self): traceparent_value = "00-{trace_id}-{span_id}-00".format( trace_id=format(self.TRACE_ID, "032x"), span_id=format(self.SPAN_ID, "016x"), ) tracestate_value = "foo=1,bar=2,baz=3" headers = { "otcorrelationcontext": ["key1=val1,key2=val2"], "traceparent": [traceparent_value], "tracestate": [tracestate_value], } ctx = extract(get_as_list, headers) correlations = correlationcontext.get_correlations(context=ctx) expected = {"key1": "val1", "key2": "val2"} self.assertEqual(correlations, expected) span_context = get_span_from_context(context=ctx).get_context() self.assertEqual(span_context.trace_id, self.TRACE_ID) self.assertEqual(span_context.span_id, self.SPAN_ID) span = trace.DefaultSpan(span_context) ctx = correlationcontext.set_correlation("key3", "val3") ctx = correlationcontext.set_correlation("key4", "val4", context=ctx) ctx = set_span_in_context(span, context=ctx) output = {} inject(dict.__setitem__, output, context=ctx) self.assertEqual(traceparent_value, output["traceparent"]) self.assertIn("key3=val3", output["otcorrelationcontext"]) self.assertIn("key4=val4", output["otcorrelationcontext"]) self.assertIn("foo=1", output["tracestate"]) self.assertIn("bar=2", output["tracestate"]) self.assertIn("baz=3", output["tracestate"])
def _before_request(): if _excluded_urls.url_disabled(flask.request.url): return environ = flask.request.environ span_name = name_callback() token = context.attach( propagators.extract(otel_wsgi.carrier_getter, environ)) tracer = trace.get_tracer(__name__, __version__) span = tracer.start_span( span_name, kind=trace.SpanKind.SERVER, start_time=environ.get(_ENVIRON_STARTTIME_KEY), ) if span.is_recording(): attributes = otel_wsgi.collect_request_attributes(environ) if flask.request.url_rule: # For 404 that result from no route found, etc, we # don't have a url_rule. attributes["http.route"] = flask.request.url_rule.rule for key, value in attributes.items(): span.set_attribute(key, value) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() environ[_ENVIRON_ACTIVATION_KEY] = activation environ[_ENVIRON_SPAN_KEY] = span 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. """ token = context.attach( propagators.extract(get_header_from_environ, environ)) span_name = self.name_callback(environ) span = self.tracer.start_span( span_name, kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(environ), ) try: with self.tracer.use_span(span): start_response = self._create_start_response( span, start_response) iterable = self.wsgi(environ, start_response) return _end_span_after_iterating(iterable, span, self.tracer, token) except Exception as ex: span.set_status(Status(StatusCanonicalCode.INTERNAL, str(ex))) span.end() context.detach(token) raise
def process_view(self, request, view_func, view_args, view_kwargs): # pylint: disable=unused-argument # 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 # environ = { # key.lower().replace('_', '-').replace("http-", "", 1): value # for key, value in request.META.items() # } environ = request.META token = attach(extract(get_header_from_environ, environ)) tracer = get_tracer(__name__, __version__) attributes = collect_request_attributes(environ) span = tracer.start_span( view_func.__name__, kind=SpanKind.SERVER, attributes=attributes, start_time=environ.get( "opentelemetry-instrumentor-django.starttime_key"), ) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() request.META[self._environ_activation_key] = activation request.META[self._environ_span_key] = span request.META[self._environ_token] = token
def server_request(): with tracer.start_as_current_span( "server_request", context=propagators.extract(DictGetter(), request.headers), kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(request.environ)): print(request.args.get("param")) return "served"
def server_request(): with tracer.start_as_current_span( "server_request", parent=propagators.extract(lambda dict_, key: dict_.get(key, []), request.headers)["current-span"], ): print(request.args.get("param")) return "served"
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) token = context.attach(propagators.extract(carrier_getter, scope)) span_name, additional_attributes = self.span_details_callback(scope) try: with self.tracer.start_as_current_span( span_name + " asgi", kind=trace.SpanKind.SERVER, ) as span: if span.is_recording(): attributes = collect_request_attributes(scope) attributes.update(additional_attributes) for key, value in attributes.items(): span.set_attribute(key, value) @wraps(receive) async def wrapped_receive(): with self.tracer.start_as_current_span( span_name + " asgi." + scope["type"] + ".receive") as receive_span: message = await receive() if receive_span.is_recording(): if message["type"] == "websocket.receive": set_status_code(receive_span, 200) receive_span.set_attribute("type", message["type"]) return message @wraps(send) async def wrapped_send(message): with self.tracer.start_as_current_span( span_name + " asgi." + scope["type"] + ".send") as send_span: if send_span.is_recording(): if message["type"] == "http.response.start": status_code = message["status"] set_status_code(send_span, status_code) elif message["type"] == "websocket.send": set_status_code(send_span, 200) send_span.set_attribute("type", message["type"]) await send(message) await self.app(scope, wrapped_receive, wrapped_send) finally: context.detach(token)
def server_request(): with tracer.start_as_current_span( "server_request", parent=propagators.extract(lambda dict_, key: dict_.get(key, []), request.headers)["current-span"], kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(request.environ), ): print(request.args.get("param")) return "served"
def server_request(): with tracer.start_as_current_span( "GET /backend", parent=propagators.extract( lambda request, key: request.headers.get_all(key), request)["current-span"], kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(request.environ), ) as foo: return "served"
def link_from_headers(cls, headers): # type: (Dict[str, str]) -> None """ Given a dictionary, extracts the context and links the context to the current tracer. :param headers: A key value pair dictionary :type headers: dict """ ctx = extract(_get_headers_from_http_request_headers, headers) current_span = cls.get_current_span() current_span.links.append(Link(ctx))
def link_from_headers(cls, headers, attributes=None): # type: (Dict[str, str], Attributes) -> None """ Given a dictionary, extracts the context and links the context to the current tracer. :param headers: A key value pair dictionary :type headers: dict """ ctx = extract(DictGetter(), headers) span_ctx = get_span_from_context(ctx).get_span_context() current_span = cls.get_current_span() current_span.links.append(Link(span_ctx, attributes))
def _set_remote_context(self, servicer_context): metadata = servicer_context.invocation_metadata() if metadata: md_dict = {md.key: md.value for md in metadata} ctx = propagators.extract(self._carrier_getter, md_dict) token = attach(ctx) try: yield finally: detach(token) else: yield
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) token = context.attach( propagators.extract(get_header_from_scope, scope) ) span_name, additional_attributes = self.span_details_callback(scope) attributes = collect_request_attributes(scope) attributes.update(additional_attributes) try: with self.tracer.start_as_current_span( span_name + " asgi", kind=trace.SpanKind.SERVER, attributes=attributes, ): @wraps(receive) async def wrapped_receive(): with self.tracer.start_as_current_span( span_name + " asgi." + scope["type"] + ".receive" ) as receive_span: message = await receive() if message["type"] == "websocket.receive": set_status_code(receive_span, 200) receive_span.set_attribute("type", message["type"]) return message @wraps(send) async def wrapped_send(message): with self.tracer.start_as_current_span( span_name + " asgi." + scope["type"] + ".send" ) as send_span: if message["type"] == "http.response.start": status_code = message["status"] set_status_code(send_span, status_code) elif message["type"] == "websocket.send": set_status_code(send_span, 200) send_span.set_attribute("type", message["type"]) await send(message) await self.app(scope, wrapped_receive, wrapped_send) finally: context.detach(token)
async def __call__(self, scope, receive, send): if scope["type"] not in ("http", "websocket"): return await self.app(scope, receive, send) if await self.is_filtered(scope): return await self.app(scope, receive, send) token = context.attach(propagators.extract(carrier_getter, scope)) span_name, additional_attributes = self.span_details_callback(scope) try: with self.tracer.start_as_current_span( span_name + " asgi", kind=trace.SpanKind.SERVER, ) as span: if span.is_recording(): attributes = collect_request_attributes(scope) attributes.update(additional_attributes) for key, value in attributes.items(): span.set_attribute(key, value) @wraps(receive) async def wrapped_receive(): with self.tracer.start_as_current_span( span_name + " asgi." + scope["type"] + ".receive") as receive_span: message = await receive() if receive_span.is_recording(): if message["type"] == "websocket.receive": set_status_code(receive_span, 200) receive_span.set_attribute("type", message["type"]) return message @wraps(send) async def wrapped_send(message): with self.tracer.start_as_current_span( span_name + " asgi." + scope["type"] + ".send") as send_span: if send_span.is_recording(): if message["type"] == "http.response.start": status_code = message["status"] set_status_code(send_span, status_code) set_status_code(span, status_code) elif message["type"] == "websocket.send": set_status_code(send_span, 200) set_status_code(span, 200) send_span.set_attribute("type", message["type"]) await send(message) await self.app(scope, wrapped_receive, wrapped_send) finally: context.detach(token)
async def _recv_request(event: RecvRequest) -> None: tracer = get_tracer(__name__) attach(extract(_metadata_getter, event.metadata)) span_ctx = tracer.start_as_current_span( event.method_name, kind=SpanKind.SERVER, attributes={ "component": "grpc", "grpc.method": event.method_name }, ) span_ctx.__enter__() _server_span_ctx.set(span_ctx)
def poll(self, *args, **kwargs): self._self_release_context() msg = self._self_instance.poll(*args, **kwargs) if msg: ctx = propagators.extract(get_from_messge, msg) self._self_span = trace.get_tracer(__name__).start_span( name="confluent_kafka.poll", kind=trace.SpanKind.CONSUMER, parent=trace.get_current_span(ctx), ) set_span_from_message(self._self_span, msg) msg = MessageProxy(msg) weakref.finalize(msg, self._self_release_context) return msg
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) token = context.attach( propagators.extract(otel_wsgi.carrier_getter, request_environ)) 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 = tracer.start_span( span_name, kind=trace.SpanKind.SERVER, start_time=start_time, ) if span.is_recording(): attributes = otel_wsgi.collect_request_attributes(request_environ) if request.matched_route: attributes["http.route"] = request.matched_route.pattern for key, value in attributes.items(): span.set_attribute(key, value) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() request_environ[_ENVIRON_ACTIVATION_KEY] = activation request_environ[_ENVIRON_SPAN_KEY] = span request_environ[_ENVIRON_TOKEN] = token
async def __call__(self, scope:dict, receive:Coroutine, send:Coroutine) -> Coroutine: """The ASGI application Args: scope: The connection scope, a dictionary that contains at least a type key specifying the protocol that is incoming. receive: an awaitable callable that will yield a new event dictionary when one is available send: an awaitable callable taking a single event dictionary as a positional argument that will return once the send has been completed or the connection has been closed """ parent_span = propagators.extract(get_header_from_scope, scope) span_name = self.name_callback(scope) with self.tracer.start_span( span_name + " (asgi_connection)", parent_span, kind=trace.SpanKind.SERVER, attributes=collect_request_attributes(scope) ): @wraps(receive) async def wrapped_receive(): with self.tracer.start_as_current_span( span_name + " (asgi.{type}.receive".format({"type":scope['type']}) ) as receive_span: payload = await receive() if payload['type'] == 'websocket.receive': set_status_code(receive_span, 200) receive_span.set_attribute('http.status_text',payload['type']) return payload @wraps(send) async def wrapped_send(payload): with self.tracer.start_as_current_span( span_name + " (asgi.{type}.end)".format({"type":scope['type']}) ) as send_span: t = payload['type'] if t =='http.response.start': status_code = payload['sattus'] set_status_code(send_span, status_code) elif t == "websocket.send": set_status_code(send_span, 200) send_span.set_attribute( "http.status_text", payload['text'] ) send_span.set_attribute("type", t) await send(payload) await self.app(scope, wrapped_receive, wrapped_send)
def _set_remote_context(self, servicer_context): metadata = servicer_context.invocation_metadata() if metadata: md_dict = {md.key: md.value for md in metadata} def get_from_grpc_metadata(metadata, key) -> List[str]: return [md_dict[key]] if key in md_dict else [] # Update the context with the traceparent from the RPC metadata. ctx = propagators.extract(get_from_grpc_metadata, metadata) token = attach(ctx) try: yield finally: detach(token) else: yield
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 # pylint:disable=W0212 request._otel_start_time = time() request_meta = request.META token = attach(extract(carrier_getter, request_meta)) tracer = get_tracer(__name__, __version__) span = tracer.start_span( self._get_span_name(request), kind=SpanKind.SERVER, start_time=request_meta.get( "opentelemetry-instrumentor-django.starttime_key" ), ) attributes = collect_request_attributes(request_meta) # pylint:disable=W0212 request._otel_labels = self._get_metric_labels_from_attributes( attributes ) if span.is_recording(): attributes = extract_attributes_from_object( request, self._traced_request_attrs, attributes ) for key, value in attributes.items(): span.set_attribute(key, value) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() request.META[self._environ_activation_key] = activation request.META[self._environ_span_key] = span request.META[self._environ_token] = token
async def __call__(self, scope, receive, send): parent_span = propagators.extract(get_header_from_scope, scope) span_name = get_default_span_name(scope) span = self.tracer.start_span( span_name, parent_span, kind=trace.SpanKind.SERVER, attributes={}#collect_request_attributes(scope), ) try: with self.tracer.use_span(span): await self.asgi(scope)(receive, send) span.end() except: # noqa # TODO Set span status (cf. https://github.com/open-telemetry/opentelemetry-python/issues/292) span.end() raise
def _trace_prerun(self, *args, **kwargs): task = utils.retrieve_task(kwargs) task_id = utils.retrieve_task_id(kwargs) if task is None or task_id is None: return request = task.request tracectx = propagators.extract(carrier_getter, request) or None logger.debug("prerun signal start task_id=%s", task_id) operation_name = "{0}/{1}".format(_TASK_RUN, task.name) span = self._tracer.start_span( operation_name, context=tracectx, kind=trace.SpanKind.CONSUMER ) activation = self._tracer.use_span(span, end_on_exit=True) activation.__enter__() utils.attach_span(task, task_id, (span, activation))
def __call__(self, env, start_response): if _excluded_urls.url_disabled(env.get("PATH_INFO", "/")): return super().__call__(env, start_response) start_time = time_ns() token = context.attach( propagators.extract(otel_wsgi.carrier_getter, env)) span = self._tracer.start_span( otel_wsgi.get_default_span_name(env), kind=trace.SpanKind.SERVER, start_time=start_time, ) if span.is_recording(): attributes = otel_wsgi.collect_request_attributes(env) for key, value in attributes.items(): span.set_attribute(key, value) activation = self._tracer.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): otel_wsgi.add_response_attributes(span, status, response_headers) response = start_response(status, response_headers, *args, **kwargs) activation.__exit__(None, None, 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), ) context.detach(token) raise
def _start_span(tracer, handler, start_time) -> _TraceContext: token = context.attach( propagators.extract( carrier_getter, handler.request.headers, )) span = tracer.start_span( _get_operation_name(handler, handler.request), kind=trace.SpanKind.SERVER, start_time=start_time, ) if span.is_recording(): attributes = _get_attributes_from_request(handler.request) for key, value in attributes.items(): span.set_attribute(key, value) activation = tracer.use_span(span, end_on_exit=True) activation.__enter__() ctx = _TraceContext(activation, span, token) setattr(handler, _HANDLER_CONTEXT_KEY, ctx) return ctx