def decorated_function( exchange: str, routing_key: str, body: bytes, properties: BasicProperties = None, mandatory: bool = False, ) -> Any: if not properties: properties = BasicProperties(headers={}) ctx = context.get_current() span = _get_span( tracer, channel, properties, span_kind=SpanKind.PRODUCER, task_name="(temporary)", ctx=ctx, operation=None, ) if not span: return original_function( exchange, routing_key, body, properties, mandatory ) with trace.use_span(span, end_on_exit=True): if span.is_recording(): propagate.inject(properties.headers) retval = original_function( exchange, routing_key, body, properties, mandatory ) return retval
def _instrumented_open_call(_, request, call_wrapped, get_or_create_headers): # pylint: disable=too-many-locals if context.get_value( _SUPPRESS_INSTRUMENTATION_KEY) or context.get_value( _SUPPRESS_HTTP_INSTRUMENTATION_KEY): return call_wrapped() method = request.get_method().upper() url = request.full_url span_name = f"HTTP {method}".strip() url = remove_url_credentials(url) labels = { SpanAttributes.HTTP_METHOD: method, SpanAttributes.HTTP_URL: url, } with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT, attributes=labels) as span: exception = None if callable(request_hook): request_hook(span, request) headers = get_or_create_headers() inject(headers) token = context.attach( context.set_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY, True)) try: result = call_wrapped() # *** PROCEED except Exception as exc: # pylint: disable=W0703 exception = exc result = getattr(exc, "file", None) finally: context.detach(token) if result is not None: code_ = result.getcode() labels[SpanAttributes.HTTP_STATUS_CODE] = str(code_) if span.is_recording(): span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, code_) span.set_status(Status(http_status_to_status_code(code_))) ver_ = str(getattr(result, "version", "")) if ver_: labels[ SpanAttributes.HTTP_FLAVOR] = f"{ver_[:1]}.{ver_[:-1]}" if callable(response_hook): response_hook(span, request, result) if exception is not None: raise exception.with_traceback(exception.__traceback__) return result
async def on_request_start( unused_session: aiohttp.ClientSession, trace_config_ctx: types.SimpleNamespace, params: aiohttp.TraceRequestStartParams, ): if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY): trace_config_ctx.span = None return http_method = params.method.upper() request_span_name = f"HTTP {http_method}" request_url = (remove_url_credentials( trace_config_ctx.url_filter(params.url)) if callable( trace_config_ctx.url_filter) else remove_url_credentials( str(params.url))) span_attributes = { SpanAttributes.HTTP_METHOD: http_method, SpanAttributes.HTTP_URL: request_url, } trace_config_ctx.span = trace_config_ctx.tracer.start_span( request_span_name, kind=SpanKind.CLIENT, attributes=span_attributes) if callable(request_hook): request_hook(trace_config_ctx.span, params) trace_config_ctx.token = context_api.attach( trace.set_span_in_context(trace_config_ctx.span)) inject(params.headers)
def intercept_stream(self, request_or_iterator, metadata, client_info, invoker): if client_info.is_server_stream: return self._intercept_server_stream(request_or_iterator, metadata, client_info, invoker) if not metadata: mutable_metadata = OrderedDict() else: mutable_metadata = OrderedDict(metadata) with self._start_guarded_span(client_info.full_method) as guarded_span: inject(mutable_metadata, setter=_carrier_setter) metadata = tuple(mutable_metadata.items()) rpc_info = RpcInfo( full_method=client_info.full_method, metadata=metadata, timeout=client_info.timeout, request=request_or_iterator, ) rpc_info.request = request_or_iterator try: result = invoker(request_or_iterator, metadata) except grpc.RpcError as err: guarded_span.generated_span.set_status(Status( StatusCode.ERROR)) guarded_span.generated_span.set_attribute( SpanAttributes.RPC_GRPC_STATUS_CODE, err.code().value[0], ) raise err return self._trace_result(guarded_span, rpc_info, result)
def instrumented_urlopen(wrapped, instance, args, kwargs): if _is_instrumentation_suppressed(): return wrapped(*args, **kwargs) method = _get_url_open_arg("method", args, kwargs).upper() url = _get_url(instance, args, kwargs, url_filter) headers = _prepare_headers(kwargs) body = _get_url_open_arg("body", args, kwargs) span_name = f"HTTP {method.strip()}" span_attributes = { SpanAttributes.HTTP_METHOD: method, SpanAttributes.HTTP_URL: url, } with tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes ) as span, set_ip_on_next_http_connection(span): if callable(request_hook): request_hook(span, instance, headers, body) inject(headers) with _suppress_further_instrumentation(): response = wrapped(*args, **kwargs) _apply_response(span, response) if callable(response_hook): response_hook(span, instance, response) return response
def _trace_before_publish(self, *args, **kwargs): task = utils.retrieve_task_from_sender(kwargs) task_id = utils.retrieve_task_id_from_message(kwargs) if task is None or task_id is None: return operation_name = f"{_TASK_APPLY_ASYNC}/{task.name}" span = self._tracer.start_span( operation_name, kind=trace.SpanKind.PRODUCER ) # apply some attributes here because most of the data is not available if span.is_recording(): span.set_attribute(_TASK_TAG_KEY, _TASK_APPLY_ASYNC) span.set_attribute(SpanAttributes.MESSAGING_MESSAGE_ID, task_id) span.set_attribute(_TASK_NAME_KEY, task.name) utils.set_attributes_from_context(span, kwargs) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 utils.attach_span(task, task_id, (span, activation), is_publish=True) headers = kwargs.get("headers") if headers: inject(headers)
def intercept_unary(self, request, metadata, client_info, invoker): if not metadata: mutable_metadata = OrderedDict() else: mutable_metadata = OrderedDict(metadata) with self._start_guarded_span(client_info.full_method) as guarded_span: inject(mutable_metadata, setter=_carrier_setter) metadata = tuple(mutable_metadata.items()) rpc_info = RpcInfo( full_method=client_info.full_method, metadata=metadata, timeout=client_info.timeout, request=request, ) try: result = invoker(request, metadata) except grpc.RpcError as err: guarded_span.generated_span.set_status(Status( StatusCode.ERROR)) guarded_span.generated_span.set_attribute( "rpc.grpc.status_code", err.code().value[0]) raise err return self._trace_result(guarded_span, rpc_info, result)
def before_enqueue(self, _broker, message, delay): retry_count = message.options.get("retries", 0) operation_name = utils.get_operation_name("before_enqueue", retry_count) span_attributes = {_REMOULADE_MESSAGE_RETRY_COUNT_KEY: retry_count} span = self._tracer.start_span( operation_name, kind=trace.SpanKind.PRODUCER, attributes=span_attributes, ) if span.is_recording(): span.set_attributes({ _REMOULADE_MESSAGE_TAG_KEY: _REMOULADE_MESSAGE_SEND, _REMOULADE_MESSAGE_NAME_KEY: message.actor_name, SpanAttributes.MESSAGING_MESSAGE_ID: message.message_id, }) activation = trace.use_span(span, end_on_exit=True) activation.__enter__() # pylint: disable=E1101 utils.attach_span( self._span_registry, message.message_id, (span, activation), is_publish=True, ) if "trace_ctx" not in message.options: message.options["trace_ctx"] = {} inject(message.options["trace_ctx"])
def decorated_function( exchange: str, routing_key: str, body: bytes, properties: BasicProperties = None, mandatory: bool = False, ) -> Any: if not properties: properties = BasicProperties(headers={}) if properties.headers is None: properties.headers = {} span = _get_span( tracer, channel, properties, destination=exchange if exchange else routing_key, span_kind=SpanKind.PRODUCER, task_name="(temporary)", operation=None, ) if not span: return original_function(exchange, routing_key, body, properties, mandatory) with trace.use_span(span, end_on_exit=True): if span.is_recording(): propagate.inject(properties.headers) try: publish_hook(span, body, properties) except Exception as hook_exception: # pylint: disable=W0703 _LOG.exception(hook_exception) retval = original_function(exchange, routing_key, body, properties, mandatory) return retval
def instrumented_urlopen(wrapped, instance, args, kwargs): if _is_instrumentation_suppressed(): return wrapped(*args, **kwargs) method = _get_url_open_arg("method", args, kwargs).upper() url = _get_url(instance, args, kwargs, url_filter) headers = _prepare_headers(kwargs) span_name = _get_span_name(span_name_or_callback, method, url, headers) span_attributes = { "http.method": method, "http.url": url, } with get_tracer(__name__, __version__, tracer_provider).start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes) as span: inject(headers) with _suppress_further_instrumentation(): response = wrapped(*args, **kwargs) _apply_response(span, response) return response
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 = { "baggage": ["key1=val1,key2=val2"], "traceparent": [traceparent_value], "tracestate": [tracestate_value], } ctx = extract(carrier_getter, headers) baggage_entries = baggage.get_all(context=ctx) expected = {"key1": "val1", "key2": "val2"} self.assertEqual(baggage_entries, expected) span_context = get_current_span(context=ctx).get_span_context() self.assertEqual(span_context.trace_id, self.TRACE_ID) self.assertEqual(span_context.span_id, self.SPAN_ID) span = trace.NonRecordingSpan(span_context) ctx = baggage.set_baggage("key3", "val3") ctx = baggage.set_baggage("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["baggage"]) self.assertIn("key4=val4", output["baggage"]) self.assertIn("foo=1", output["tracestate"]) self.assertIn("bar=2", output["tracestate"]) self.assertIn("baz=3", output["tracestate"])
def _traced_send(func, instance, args, kwargs): headers = KafkaPropertiesExtractor.extract_send_headers(args, kwargs) if headers is None: headers = [] kwargs["headers"] = headers topic = KafkaPropertiesExtractor.extract_send_topic(args) bootstrap_servers = KafkaPropertiesExtractor.extract_bootstrap_servers( instance) partition = KafkaPropertiesExtractor.extract_send_partition( instance, args, kwargs) span_name = _get_span_name("send", topic) with tracer.start_as_current_span( span_name, kind=trace.SpanKind.PRODUCER) as span: _enrich_span(span, bootstrap_servers, topic, partition) propagate.inject( headers, context=trace.set_span_in_context(span), setter=_kafka_setter, ) try: if callable(produce_hook): produce_hook(span, args, kwargs) except Exception as hook_exception: # pylint: disable=W0703 _LOG.exception(hook_exception) return func(*args, **kwargs)
def _intercept_server_stream(self, request_or_iterator, metadata, client_info, invoker): if not metadata: mutable_metadata = OrderedDict() else: mutable_metadata = OrderedDict(metadata) with self._start_span(client_info.full_method) as span: inject(mutable_metadata, setter=_carrier_setter) metadata = tuple(mutable_metadata.items()) rpc_info = RpcInfo( full_method=client_info.full_method, metadata=metadata, timeout=client_info.timeout, ) if client_info.is_client_stream: rpc_info.request = request_or_iterator try: yield from invoker(request_or_iterator, metadata) except grpc.RpcError as err: span.set_status(Status(StatusCode.ERROR)) span.set_attribute(SpanAttributes.RPC_GRPC_STATUS_CODE, err.code().value[0]) raise err
def wrap_produce(func, instance, tracer, args, kwargs): topic = kwargs.get("topic") if not topic: topic = args[0] span_name = _get_span_name("send", topic) with tracer.start_as_current_span( name=span_name, kind=trace.SpanKind.PRODUCER ) as span: headers = KafkaPropertiesExtractor.extract_produce_headers( args, kwargs ) if headers is None: headers = [] kwargs["headers"] = headers topic = KafkaPropertiesExtractor.extract_produce_topic(args) _enrich_span( span, topic, operation=MessagingOperationValues.RECEIVE, ) # Replace propagate.inject( headers, setter=_kafka_setter, ) return func(*args, **kwargs)
def fetch_async(tracer, func, _, args, kwargs): start_time = time_ns() # Return immediately if no args were provided (error) # or original_request is set (meaning we are in a redirect step). if len(args) == 0 or hasattr(args[0], "original_request"): return func(*args, **kwargs) # Force the creation of a HTTPRequest object if needed, # so we can inject the context into the headers. args, kwargs = _normalize_request(args, kwargs) request = args[0] span = tracer.start_span( request.method, kind=trace.SpanKind.CLIENT, start_time=start_time, ) if span.is_recording(): attributes = { "http.url": request.url, "http.method": request.method, } for key, value in attributes.items(): span.set_attribute(key, value) with tracer.use_span(span): inject(type(request.headers).__setitem__, request.headers) future = func(*args, **kwargs) future.add_done_callback( functools.partial(_finish_tracing_callback, span=span)) return future
def _instrumented_requests_call(method: str, url: str, call_wrapped, get_or_create_headers): if context.get_value("suppress_instrumentation") or context.get_value( _SUPPRESS_REQUESTS_INSTRUMENTATION_KEY): return call_wrapped() # See # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-client method = method.upper() span_name = "" if name_callback is not None: span_name = name_callback(method, url) if not span_name or not isinstance(span_name, str): span_name = get_default_span_name(method) labels = {} labels["http.method"] = method labels["http.url"] = url with get_tracer(__name__, __version__, tracer_provider).start_as_current_span( span_name, kind=SpanKind.CLIENT) as span: exception = None if span.is_recording(): span.set_attribute("http.method", method) span.set_attribute("http.url", url) headers = get_or_create_headers() inject(type(headers).__setitem__, headers) token = context.attach( context.set_value(_SUPPRESS_REQUESTS_INSTRUMENTATION_KEY, True)) try: result = call_wrapped() # *** PROCEED except Exception as exc: # pylint: disable=W0703 exception = exc result = getattr(exc, "response", None) finally: context.detach(token) if isinstance(result, Response): if span.is_recording(): span.set_attribute("http.status_code", result.status_code) span.set_attribute("http.status_text", result.reason) span.set_status( Status(http_status_to_status_code(result.status_code))) labels["http.status_code"] = str(result.status_code) if result.raw and result.raw.version: labels["http.flavor"] = (str(result.raw.version)[:1] + "." + str(result.raw.version)[:-1]) if span_callback is not None: span_callback(span, result) if exception is not None: raise exception.with_traceback(exception.__traceback__) return result
def _inject_propagation_headers(headers, args, kwargs): _headers = _prepare_headers(headers) inject(_headers) if isinstance(args[0], httpx.Request): request: httpx.Request = args[0] request.headers = _headers else: kwargs["headers"] = _headers.raw
def _inject_span_context(metadata: MutableMapping[str, str]) -> None: # pylint:disable=unused-argument def append_metadata(carrier: MutableMapping[str, str], key: str, value: str): metadata[key] = value # Inject current active span from the context inject(append_metadata, metadata)
def to_header(self): # pylint: disable=no-self-use # type: () -> Dict[str, str] """ Returns a dictionary with the header labels and values. :return: A key value pair dictionary """ temp_headers = {} # type: Dict[str, str] inject(temp_headers) return temp_headers
def _instrumented_requests_call( method: str, url: str, call_wrapped, get_or_create_headers ): if context.get_value( _SUPPRESS_INSTRUMENTATION_KEY ) or context.get_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY): return call_wrapped() # See # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-client method = method.upper() span_name = "" if name_callback is not None: span_name = name_callback(method, url) if not span_name or not isinstance(span_name, str): span_name = get_default_span_name(method) url = remove_url_credentials(url) with tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT ) as span: exception = None if span.is_recording(): span.set_attribute(SpanAttributes.HTTP_METHOD, method) span.set_attribute(SpanAttributes.HTTP_URL, url) headers = get_or_create_headers() inject(headers) token = context.attach( context.set_value(_SUPPRESS_HTTP_INSTRUMENTATION_KEY, True) ) try: result = call_wrapped() # *** PROCEED except Exception as exc: # pylint: disable=W0703 exception = exc result = getattr(exc, "response", None) finally: context.detach(token) if isinstance(result, Response): if span.is_recording(): span.set_attribute( SpanAttributes.HTTP_STATUS_CODE, result.status_code ) span.set_status( Status(http_status_to_status_code(result.status_code)) ) if span_callback is not None: span_callback(span, result) if exception is not None: raise exception.with_traceback(exception.__traceback__) return result
async def handle_async_request( self, method: bytes, url: URL, headers: typing.Optional[Headers] = None, stream: typing.Optional[httpx.AsyncByteStream] = None, extensions: typing.Optional[dict] = None, ) -> typing.Tuple[int, "Headers", httpx.AsyncByteStream, dict]: """Add request info to span.""" if context.get_value("suppress_instrumentation"): return await self._transport.handle_async_request( method, url, headers=headers, stream=stream, extensions=extensions, ) span_attributes = _prepare_attributes(method, url) _headers = _prepare_headers(headers) span_name = _get_default_span_name( span_attributes[SpanAttributes.HTTP_METHOD] ) request = RequestInfo(method, url, headers, stream, extensions) with self._tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes ) as span: if self._request_hook is not None: await self._request_hook(span, request) inject(_headers) ( status_code, headers, stream, extensions, ) = await self._transport.handle_async_request( method, url, headers=_headers.raw, stream=stream, extensions=extensions, ) _apply_status_code(span, status_code) if self._response_hook is not None: await self._response_hook( span, request, ResponseInfo(status_code, headers, stream, extensions), ) return status_code, headers, stream, extensions
def _patch_lambda_invoke(api_params): try: payload_str = api_params["Payload"] payload = json.loads(payload_str) headers = payload.get("headers", {}) inject(headers) payload["headers"] = headers api_params["Payload"] = json.dumps(payload) except ValueError: pass
async def decorated_publish( message: AbstractMessage, routing_key: str, **kwargs) -> Optional[aiormq.abc.ConfirmationFrameType]: span = self._get_publish_span(message, routing_key) if not span: return await publish(message, routing_key, **kwargs) with trace.use_span(span, end_on_exit=True): if span.is_recording(): propagate.inject(message.properties.headers) return_value = await publish(message, routing_key, **kwargs) return return_value
def _inject_current_span(cls, call_context: _AwsSdkCallContext): payload_str = call_context.params.get("Payload") if payload_str is None: return # TODO: reconsider propagation via payload as it manipulates input of the called lambda function try: payload = json.loads(payload_str) headers = payload.get("headers", {}) inject(headers) payload["headers"] = headers call_context.params["Payload"] = json.dumps(payload) except ValueError: pass
def _intercept(self, request, metadata, client_info, invoker): if context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): return invoker(request, metadata) if not metadata: mutable_metadata = OrderedDict() else: mutable_metadata = OrderedDict(metadata) with self._start_span( client_info.full_method, end_on_exit=False, record_exception=False, set_status_on_exception=False, ) as span: result = None try: inject(mutable_metadata, setter=_carrier_setter) metadata = tuple(mutable_metadata.items()) rpc_info = RpcInfo( full_method=client_info.full_method, metadata=metadata, timeout=client_info.timeout, request=request, ) result = invoker(request, metadata) except Exception as exc: if isinstance(exc, grpc.RpcError): span.set_attribute( SpanAttributes.RPC_GRPC_STATUS_CODE, exc.code().value[0], ) span.set_status( Status( status_code=StatusCode.ERROR, description=f"{type(exc).__name__}: {exc}", )) span.record_exception(exc) raise exc finally: if not result: span.end() return self._trace_result(span, rpc_info, result)
def instrumented_urlopen(wrapped, instance, args, kwargs): if _is_instrumentation_suppressed(): return wrapped(*args, **kwargs) method = _get_url_open_arg("method", args, kwargs).upper() url = _get_url(instance, args, kwargs, url_filter) headers = _prepare_headers(kwargs) body = _get_url_open_arg("body", args, kwargs) span_name = f"HTTP {method.strip()}" span_attributes = { SpanAttributes.HTTP_METHOD: method, SpanAttributes.HTTP_URL: url, } with tracer.start_as_current_span( span_name, kind=SpanKind.CLIENT, attributes=span_attributes ) as span, set_ip_on_next_http_connection(span): if callable(request_hook): request_hook(span, instance, headers, body) inject(headers) with _suppress_further_instrumentation(): start_time = default_timer() response = wrapped(*args, **kwargs) elapsed_time = round((default_timer() - start_time) * 1000) _apply_response(span, response) if callable(response_hook): response_hook(span, instance, response) request_size = 0 if body is None else len(body) response_size = int(response.headers.get("Content-Length", 0)) metric_attributes = _create_metric_attributes( instance, response, method) duration_histogram.record(elapsed_time, attributes=metric_attributes) request_size_histogram.record(request_size, attributes=metric_attributes) response_size_histogram.record(response_size, attributes=metric_attributes) return response
def send_batch_wrapper(wrapped, instance, args, kwargs): queue_url = kwargs.get("QueueUrl") entries = kwargs.get("Entries") # The method expect QueueUrl and Entries params, so if they are None, we call wrapped to receive the # original exception if (context.get_value(_SUPPRESS_INSTRUMENTATION_KEY) or not queue_url or not entries): return wrapped(*args, **kwargs) queue_name = Boto3SQSInstrumentor._extract_queue_name_from_url( queue_url) ids_to_spans: Dict[str, Span] = {} for entry in entries: entry_id = entry["Id"] span = self._tracer.start_span(name=f"{queue_name} send", kind=SpanKind.PRODUCER) ids_to_spans[entry_id] = span Boto3SQSInstrumentor._enrich_span(span, queue_name, queue_url, conversation_id=entry_id) with trace.use_span(span): if "MessageAttributes" not in entry: entry["MessageAttributes"] = {} propagate.inject(entry["MessageAttributes"], setter=boto3sqs_setter) retval = wrapped(*args, **kwargs) for successful_messages in retval["Successful"]: message_identifier = successful_messages["Id"] message_span = ids_to_spans.get(message_identifier) if message_span: if message_span.is_recording(): message_span.set_attribute( SpanAttributes.MESSAGING_MESSAGE_ID, successful_messages.get("MessageId"), ) for span in ids_to_spans.values(): span.end() return retval
async def on_request_start( unused_session: aiohttp.ClientSession, trace_config_ctx: types.SimpleNamespace, params: aiohttp.TraceRequestStartParams, ): if context_api.get_value(_SUPPRESS_INSTRUMENTATION_KEY): trace_config_ctx.span = None return http_method = params.method.upper() if trace_config_ctx.span_name is None: request_span_name = "HTTP {}".format(http_method) elif callable(trace_config_ctx.span_name): request_span_name = str(trace_config_ctx.span_name(params)) else: request_span_name = str(trace_config_ctx.span_name) trace_config_ctx.span = trace_config_ctx.tracer.start_span( request_span_name, kind=SpanKind.CLIENT, ) if trace_config_ctx.span.is_recording(): attributes = { SpanAttributes.HTTP_METHOD: http_method, SpanAttributes.HTTP_URL: remove_url_credentials(trace_config_ctx.url_filter(params.url)) if callable(trace_config_ctx.url_filter) else remove_url_credentials(str(params.url)), } for key, value in attributes.items(): trace_config_ctx.span.set_attribute(key, value) trace_config_ctx.token = context_api.attach( trace.set_span_in_context(trace_config_ctx.span)) inject(params.headers)
def send_wrapper(wrapped, instance, args, kwargs): if context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): return wrapped(*args, **kwargs) queue_url = kwargs.get("QueueUrl") # The method expect QueueUrl and Entries params, so if they are None, we call wrapped to receive the # original exception queue_name = Boto3SQSInstrumentor._extract_queue_name_from_url( queue_url) with self._tracer.start_as_current_span( name=f"{queue_name} send", kind=SpanKind.PRODUCER, end_on_exit=True, ) as span: Boto3SQSInstrumentor._enrich_span(span, queue_name, queue_url) attributes = kwargs.pop("MessageAttributes", {}) propagate.inject(attributes, setter=boto3sqs_setter) retval = wrapped(*args, MessageAttributes=attributes, **kwargs) message_id = retval.get("MessageId") if message_id: if span.is_recording(): span.set_attribute(SpanAttributes.MESSAGING_MESSAGE_ID, message_id) return retval
async def on_request_start( unused_session: aiohttp.ClientSession, trace_config_ctx: types.SimpleNamespace, params: aiohttp.TraceRequestStartParams, ): if context_api.get_value("suppress_instrumentation"): trace_config_ctx.span = None return http_method = params.method.upper() if trace_config_ctx.span_name is None: request_span_name = "HTTP {}".format(http_method) elif callable(trace_config_ctx.span_name): request_span_name = str(trace_config_ctx.span_name(params)) else: request_span_name = str(trace_config_ctx.span_name) trace_config_ctx.span = trace_config_ctx.tracer.start_span( request_span_name, kind=SpanKind.CLIENT, ) if trace_config_ctx.span.is_recording(): attributes = { "http.method": http_method, "http.url": trace_config_ctx.url_filter(params.url) if callable(trace_config_ctx.url_filter) else str(params.url), } for key, value in attributes.items(): trace_config_ctx.span.set_attribute(key, value) trace_config_ctx.token = context_api.attach( trace.set_span_in_context(trace_config_ctx.span)) inject(type(params.headers).__setitem__, params.headers)