def extract( self, getter: textmap.Getter[textmap.TextMapPropagatorT], carrier: textmap.TextMapPropagatorT, context: typing.Optional[Context] = None, ) -> Context: header = self._get_header_value(getter, carrier) if not header: return trace.set_span_in_context(trace.INVALID_SPAN, context) match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header) if match is None: return trace.set_span_in_context(trace.INVALID_SPAN, context) trace_id = match.group("trace_id") span_id = match.group("span_id") trace_options = match.group("trace_flags") if trace_id == "0" * 32 or int(span_id) == 0: return trace.set_span_in_context(trace.INVALID_SPAN, context) span_context = SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id), is_remote=True, trace_flags=TraceFlags(trace_options), ) return trace.set_span_in_context( trace.DefaultSpan(span_context), context )
def extract( self, get_from_carrier: httptextformat.Getter[ httptextformat.HTTPTextFormatT], carrier: httptextformat.HTTPTextFormatT, context: typing.Optional[Context] = None, ) -> Context: header = get_from_carrier(carrier, _TRACE_CONTEXT_HEADER_NAME) if not header: return trace.set_span_in_context(trace.INVALID_SPAN, context) match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header[0]) if match is None: return trace.set_span_in_context(trace.INVALID_SPAN, context) trace_id = match.group("trace_id") span_id = match.group("span_id") trace_options = match.group("trace_flags") if trace_id == "0" * 32 or int(span_id) == 0: return trace.set_span_in_context(trace.INVALID_SPAN, context) span_context = SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id), is_remote=True, trace_flags=TraceFlags(trace_options), ) return trace.set_span_in_context(trace.DefaultSpan(span_context), context)
def extract( self, getter: Getter[TextMapPropagatorT], carrier: TextMapPropagatorT, context: typing.Optional[Context] = None, ) -> Context: if context is None: context = get_current() header = getter.get(carrier, self.TRACE_ID_KEY) if not header: return trace.set_span_in_context(trace.INVALID_SPAN, context) fields = _extract_first_element(header).split(":") context = self._extract_baggage(getter, carrier, context) if len(fields) != 4: return trace.set_span_in_context(trace.INVALID_SPAN, context) trace_id, span_id, _parent_id, flags = fields if (trace_id == trace.INVALID_TRACE_ID or span_id == trace.INVALID_SPAN_ID): return trace.set_span_in_context(trace.INVALID_SPAN, context) span = trace.DefaultSpan( trace.SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id, 16), is_remote=True, trace_flags=trace.TraceFlags( int(flags, 16) & trace.TraceFlags.SAMPLED), )) return trace.set_span_in_context(span, context)
def extract( self, get_from_carrier: Getter[HTTPTextFormatT], carrier: HTTPTextFormatT, context: typing.Optional[Context] = None, ) -> Context: trace_id = format_trace_id(trace.INVALID_TRACE_ID) span_id = format_span_id(trace.INVALID_SPAN_ID) sampled = "0" flags = None single_header = _extract_first_element( get_from_carrier(carrier, self.SINGLE_HEADER_KEY)) if single_header: # The b3 spec calls for the sampling state to be # "deferred", which is unspecified. This concept does not # translate to SpanContext, so we set it as recorded. sampled = "1" fields = single_header.split("-", 4) if len(fields) == 1: sampled = fields[0] elif len(fields) == 2: trace_id, span_id = fields elif len(fields) == 3: trace_id, span_id, sampled = fields elif len(fields) == 4: trace_id, span_id, sampled, _ = fields else: return trace.set_span_in_context(trace.INVALID_SPAN) else: trace_id = (_extract_first_element( get_from_carrier(carrier, self.TRACE_ID_KEY)) or trace_id) span_id = (_extract_first_element( get_from_carrier(carrier, self.SPAN_ID_KEY)) or span_id) sampled = (_extract_first_element( get_from_carrier(carrier, self.SAMPLED_KEY)) or sampled) flags = (_extract_first_element( get_from_carrier(carrier, self.FLAGS_KEY)) or flags) options = 0 # The b3 spec provides no defined behavior for both sample and # flag values set. Since the setting of at least one implies # the desire for some form of sampling, propagate if either # header is set to allow. if sampled in self._SAMPLE_PROPAGATE_VALUES or flags == "1": options |= trace.TraceFlags.SAMPLED return trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( # trace an span ids are encoded in hex, so must be converted trace_id=int(trace_id, 16), span_id=int(span_id, 16), is_remote=True, trace_flags=trace.TraceFlags(options), trace_state=trace.TraceState(), )))
def extract( self, getter: Getter[TextMapPropagatorT], carrier: TextMapPropagatorT, context: typing.Optional[Context] = None, ) -> Context: trace_header_list = getter.get(carrier, TRACE_HEADER_KEY) if not trace_header_list or len(trace_header_list) != 1: return trace.set_span_in_context( trace.INVALID_SPAN, context=context ) trace_header = trace_header_list[0] if not trace_header: return trace.set_span_in_context( trace.INVALID_SPAN, context=context ) try: ( trace_id, span_id, sampled, ) = AwsXRayFormat._extract_span_properties(trace_header) except AwsParseTraceHeaderError as err: _logger.debug(err.message) return trace.set_span_in_context( trace.INVALID_SPAN, context=context ) options = 0 if sampled: options |= trace.TraceFlags.SAMPLED span_context = trace.SpanContext( trace_id=trace_id, span_id=span_id, is_remote=True, trace_flags=trace.TraceFlags(options), trace_state=trace.TraceState(), ) if not span_context.is_valid: _logger.debug( "Invalid Span Extracted. Insertting INVALID span into provided context." ) return trace.set_span_in_context( trace.INVALID_SPAN, context=context ) return trace.set_span_in_context( trace.DefaultSpan(span_context), context=context )
def get_context_new_carrier(old_carrier, carrier_baggage=None): ctx = FORMAT.extract(carrier_getter, old_carrier) if carrier_baggage: for key, value in carrier_baggage.items(): ctx = baggage.set_baggage(key, value, ctx) parent_span_context = trace_api.get_current_span(ctx).get_span_context() parent = trace._Span("parent", parent_span_context) child = trace._Span( "child", trace_api.SpanContext( parent_span_context.trace_id, id_generator.RandomIdGenerator().generate_span_id(), is_remote=False, trace_flags=parent_span_context.trace_flags, trace_state=parent_span_context.trace_state, ), parent=parent.get_span_context(), ) new_carrier = {} ctx = trace_api.set_span_in_context(child, ctx) FORMAT.inject(dict.__setitem__, new_carrier, context=ctx) return ctx, new_carrier
def test_inject_invalid_baggage_values(self): """Test that invalid baggage values are not set""" carrier = {} self.ot_trace_propagator.inject( carrier, set_baggage( "key", "α", context=set_span_in_context( _Span( "child", SpanContext( trace_id=int("80f198ee56343ba864fe8b2a57d3eff7", 16), span_id=int("e457b5a2e4d86bd1", 16), is_remote=True, trace_flags=TraceFlags.SAMPLED, ), )), ), ) self.assertNotIn("".join([OT_BAGGAGE_PREFIX, "key"]), carrier.keys())
def test_inject_set_baggage(self): """Test that baggage is set""" carrier = {} self.ot_trace_propagator.inject( carrier, set_baggage( "key", "value", context=set_span_in_context( _Span( "child", SpanContext( trace_id=int("80f198ee56343ba864fe8b2a57d3eff7", 16), span_id=int("e457b5a2e4d86bd1", 16), is_remote=True, trace_flags=TraceFlags.SAMPLED, ), )), ), ) self.assertEqual(carrier["".join([OT_BAGGAGE_PREFIX, "key"])], "value")
def on_validation_start(self): ctx = trace.set_span_in_context( self._span_holder[RequestStage.REQUEST]) self._span_holder[RequestStage.VALIDATION] = self._tracer.start_span( "GraphQL Validation", context=ctx, )
async def on_request_start( unused_session: aiohttp.ClientSession, trace_config_ctx: types.SimpleNamespace, params: aiohttp.TraceRequestStartParams, ): 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 = { "component": "http", "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)) propagators.inject(type(params.headers).__setitem__, params.headers)
def extract( self, carrier: textmap.CarrierT, context: typing.Optional[Context] = None, getter: textmap.Getter = textmap.default_getter, ) -> Context: if context is None: context = Context() header = self._get_header_value(getter, carrier) if not header: return context match = re.fullmatch(_TRACE_CONTEXT_HEADER_RE, header) if match is None: return context trace_id = match.group("trace_id") span_id = match.group("span_id") trace_options = match.group("trace_flags") if trace_id == "0" * 32 or int(span_id) == 0: return context span_context = SpanContext( trace_id=int(trace_id, 16), span_id=int(span_id), is_remote=True, trace_flags=TraceFlags(trace_options), ) return trace.set_span_in_context(trace.NonRecordingSpan(span_context), context)
def extract( self, carrier: CarrierT, context: typing.Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() header = getter.get(carrier, self.TRACE_ID_KEY) if not header: return context context = self._extract_baggage(getter, carrier, context) trace_id, span_id, flags = _parse_trace_id_header(header) if (trace_id == trace.INVALID_TRACE_ID or span_id == trace.INVALID_SPAN_ID): return context span = trace.NonRecordingSpan( trace.SpanContext( trace_id=trace_id, span_id=span_id, is_remote=True, trace_flags=trace.TraceFlags(flags & trace.TraceFlags.SAMPLED), )) return trace.set_span_in_context(span, context)
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_current_span(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"])
async def otel_send(message): with self.tracer.start_as_current_span(" ".join( (server_span_name, scope["type"], "send"))) as send_span: if callable(self.client_response_hook): self.client_response_hook(send_span, message) if send_span.is_recording(): if message["type"] == "http.response.start": status_code = message["status"] set_status_code(server_span, status_code) set_status_code(send_span, status_code) elif message["type"] == "websocket.send": set_status_code(server_span, 200) set_status_code(send_span, 200) send_span.set_attribute("type", message["type"]) propagator = get_global_response_propagator() if propagator: propagator.inject( message, context=set_span_in_context( server_span, trace.context_api.Context()), setter=asgi_setter, ) await send(message)
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 inject(self, span_context, format: object, carrier: object): """Injects ``span_context`` into ``carrier``. See base class for more details. Args: span_context: The ``opentracing.SpanContext`` to inject. format: a Python object instance that represents a given carrier format. `format` may be of any type, and `format` equality is defined by Python ``==`` operator. carrier: the format-specific carrier object to inject into """ # pylint: disable=redefined-builtin # This implementation does not perform the injecting by itself but # uses the configured propagators in opentelemetry.propagators. # TODO: Support Format.BINARY once it is supported in # opentelemetry-python. if format not in self._supported_formats: raise UnsupportedFormatException propagator = propagators.get_global_textmap() ctx = set_span_in_context(DefaultSpan(span_context.unwrap())) propagator.inject(type(carrier).__setitem__, carrier, context=ctx)
def test_sampling_priority_auto_reject(self): """Test sampling priority rejected.""" parent_span_context = get_current_span( FORMAT.extract( { FORMAT.TRACE_ID_KEY: self.serialized_trace_id, FORMAT.PARENT_ID_KEY: self.serialized_parent_id, FORMAT.SAMPLING_PRIORITY_KEY: str(constants.AUTO_REJECT), }, )).get_span_context() self.assertEqual(parent_span_context.trace_flags, constants.AUTO_REJECT) child = trace._Span( "child", trace_api.SpanContext( parent_span_context.trace_id, RandomIdGenerator().generate_span_id(), is_remote=False, trace_flags=parent_span_context.trace_flags, trace_state=parent_span_context.trace_state, ), parent=parent_span_context, ) child_carrier = {} child_context = set_span_in_context(child) FORMAT.inject(child_carrier, context=child_context) self.assertEqual( child_carrier[FORMAT.SAMPLING_PRIORITY_KEY], str(constants.AUTO_REJECT), )
def test_headers_with_tracestate(self): """When there is a traceparent and tracestate header, data from both should be addded to the SpanContext. """ 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" span_context = trace.get_current_span( FORMAT.extract( { "traceparent": [traceparent_value], "tracestate": [tracestate_value], }, ) ).get_span_context() self.assertEqual(span_context.trace_id, self.TRACE_ID) self.assertEqual(span_context.span_id, self.SPAN_ID) self.assertEqual( span_context.trace_state, {"foo": "1", "bar": "2", "baz": "3"} ) self.assertTrue(span_context.is_remote) output = {} # type:typing.Dict[str, str] span = trace.NonRecordingSpan(span_context) ctx = trace.set_span_in_context(span) FORMAT.inject(output, context=ctx) self.assertEqual(output["traceparent"], traceparent_value) for pair in ["foo=1", "bar=2", "baz=3"]: self.assertIn(pair, output["tracestate"]) self.assertEqual(output["tracestate"].count(","), 2)
def test_start_span_explicit(self): tracer = new_tracer() other_parent = trace._Span( "name", trace_api.SpanContext( trace_id=0x000000000000000000000000DEADBEEF, span_id=0x00000000DEADBEF0, is_remote=False, trace_flags=trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED), ), ) other_parent_context = trace_api.set_span_in_context(other_parent) self.assertEqual(trace_api.get_current_span(), trace_api.INVALID_SPAN) root = tracer.start_span("root") self.assertIsNotNone(root.start_time) self.assertIsNone(root.end_time) # Test with the implicit root span with tracer.use_span(root, True): self.assertIs(trace_api.get_current_span(), root) with tracer.start_span("stepchild", other_parent_context) as child: # The child's parent should be the one passed in, # not the current span. self.assertNotEqual(child.parent, root) self.assertIs(child.parent, other_parent.get_span_context()) self.assertIsNotNone(child.start_time) self.assertIsNone(child.end_time) # The child should inherit its context from the explicit # parent, not the current span. child_context = child.get_span_context() self.assertEqual( other_parent.get_span_context().trace_id, child_context.trace_id, ) self.assertNotEqual( other_parent.get_span_context().span_id, child_context.span_id, ) self.assertEqual( other_parent.get_span_context().trace_state, child_context.trace_state, ) self.assertEqual( other_parent.get_span_context().trace_flags, child_context.trace_flags, ) # Verify start_span() did not set the current span. self.assertIs(trace_api.get_current_span(), root) # Verify ending the child did not set the current span. self.assertIs(trace_api.get_current_span(), root) self.assertIsNotNone(child.end_time)
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 test_parent_based(self): sampler = sampling.ParentBased(sampling.ALWAYS_ON) context = trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( 0xDEADBEF0, 0xDEADBEF1, is_remote=False, trace_flags=TO_DEFAULT, ))) # Check that the sampling decision matches the parent context if given self.assertFalse( sampler.should_sample( context, 0x7FFFFFFFFFFFFFFF, 0xDEADBEEF, "span name", ).decision.is_sampled()) context = trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( 0xDEADBEF0, 0xDEADBEF1, is_remote=False, trace_flags=TO_SAMPLED, ))) sampler2 = sampling.ParentBased(sampling.ALWAYS_OFF) self.assertTrue( sampler2.should_sample( context, 0x8000000000000000, 0xDEADBEEF, "span name", ).decision.is_sampled()) # root span always sampled for parentbased context = trace.set_span_in_context(trace.INVALID_SPAN) sampler3 = sampling.ParentBased(sampling.ALWAYS_OFF) self.assertTrue( sampler3.should_sample( context, 0x8000000000000000, 0xDEADBEEF, "span name", ).decision.is_sampled())
def _inject(self, span=None): """Test helper""" ctx = get_current() if span is not None: ctx = trace.set_span_in_context(span, ctx) output = {} self.propagator.inject(dict.__setitem__, output, context=ctx) return output.get(_TRACE_CONTEXT_HEADER_NAME)
def _create_parent( self, trace_flags: trace.TraceFlags, is_remote=False ) -> typing.Optional[context_api.Context]: if trace_flags is None: return None return trace.set_span_in_context( self._create_parent_span(trace_flags, is_remote) )
def extract( self, carrier: CarrierT, context: Optional[Context] = None, getter: Getter = default_getter, ) -> Context: if context is None: context = Context() traceid = _extract_identifier( getter.get(carrier, OT_TRACE_ID_HEADER), _valid_extract_traceid, INVALID_TRACE_ID, ) spanid = _extract_identifier( getter.get(carrier, OT_SPAN_ID_HEADER), _valid_extract_spanid, INVALID_SPAN_ID, ) sampled = _extract_first_element( getter.get(carrier, OT_SAMPLED_HEADER) ) if sampled == "true": traceflags = TraceFlags.SAMPLED else: traceflags = TraceFlags.DEFAULT if traceid != INVALID_TRACE_ID and spanid != INVALID_SPAN_ID: context = set_span_in_context( NonRecordingSpan( SpanContext( trace_id=traceid, span_id=spanid, is_remote=True, trace_flags=TraceFlags(traceflags), ) ), context, ) baggage = get_all(context) or {} for key in getter.keys(carrier): if not key.startswith(OT_BAGGAGE_PREFIX): continue baggage[ key[len(OT_BAGGAGE_PREFIX) :] ] = _extract_first_element(getter.get(carrier, key)) for key, value in baggage.items(): context = set_baggage(key, value, context) return context
def test_default_on(self): context = trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( 0xDEADBEEF, 0xDEADBEF0, is_remote=False, trace_flags=TO_DEFAULT, ))) no_record_default_on = sampling.DEFAULT_ON.should_sample( context, 0xDEADBEF1, 0xDEADBEF2, "unsampled parent, sampling on", ) self.assertFalse(no_record_default_on.decision.is_sampled()) self.assertEqual(no_record_default_on.attributes, {}) context = trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( 0xDEADBEEF, 0xDEADBEF0, is_remote=False, trace_flags=TO_SAMPLED, ))) sampled_default_on = sampling.DEFAULT_ON.should_sample( context, 0xDEADBEF1, 0xDEADBEF2, {"sampled parent": "sampling on"}, ) self.assertTrue(sampled_default_on.decision.is_sampled()) self.assertEqual(sampled_default_on.attributes, {"sampled parent": "sampling on"}) default_on = sampling.DEFAULT_ON.should_sample( None, 0xDEADBEF1, 0xDEADBEF2, {"sampled parent": "sampling on"}, ) self.assertTrue(default_on.decision.is_sampled()) self.assertEqual(default_on.attributes, {"sampled parent": "sampling on"})
def test_context_propagation(self): """Test the propagation of Datadog headers.""" parent_span_context = get_current_span( FORMAT.extract( carrier_getter, { FORMAT.TRACE_ID_KEY: self.serialized_trace_id, FORMAT.PARENT_ID_KEY: self.serialized_parent_id, FORMAT.SAMPLING_PRIORITY_KEY: str(constants.AUTO_KEEP), FORMAT.ORIGIN_KEY: self.serialized_origin, }, ) ).get_span_context() self.assertEqual( parent_span_context.trace_id, int(self.serialized_trace_id) ) self.assertEqual( parent_span_context.span_id, int(self.serialized_parent_id) ) self.assertEqual(parent_span_context.trace_flags, constants.AUTO_KEEP) self.assertEqual( parent_span_context.trace_state.get(constants.DD_ORIGIN), self.serialized_origin, ) self.assertTrue(parent_span_context.is_remote) child = trace._Span( "child", trace_api.SpanContext( parent_span_context.trace_id, trace_api.RandomIdsGenerator().generate_span_id(), is_remote=False, trace_flags=parent_span_context.trace_flags, trace_state=parent_span_context.trace_state, ), parent=parent_span_context, ) child_carrier = {} child_context = set_span_in_context(child) FORMAT.inject(dict.__setitem__, child_carrier, context=child_context) self.assertEqual( child_carrier[FORMAT.TRACE_ID_KEY], self.serialized_trace_id ) self.assertEqual( child_carrier[FORMAT.PARENT_ID_KEY], str(child.context.span_id) ) self.assertEqual( child_carrier[FORMAT.SAMPLING_PRIORITY_KEY], str(constants.AUTO_KEEP), ) self.assertEqual( child_carrier.get(FORMAT.ORIGIN_KEY), self.serialized_origin )
def extract( self, get_from_carrier: Getter[HTTPTextFormatT], carrier: HTTPTextFormatT, context: typing.Optional[Context] = None, ) -> Context: trace_id_list = get_from_carrier(carrier, self.TRACE_ID_KEY) span_id_list = get_from_carrier(carrier, self.SPAN_ID_KEY) if not trace_id_list or not span_id_list: return trace.set_span_in_context(trace.INVALID_SPAN) return trace.set_span_in_context( trace.DefaultSpan( trace.SpanContext( trace_id=int(trace_id_list[0]), span_id=int(span_id_list[0]), is_remote=True, )))
def extract( self, getter: Getter[TextMapPropagatorT], carrier: TextMapPropagatorT, context: typing.Optional[Context] = None, ) -> Context: trace_id_list = getter.get(carrier, self.TRACE_ID_KEY) span_id_list = getter.get(carrier, self.SPAN_ID_KEY) if not trace_id_list or not span_id_list: return trace.set_span_in_context(trace.INVALID_SPAN) return trace.set_span_in_context( trace.NonRecordingSpan( trace.SpanContext( trace_id=int(trace_id_list[0]), span_id=int(span_id_list[0]), is_remote=True, )))
def build_test_current_context( trace_id=int(TRACE_ID_BASE16, 16), span_id=int(SPAN_ID_BASE16, 16), is_remote=True, trace_flags=DEFAULT_TRACE_OPTIONS, trace_state=DEFAULT_TRACE_STATE, ): return set_span_in_context( trace_api.NonRecordingSpan( build_test_span_context(trace_id, span_id, is_remote, trace_flags, trace_state)))