public TracerShim(Trace.Tracer tracer, TextMapPropagator textFormat) { this.tracer = tracer ?? throw new ArgumentNullException(nameof(tracer), "Parameter cannot be null"); this.propagator = textFormat ?? throw new ArgumentNullException(nameof(textFormat), "Parameter cannot be null"); this.ScopeManager = new ScopeManagerShim(this.tracer); }
private void TestDefaultPropagatorUsing(Activity a, TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage) { // Test with non-current propagator.Inject(a, null, (object carrier, string fieldName, string value) => { if (fieldName == TraceParent && a.IdFormat == ActivityIdFormat.W3C) { Assert.Equal(a.Id, value); return; } if (fieldName == RequestId && a.IdFormat != ActivityIdFormat.W3C) { Assert.Equal(a.Id, value); return; } if (fieldName == TraceState) { Assert.Equal(a.TraceStateString, value); return; } if (fieldName == CorrelationContext) { Assert.Equal(GetFormattedBaggage(a.Baggage), value); return; } Assert.False(true, $"Encountered wrong header name '{fieldName}'"); }); TestDefaultExtraction(propagator, a); TestBaggageExtraction(propagator, a); }
public void PropagatorStackShouldInjectExtractAllPropagators() { var ps = new PropagatorStack(BuiltinFormats.TextMap); var httpPropagator = new HttpHeadersPropagator(); var b3Propagator = new B3Propagator(); var textPropagator = new TextMapPropagator(); ps.AddPropagator(httpPropagator); ps.AddPropagator(b3Propagator); ps.AddPropagator(textPropagator); var carrier = new Dictionary <string, string>(); var context = new SpanContext(0, 0); ps.Inject(context, BuiltinFormats.TextMap, new TextMapInjectAdapter(carrier)); var propagators = new List <IPropagator> { httpPropagator, b3Propagator, textPropagator }; foreach (var t in propagators) { var extractedContext = t.Extract(BuiltinFormats.TextMap, new TextMapExtractAdapter(carrier)); Assert.NotNull(extractedContext); Assert.Equal(context.TraceId, extractedContext.TraceId); Assert.Equal(context.SpanId, extractedContext.SpanId); } }
public void TextHeaderPropagatorIsCaseSensitive(CasingType casingType) { UInt64 spanId = 4952807665017200957; UInt64 traceId = 14848807816610383171; var headers = new Dictionary <string, string> { { ToCase("Ot-Tracer-Spanid", casingType), spanId.ToString("X") }, { ToCase("Ot-Tracer-Traceid", casingType), traceId.ToString("X") }, }; var textPropagator = new TextMapPropagator(); var extractedContext = textPropagator.Extract(BuiltinFormats.TextMap, new TextMapExtractAdapter(headers)); if (casingType != CasingType.LowerCase) { Assert.Null(extractedContext); return; } Assert.NotNull(extractedContext); Assert.Equal(spanId.ToString("x"), extractedContext.SpanId); Assert.Equal(traceId.ToString("x"), extractedContext.TraceId); }
private void TestPassThroughPropagatorUsingW3CActivity(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage) { using Activity a = CreateW3CActivity("PassThroughW3C", "PassThroughW3CState=1", baggage); propagator.Inject(a, null, (object carrier, string fieldName, string value) => { if (fieldName == TraceParent) { Assert.Equal(a.Id, value); return; } if (fieldName == TraceState) { Assert.Equal(a.TraceStateString, value); return; } if (fieldName == CorrelationContext) { Assert.Equal(GetFormattedBaggage(a.Baggage), value); return; } Assert.False(true, $"Encountered wrong header name '{fieldName}'"); }); TestDefaultExtraction(propagator, a); TestBaggageExtraction(propagator, a); }
public PropagationContext Extract <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter) { if (this.defaultContext) { return(context); } IEnumerable <string> id = getter(carrier, this.idHeaderName); if (id.Count() <= 0) { return(context); } var traceparentParsed = TextMapPropagator.TryExtractTraceparent(id.First(), out var traceId, out var spanId, out var traceoptions); if (!traceparentParsed) { return(context); } string tracestate = string.Empty; IEnumerable <string> tracestateCollection = getter(carrier, this.stateHeaderName); if (tracestateCollection?.Any() ?? false) { TextMapPropagator.TryExtractTracestate(tracestateCollection.ToArray(), out tracestate); } return(new PropagationContext( new ActivityContext(traceId, spanId, traceoptions, tracestate), context.Baggage)); }
private void TestFields(TextMapPropagator propagator) { Assert.True(propagator.Fields.Contains(TraceParent)); Assert.True(propagator.Fields.Contains(RequestId)); Assert.True(propagator.Fields.Contains(TraceState)); Assert.True(propagator.Fields.Contains(Baggage)); Assert.True(propagator.Fields.Contains(CorrelationContext)); }
public TracerShim(Trace.Tracer tracer, TextMapPropagator textFormat) { Guard.ThrowIfNull(tracer); Guard.ThrowIfNull(textFormat); this.tracer = tracer; this.propagator = textFormat; this.ScopeManager = new ScopeManagerShim(this.tracer); }
public void TextMapPropagator_Extract_ThrowsWhenCarrierIsNotITextMap() { var propagator = new TextMapPropagator(new HeadersConfig("", ""), (val) => val, (val) => val); var spanContext = Substitute.For <ILetsTraceSpanContext>(); var ex = Assert.Throws <ArgumentException>(() => propagator.Extract(new List <string>())); Assert.Equal("carrier is not ITextMap", ex.Message); }
public void CanParseExampleFromSpec() { var headers = new Dictionary <string, string> { { TraceParent, $"00-{TraceId}-{SpanId}-01" }, { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" }, }; var f = new TextMapPropagator(); var ctx = f.Extract(default, headers, Getter);
public void TextMapPropagator_Extract_TraceContextHeaderMissing() { var headersConfig = new HeadersConfig("TraceContextHeaderName", "TraceBaggageHeaderPrefix"); var propagator = new TextMapPropagator(headersConfig, (val) => val, (val) => val); var carrier = new DictionaryTextMap(new Dictionary <string, string> { { "TraceBaggageHeaderPrefix-Item1", "item1" }, { "TraceBaggageHeaderPrefix-Item2", "item2" }, }); var sc = (SpanContext)propagator.Extract(carrier); Assert.Null(sc); }
private void TestNoOutputPropagatorUsingW3CActivity(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage) { using Activity a = CreateW3CActivity("NoOutputW3C", state, baggage); propagator.Inject(a, null, (object carrier, string fieldName, string value) => { Assert.False(true, $"Not expected to have the setter callback be called in the NoOutput propgator."); }); TestDefaultExtraction(propagator, a); TestBaggageExtraction(propagator, a); }
private void TestDefaultPropagatorUsingHierarchicalActivity(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage) { using Activity a = CreateHierarchicalActivity("LegacyHierarchical1", null, "LegacyHierarchicalState=1", baggage); using Activity b = CreateHierarchicalActivity("LegacyHierarchical2", null, "LegacyHierarchicalState=2", baggage); Assert.NotSame(Activity.Current, a); TestDefaultPropagatorUsing(a, propagator, state, baggage); Assert.Same(Activity.Current, b); TestDefaultPropagatorUsing(Activity.Current, propagator, state, baggage); }
public WorkerBackgroundService( ILogger <WorkerBackgroundService> logger, IConfiguration configuration, ConnectionFactory connectionFactory) { _logger = logger; _configuration = configuration; _connectionFactory = connectionFactory; _rabbitConnection = _connectionFactory.CreateConnection(); _rabbitChanel = _rabbitConnection.CreateModel(); _propagator = new TraceContextPropagator(); }
private void TestDefaultExtraction(TextMapPropagator propagator, Activity a) { bool traceParentEncountered = false; propagator.ExtractTraceIdAndState(null, (object carrier, string fieldName, out string?fieldValue, out IEnumerable <string>?fieldValues) => { Assert.Null(carrier); fieldValues = null; fieldValue = null; if (fieldName == TraceParent) { if (a.IdFormat == ActivityIdFormat.W3C) { fieldValue = a.Id; } else { traceParentEncountered = true; } return; } if (fieldName == RequestId) { if (a.IdFormat == ActivityIdFormat.W3C) { Assert.True(false, $"Not expected to get RequestId as we expect the request handled using TraceParenet."); } else { Assert.True(traceParentEncountered, $"Expected to get TraceParent request before getting RequestId."); fieldValue = a.Id; } return; } if (fieldName == TraceState) { fieldValue = a.TraceStateString; return; } Assert.False(true, $"Encountered wrong header name '{fieldName}'"); }, out string?traceId, out string?traceState); Assert.Equal(a.Id, traceId); Assert.Equal(a.TraceStateString, traceState); }
private void TestPassThroughPropagatorUsingHierarchicalActivityWithParentId(TextMapPropagator propagator, string state, IEnumerable <KeyValuePair <string, string> > baggage) { using Activity a = CreateHierarchicalActivity("PassThrough", "Parent1", state, baggage); using Activity b = CreateHierarchicalActivity("PassThroughChild1", "Parent2", state + "1", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("Child1Key", "Child1Value") }); using Activity c = CreateHierarchicalActivity("PassThroughChild2", "Parent3", state + "2", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("Child2Key", "Child2Value") }); propagator.Inject(a, null, (object carrier, string fieldName, string value) => { if (fieldName == TraceParent) { Assert.False(true, $"Unexpected to inject a TraceParent with Hierarchical Activity."); return; } if (fieldName == RequestId) { Assert.Equal(c.ParentId, value); return; } if (fieldName == TraceState) { Assert.Equal(c.TraceStateString, value); return; } if (fieldName == CorrelationContext) { Assert.Equal(GetFormattedBaggage(c.Baggage), value); return; } Assert.False(true, $"Encountered wrong header name '{fieldName}'"); }); TestDefaultExtraction(propagator, a); TestDefaultExtraction(propagator, b); TestDefaultExtraction(propagator, c); TestBaggageExtraction(propagator, a); TestBaggageExtraction(propagator, b); TestBaggageExtraction(propagator, c); }
public void InjectExtract_TextMap_Ok() { var carrier = new TextMapCarrier(); var spanContextShim = new SpanContextShim(new SpanContext(ActivityTraceId.CreateRandom(), ActivitySpanId.CreateRandom(), ActivityTraceFlags.None)); var format = new TextMapPropagator(); var tracer = TracerProvider.Default.GetTracer(TracerName); var shim = new TracerShim(tracer, format); // first inject shim.Inject(spanContextShim, BuiltinFormats.TextMap, carrier); // then extract var extractedSpanContext = shim.Extract(BuiltinFormats.TextMap, carrier); AssertOpenTracerSpanContextEqual(spanContextShim, extractedSpanContext); }
public void TextMapPropagator_Inject_SetsTheRightHeadersWithTheRightData() { var headersConfig = new HeadersConfig("TraceContextHeaderName", "TraceBaggageHeaderPrefix"); var propagator = new TextMapPropagator(headersConfig, (val) => val, (val) => val); var baggage = new Dictionary <string, string> { { "key1", "value1" }, { "key2", "value2" } }; var spanContext = Substitute.For <ILetsTraceSpanContext>(); var carrier = new DictionaryTextMap(); spanContext.GetBaggageItems().Returns(baggage); propagator.Inject(spanContext, carrier); var carrierDict = carrier.ToDictionary(c => c.Key, c => c.Value); Assert.Equal(spanContext.GetType().FullName, carrierDict[headersConfig.TraceContextHeaderName]); // cannot mock ToString Assert.Equal(baggage["key1"], carrierDict[$"{headersConfig.TraceBaggageHeaderPrefix}-key1"]); Assert.Equal(baggage["key2"], carrierDict[$"{headersConfig.TraceBaggageHeaderPrefix}-key2"]); }
public void TextMapPropagator_Extract_SetsTheRightHeadersWithTheRightData() { var headersConfig = new HeadersConfig("TraceContextHeaderName", "TraceBaggageHeaderPrefix"); var propagator = new TextMapPropagator(headersConfig, (val) => val, (val) => val); var carrier = new DictionaryTextMap(new Dictionary <string, string> { { "TraceContextHeaderName", "1:2:3:4" }, { "TraceBaggageHeaderPrefix-Item1", "item1" }, { "TraceBaggageHeaderPrefix-Item2", "item2" }, }); var sc = (SpanContext)propagator.Extract(carrier); var baggage = sc.GetBaggageItems().ToDictionary(kv => kv.Key, kv => kv.Value); Assert.Equal("item1", baggage["Item1"]); Assert.Equal("item2", baggage["Item2"]); Assert.Equal("1", sc.TraceId.Low.ToString()); Assert.Equal("2", sc.SpanId.ToString()); Assert.Equal("3", sc.ParentId.ToString()); Assert.Equal(4, (byte)sc.Flags); }
private void TestPassThroughPropagatorWithNullCurrent(TextMapPropagator propagator) { Activity.Current = null; propagator.Inject(null, null, (object carrier, string fieldName, string value) => { Assert.False(true, $"PassThroughPropagator shouldn't inject anything if the Activity.Current is null"); }); using Activity a = CreateW3CActivity("PassThroughNotNull", "", null); propagator.Inject(a, null, (object carrier, string fieldName, string value) => { if (fieldName == TraceParent) { Assert.Equal(a.Id, value); return; } Assert.False(true, $"Encountered wrong header name '{fieldName}'"); }); }
private void TestBaggageExtraction(TextMapPropagator propagator, Activity a) { bool baggageEncountered = false; IEnumerable <KeyValuePair <string, string?> >?b = propagator.ExtractBaggage(null, (object carrier, string fieldName, out string?fieldValue, out IEnumerable <string>?fieldValues) => { Assert.Null(carrier); fieldValue = null; fieldValues = null; if (fieldName == Baggage) { if (a.IdFormat == ActivityIdFormat.W3C) { fieldValue = GetFormattedBaggage(a.Baggage); } else { baggageEncountered = true; } return; } if (fieldName == CorrelationContext && a.IdFormat != ActivityIdFormat.W3C) { Assert.True(baggageEncountered, $"Expected to get Baggage request before getting Correlation-Context."); fieldValue = GetFormattedBaggage(a.Baggage); return; } Assert.False(true, $"Encountered wrong header name '{fieldName}'"); }); Assert.Equal(GetFormattedBaggage(a.Baggage, false, true), GetFormattedBaggage(b, true)); }
/// <summary> /// Creates root (first level) activity that describes incoming request. /// </summary> /// <param name="textMapPropagator"><see cref="TextMapPropagator"/>.</param> /// <param name="context"><see cref="HttpContext"/>.</param> /// <param name="onRequestStartedCallback">Callback action.</param> /// <returns>New root activity.</returns> public static Activity StartAspNetActivity(TextMapPropagator textMapPropagator, HttpContext context, Action <Activity, HttpContext> onRequestStartedCallback) { Debug.Assert(context != null, "Context is null."); PropagationContext propagationContext = textMapPropagator.Extract(default, context.Request, HttpRequestHeaderValuesGetter);
internal static void Reset() { DefaultTextMapPropagator = Noop; }
public void TestAllPropagators() { RemoteExecutor.Invoke(() => { Assert.NotNull(TextMapPropagator.Current); // // Default Propagator // Assert.Same(TextMapPropagator.CreateDefaultPropagator(), TextMapPropagator.Current); TestDefaultPropagatorUsingW3CActivity( TextMapPropagator.Current, "Legacy1=true", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>(" LegacyKey1 ", " LegacyValue1 ") }); TestDefaultPropagatorUsingHierarchicalActivity( TextMapPropagator.Current, "Legacy2=true", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("LegacyKey2", "LegacyValue2") }); TestFields(TextMapPropagator.Current); // // NoOutput Propagator // TextMapPropagator.Current = TextMapPropagator.CreateNoOutputPropagator(); Assert.NotNull(TextMapPropagator.Current); TestNoOutputPropagatorUsingHierarchicalActivity( TextMapPropagator.Current, "ActivityState=1", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("B1", "V1"), new KeyValuePair <string, string>(" B2 ", " V2 ") }); TestNoOutputPropagatorUsingHierarchicalActivity( TextMapPropagator.Current, "ActivityState=2", null); TestNoOutputPropagatorUsingW3CActivity( TextMapPropagator.Current, "ActivityState=1", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>(" B3 ", " V3"), new KeyValuePair <string, string>(" B4 ", " V4 "), new KeyValuePair <string, string>("B5", "V5") }); TestNoOutputPropagatorUsingW3CActivity( TextMapPropagator.Current, "ActivityState=2", null); TestFields(TextMapPropagator.Current); // // Pass Through Propagator // TextMapPropagator.Current = TextMapPropagator.CreatePassThroughPropagator(); Assert.NotNull(TextMapPropagator.Current); TestPassThroughPropagatorUsingHierarchicalActivityWithParentChain( TextMapPropagator.Current, "PassThrough=true", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("PassThroughKey1", "PassThroughValue1"), new KeyValuePair <string, string>("PassThroughKey2", "PassThroughValue2") }); TestPassThroughPropagatorUsingHierarchicalActivityWithParentId( TextMapPropagator.Current, "PassThrough1=true", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>("PassThroughKey3", "PassThroughValue3"), new KeyValuePair <string, string>(" PassThroughKey4 ", " PassThroughValue4 ") }); TestPassThroughPropagatorUsingW3CActivity( TextMapPropagator.Current, "PassThrough2=1", new List <KeyValuePair <string, string> >() { new KeyValuePair <string, string>(" PassThroughKey4 ", " PassThroughValue4 ") }); TestPassThroughPropagatorWithNullCurrent(TextMapPropagator.Current); TestFields(TextMapPropagator.Current); // // Test Current // Assert.Throws <ArgumentNullException>(() => TextMapPropagator.Current = null); }).Dispose(); }
/// <summary> /// Sets the Default TextMapPropagator. /// </summary> /// <param name="textMapPropagator">TextMapPropagator to be set as default.</param> public static void SetDefaultTextMapPropagator(TextMapPropagator textMapPropagator) { Propagators.DefaultTextMapPropagator = textMapPropagator; }