private static Activity CreateSubstituteActivityFromCompatibleRootId(Activity currentActivity, ReadOnlySpan <char> traceId) { #pragma warning disable CA2000 // Dispose objects before losing scope // Since we don't know when it will finish, we will not dispose var activity = new Activity(currentActivity.OperationName); #pragma warning restore CA2000 // Dispose objects before losing scope activity.SetParentId(ActivityTraceId.CreateFromString(traceId), default, ActivityTraceFlags.None);
public void TraceContextFormatCanParseExampleFromSpec() { var headers = new Dictionary <string, string>() { { "traceparent", "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01" }, { "tracestate", "congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01" }, }; var f = new TraceContextFormat(); var ctx = f.Extract(headers, getter); Assert.Equal(ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c".AsSpan()), ctx.TraceId); Assert.Equal(ActivitySpanId.CreateFromString("b9c7c989f97918e1".AsSpan()), ctx.SpanId); Assert.True(ctx.IsRemote); Assert.True(ctx.IsValid); Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) != 0); Assert.Equal(2, ctx.Tracestate.Count()); var first = ctx.Tracestate.First(); Assert.Equal("congo", first.Key); Assert.Equal("lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4", first.Value); var last = ctx.Tracestate.Last(); Assert.Equal("rojo", last.Key); Assert.Equal("00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01", last.Value); }
internal SpanData CreateTestSpan( bool setAttributes = true, bool addEvents = true, bool addLinks = true, Resource resource = null) { var startTimestamp = DateTime.UtcNow; var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = DateTime.UtcNow; var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var spanId = ActivitySpanId.CreateRandom(); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }; var events = new List <Event> { new Event( "Event1", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), new Event( "Event2", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); return(new SpanData( "Name", new SpanContext(traceId, spanId, ActivityTraceFlags.Recorded), parentSpanId, SpanKind.Client, startTimestamp, setAttributes ? attributes : null, addEvents ? events : null, addLinks ? new[] { new Link(new SpanContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)), } : null, resource, Status.Ok, endTimestamp)); }
public void TraceContextFormatCanParseExampleFromSpec() { var headers = new Dictionary <string, string> { { TraceParent, $"00-{TraceId}-{SpanId}-01" }, { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" }, }; var f = new TraceContextFormat(); var ctx = f.Extract(headers, Getter); Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.TraceId); Assert.Equal(ActivitySpanId.CreateFromString(SpanId.AsSpan()), ctx.SpanId); Assert.True(ctx.IsRemote); Assert.True(ctx.IsValid); Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) != 0); Assert.Equal(2, ctx.Tracestate.Count()); var first = ctx.Tracestate.First(); Assert.Equal("congo", first.Key); Assert.Equal("lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4", first.Value); var last = ctx.Tracestate.Last(); Assert.Equal("rojo", last.Key); Assert.Equal($"00-{TraceId}-00f067aa0ba902b7-01", last.Value); }
public ActivityContext(string traceParent, string traceState) { SpanId = ActivitySpanId.CreateFromString(traceParent.AsSpan(36, 16)); TraceId = ActivityTraceId.CreateFromString(traceParent.AsSpan(3, 32)); Flags = (ActivityTraceFlags)HexByteFromChars(traceParent[53], traceParent[54]); TraceState = new ActivityTraceState(traceState); }
public override void OnEvent(KeyValuePair <string, object> evnt, DiagnosticListener ignored) { Activity currentActivity = Activity.Current; switch (evnt.Key) { case "Microsoft.Azure.ServiceBus.ProcessSession.Start": case "Microsoft.Azure.ServiceBus.Process.Start": // if Activity is W3C, but there is a parent id which is not W3C. if (currentActivity.IdFormat == ActivityIdFormat.W3C && !string.IsNullOrEmpty(currentActivity.ParentId) && currentActivity.ParentSpanId == default) { // if hierarchical parent has compatible rootId, reuse it and keep legacy parentId if (W3CUtilities.TryGetTraceId(currentActivity.ParentId, out var traceId)) { #pragma warning disable CA2000 // Dispose objects before losing scope // Since we don't know when it will finish, we will not dispose var backCompatActivity = new Activity(currentActivity.OperationName); #pragma warning restore CA2000 // Dispose objects before losing scope backCompatActivity.SetParentId(ActivityTraceId.CreateFromString(traceId), default, currentActivity.ActivityTraceFlags); backCompatActivity.Start(); backCompatActivity.AddTag("__legacyParentId", currentActivity.ParentId); foreach (var tag in currentActivity.Tags) { backCompatActivity.AddTag(tag.Key, tag.Value); } foreach (var baggage in currentActivity.Baggage) { backCompatActivity.AddBaggage(baggage.Key, baggage.Value); } }
private static PropagationContext ExtractFromSingleHeader <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter) { try { var header = getter(carrier, XB3Combined)?.FirstOrDefault(); if (string.IsNullOrWhiteSpace(header)) { return(context); } var parts = header.Split(XB3CombinedDelimiter); if (parts.Length < 2 || parts.Length > 4) { return(context); } var traceIdStr = parts[0]; if (string.IsNullOrWhiteSpace(traceIdStr)) { return(context); } if (traceIdStr.Length == 16) { // This is an 8-byte traceID. traceIdStr = UpperTraceId + traceIdStr; } var traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan()); var spanIdStr = parts[1]; if (string.IsNullOrWhiteSpace(spanIdStr)) { return(context); } var spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan()); var traceOptions = ActivityTraceFlags.None; if (parts.Length > 2) { var traceFlagsStr = parts[2]; if (SampledValues.Contains(traceFlagsStr) || FlagsValue.Equals(traceFlagsStr, StringComparison.Ordinal)) { traceOptions |= ActivityTraceFlags.Recorded; } } return(new PropagationContext( new ActivityContext(traceId, spanId, traceOptions, isRemote: true), context.Baggage)); } catch (Exception e) { OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(B3Propagator), e); return(context); } }
/// <inheritdoc/> public SpanContext Extract <T>(T carrier, Func <T, string, IEnumerable <string> > getter) { if (carrier == null) { OpenTelemetrySdkEventSource.Log.FailedToExtractContext("null carrier"); return(SpanContext.BlankRemote); } if (getter == null) { OpenTelemetrySdkEventSource.Log.FailedToExtractContext("null getter"); return(SpanContext.BlankRemote); } try { ActivityTraceId traceId; var traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault(); if (traceIdStr != null) { if (traceIdStr.Length == 16) { // This is an 8-byte traceID. traceIdStr = UpperTraceId + traceIdStr; } traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan()); } else { return(SpanContext.BlankRemote); } ActivitySpanId spanId; var spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault(); if (spanIdStr != null) { spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan()); } else { return(SpanContext.BlankRemote); } var traceOptions = ActivityTraceFlags.None; if (SampledValue.Equals(getter(carrier, XB3Sampled)?.FirstOrDefault()) || FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault())) { traceOptions |= ActivityTraceFlags.Recorded; } return(new SpanContext(traceId, spanId, traceOptions)); } catch (Exception e) { OpenTelemetrySdkEventSource.Log.ContextExtractException(e); return(SpanContext.BlankRemote); } }
private Activity CreateTestActivity() { var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var spanId = ActivitySpanId.CreateFromString("6a69db47429ea340".AsSpan()); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }; var events = new List <ActivityEvent> { new ActivityEvent( "Event1", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), new ActivityEvent( "Event2", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = attributes.Select(kvp => new KeyValuePair <string, string>(kvp.Key, kvp.Value.ToString())); var links = new[] { new ActivityLink(new ActivityContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)), }; return(activitySource.StartActivity( "Name", ActivityKind.Client, parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), tags, links, startTime: startTimestamp)); }
public override ActivityContext Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var reader = context.Reader; switch (reader.CurrentBsonType) { case BsonType.Null: reader.ReadNull(); return(default); case BsonType.Document: reader.ReadStartDocument(); var isRemote = false; var traceId = default(ActivityTraceId); var traceFlags = default(ActivityTraceFlags); var traceState = (string?)null; var spanId = default(ActivitySpanId); while (reader.ReadBsonType() != BsonType.EndOfDocument) { var name = reader.ReadName(Utf8NameDecoder.Instance); switch (name) { case nameof(ActivityContext.IsRemote): isRemote = reader.ReadBoolean(); break; case nameof(ActivityContext.TraceId): traceId = ActivityTraceId.CreateFromString(reader.ReadString()); break; case nameof(ActivityContext.TraceFlags): traceFlags = Enum.Parse <ActivityTraceFlags>(reader.ReadString() !); break; case nameof(ActivityContext.TraceState): traceState = reader.ReadString(); break; case nameof(ActivityContext.SpanId): spanId = ActivitySpanId.CreateFromString(reader.ReadString()); break; default: throw new BsonSerializationException($"Invalid property {name}."); } } reader.ReadEndDocument(); return(new ActivityContext(traceId, spanId, traceFlags, traceState, isRemote)); default: throw new BsonSerializationException($"Expected BsonType.Document or JsonTokenType.Null, got {reader.CurrentBsonType}."); } }
private SpanData CreateTestSpan() { var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var spanId = ActivitySpanId.CreateFromString("6a69db47429ea340".AsSpan()); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }; var events = new List <Event> { new Event( "Event1", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), new Event( "Event2", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var link = new Link(new SpanContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)); return(new SpanData( "Name", new SpanContext(traceId, spanId, ActivityTraceFlags.Recorded), parentSpanId, SpanKind.Client, startTimestamp, attributes, events, new[] { link, }, null, Status.Ok, endTimestamp)); }
private Span CreateTestSpan() { var startTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = new DateTimeOffset(2019, 1, 1, 0, 0, 0, TimeSpan.Zero); var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var spanId = "6a69db47429ea340"; var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }; var events = new List <Event> { new Event( "Event1", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), new Event( "Event2", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var link = new Link(new SpanContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)); var span = (Span)tracer .StartSpan("Name", new SpanContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), SpanKind.Client, new SpanCreationOptions { StartTimestamp = startTimestamp, Links = new[] { link }, }); var spanContextSetter = typeof(Span).GetMethod("set_Context", BindingFlags.Instance | BindingFlags.NonPublic); ActivitySpanId activitySpanId = ActivitySpanId.CreateFromString(spanId.AsSpan()); spanContextSetter.Invoke(span, new [] { (object)new SpanContext(in traceId, in activitySpanId, ActivityTraceFlags.Recorded) });
/// <inheritdoc/> public SpanContext Extract <T>(T carrier, Func <T, string, IEnumerable <string> > getter) { if (carrier == null) { throw new ArgumentNullException(nameof(carrier)); } if (getter == null) { throw new ArgumentNullException(nameof(getter)); } try { ActivityTraceId traceId; var traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault(); if (traceIdStr != null) { if (traceIdStr.Length == 16) { // This is an 8-byte traceID. traceIdStr = UpperTraceId + traceIdStr; } traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan()); } else { throw new SpanContextParseException("Missing X_B3_TRACE_ID."); } ActivitySpanId spanId; var spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault(); if (spanIdStr != null) { spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan()); } else { throw new SpanContextParseException("Missing X_B3_SPAN_ID."); } var traceOptions = ActivityTraceFlags.None; if (SampledValue.Equals(getter(carrier, XB3Sampled)?.FirstOrDefault()) || FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault())) { traceOptions |= ActivityTraceFlags.Recorded; } return(new SpanContext(traceId, spanId, traceOptions)); } catch (Exception e) { throw new SpanContextParseException("Invalid input.", e); } }
public void TestExtractTraceHeader() { var carrier = new Dictionary <string, string>() { { AWSXRayTraceHeaderKey, "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1" }, }; var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); var traceFlags = ActivityTraceFlags.Recorded; var activityContext = new ActivityContext(traceId, parentId, traceFlags, isRemote: true); Assert.Equal(new PropagationContext(activityContext, default), this.awsXRayPropagator.Extract(default, carrier, Getter));
public override ActivityContext Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { switch (reader.TokenType) { case JsonTokenType.Null: return(default); case JsonTokenType.StartObject: var isRemote = false; var traceId = default(ActivityTraceId); var traceFlags = default(ActivityTraceFlags); var traceState = (string?)null; var spanId = default(ActivitySpanId); while (reader.Read() && reader.TokenType != JsonTokenType.EndObject) { var property = reader.GetString(); reader.Read(); switch (property) { case "isRemote": isRemote = reader.GetBoolean(); break; case "traceId": traceId = ActivityTraceId.CreateFromString(reader.GetString()); break; case "traceFlags": traceFlags = Enum.Parse <ActivityTraceFlags>(reader.GetString() !); break; case "traceState": traceState = reader.GetString(); break; case "spanId": spanId = ActivitySpanId.CreateFromString(reader.GetString()); break; default: throw new JsonException($"Invalid property {property}."); } } return(new ActivityContext(traceId, spanId, traceFlags, traceState, isRemote)); default: throw new JsonException($"Expected JsonTokenType.StartObject or JsonTokenType.Null, got {reader.TokenType}."); } }
public void TestInjectTraceHeaderNotSampled() { var carrier = new Dictionary <string, string>(); var traceId = ActivityTraceId.CreateFromString(TraceId.AsSpan()); var parentId = ActivitySpanId.CreateFromString(ParentId.AsSpan()); var traceFlags = ActivityTraceFlags.None; var activityContext = new ActivityContext(traceId, parentId, traceFlags); this.awsXRayPropagator.Inject(new PropagationContext(activityContext, default), carrier, Setter); Assert.True(carrier.ContainsKey(AWSXRayTraceHeaderKey)); Assert.Equal("Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=0", carrier[AWSXRayTraceHeaderKey]); }
private static ActivityContext GetActivityContext(Context context) { if (context == null || string.IsNullOrEmpty(context.TraceId) || string.IsNullOrEmpty(context.SpanId)) { return(default(ActivityContext)); } Enum.TryParse(context.TraceFlags, out ActivityTraceFlags flags); return(new ActivityContext( ActivityTraceId.CreateFromString(context.TraceId.ToCharArray()), ActivitySpanId.CreateFromString(context.SpanId.ToCharArray()), flags, context.TraceState)); }
public void TraceContextFormatNotSampled() { var headers = new Dictionary <string, string>() { { "traceparent", "00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-00" }, }; var f = new TraceContextFormat(); var ctx = f.Extract(headers, getter); Assert.Equal(ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c".AsSpan()), ctx.TraceId); Assert.Equal(ActivitySpanId.CreateFromString("b9c7c989f97918e1".AsSpan()), ctx.SpanId); Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) == 0); }
private static PropagationContext ExtractFromMultipleHeaders <T>(PropagationContext context, T carrier, Func <T, string, IEnumerable <string> > getter) { try { ActivityTraceId traceId; var traceIdStr = getter(carrier, XB3TraceId)?.FirstOrDefault(); if (traceIdStr != null) { if (traceIdStr.Length == 16) { // This is an 8-byte traceID. traceIdStr = UpperTraceId + traceIdStr; } traceId = ActivityTraceId.CreateFromString(traceIdStr.AsSpan()); } else { return(context); } ActivitySpanId spanId; var spanIdStr = getter(carrier, XB3SpanId)?.FirstOrDefault(); if (spanIdStr != null) { spanId = ActivitySpanId.CreateFromString(spanIdStr.AsSpan()); } else { return(context); } var traceOptions = ActivityTraceFlags.None; if (SampledValues.Contains(getter(carrier, XB3Sampled)?.FirstOrDefault()) || FlagsValue.Equals(getter(carrier, XB3Flags)?.FirstOrDefault(), StringComparison.Ordinal)) { traceOptions |= ActivityTraceFlags.Recorded; } return(new PropagationContext( new ActivityContext(traceId, spanId, traceOptions, isRemote: true), context.Baggage)); } catch (Exception e) { OpenTelemetryApiEventSource.Log.ActivityContextExtractException(nameof(B3Propagator), e); return(context); } }
public void TraceIdBeforeStartTests() { try { Activity activity; // from traceparent header activity = new Activity("activity1"); activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); // from explicit TraceId and SpanId activity = new Activity("activity2"); activity.SetParentId( ActivityTraceId.CreateFromString("0123456789abcdef0123456789abcdef".AsSpan()), ActivitySpanId.CreateFromString("0123456789abcdef".AsSpan())); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); // from in-proc parent Activity parent = new Activity("parent"); parent.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"); parent.Start(); activity = new Activity("child"); activity.Start(); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); parent.Stop(); activity.Stop(); // no parent Activity.DefaultIdFormat = ActivityIdFormat.W3C; Activity.ForceDefaultIdFormat = true; activity = new Activity("activity3"); Assert.Equal("00000000000000000000000000000000", activity.TraceId.ToHexString()); // from invalid traceparent header activity.SetParentId("123"); Assert.Equal("00000000000000000000000000000000", activity.TraceId.ToHexString()); } finally { Activity.ForceDefaultIdFormat = false; Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical; Activity.Current = null; } }
public void TraceContextFormatNotSampled() { var headers = new Dictionary <string, string> { { TraceParent, $"00-{TraceId}-{SpanId}-00" }, }; var f = new TraceContextFormat(); var ctx = f.Extract(headers, Getter); Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.TraceId); Assert.Equal(ActivitySpanId.CreateFromString(SpanId.AsSpan()), ctx.SpanId); Assert.True((ctx.TraceOptions & ActivityTraceFlags.Recorded) == 0); Assert.True(ctx.IsRemote); Assert.True(ctx.IsValid); }
public void TestGenerateTraceIdForNonRootNodeNotSampled() { var activity = new Activity("Test"); var traceId = ActivityTraceId.CreateFromString("12345678901234567890123456789012".AsSpan()); var parentId = ActivitySpanId.CreateFromString("1234567890123456".AsSpan()); activity.SetParentId(traceId, parentId, ActivityTraceFlags.None); using (Sdk.CreateTracerProviderBuilder().AddXRayTraceId().Build()) { activity.Start(); Assert.Equal("12345678901234567890123456789012", activity.TraceId.ToHexString()); Assert.Equal("1234567890123456", activity.ParentSpanId.ToHexString()); Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); } }
public void BasicActivityTracking() { var healthReporter = new Mock <IHealthReporter>(); var observer = new TestObserver(); var ActivityName = GetRandomName(); var sources = new List <ActivitySourceConfiguration>(new[] { new ActivitySourceConfiguration { ActivitySourceName = SourceOneName, ActivityName = ActivityName, CapturedData = ActivitySamplingResult.AllData, CapturedEvents = CapturedActivityEvents.Both } }); using (var input = new ActivitySourceInput(new ActivitySourceInputConfiguration { Sources = sources }, healthReporter.Object)) { input.Subscribe(observer); var ctx = new ActivityContext( ActivityTraceId.CreateFromString(WellKnownTraceId), ActivitySpanId.CreateFromString(SpanIdOne), ActivityTraceFlags.None); var activity = SourceOne.StartActivity(ActivityName, ActivityKind.Internal, ctx); activity.Stop(); } healthReporter.VerifyNoOtherCalls(); Assert.Equal(2, observer.Data.Count); Assert.True(observer.Completed); Assert.Null(observer.Error); Assert.True(observer.Data.TryDequeue(out EventData e)); VerifyActivityEvent(e, ActivityName, SourceOneName, CapturedActivityEvents.Start, WellKnownTraceId, SpanIdOne); Assert.True(observer.Data.TryDequeue(out e)); VerifyActivityEvent(e, ActivityName, SourceOneName, CapturedActivityEvents.Stop, WellKnownTraceId, SpanIdOne); }
public static TraceParent CreateFromString(string traceparent) { if (string.IsNullOrWhiteSpace(traceparent)) { throw new ArgumentException("Invalid traceparent", nameof(traceparent)); } var vals = traceparent.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries); if (vals.Length != 4) { throw new ArgumentException("Invalid traceparent format: {traceparent}", traceparent); } var traceId = ActivityTraceId.CreateFromString(vals[1].AsSpan()); var spanId = ActivitySpanId.CreateFromString(vals[2].AsSpan()); var flags = vals[3] == "01" ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None; // TODO: validate each item return(new TraceParent(traceId, spanId, flags, vals[0])); }
private static Activity CopyFromCompatibleRoot(Activity from) { var copy = new Activity(from.OperationName); copy.SetParentId(ActivityTraceId.CreateFromString(from.RootId.AsSpan()), default(ActivitySpanId), from.ActivityTraceFlags); foreach (var tag in from.Tags) { copy.AddTag(tag.Key, tag.Value); } foreach (var baggage in from.Baggage) { copy.AddBaggage(baggage.Key, baggage.Value); } copy.TraceStateString = from.TraceStateString; return(copy); }
public void TraceContextFormatCanParseExampleFromSpec() { var headers = new Dictionary <string, string> { { TraceParent, $"00-{TraceId}-{SpanId}-01" }, { TraceState, $"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01" }, }; var f = new TraceContextFormatActivity(); var ctx = f.Extract(headers, Getter); Assert.Equal(ActivityTraceId.CreateFromString(TraceId.AsSpan()), ctx.TraceId); Assert.Equal(ActivitySpanId.CreateFromString(SpanId.AsSpan()), ctx.SpanId); // TODO: when ActivityContext supports IsRemote // Assert.True(ctx.IsRemote); Assert.True(ctx.IsValid()); Assert.True((ctx.TraceFlags & ActivityTraceFlags.Recorded) != 0); Assert.Equal($"congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4,rojo=00-{TraceId}-00f067aa0ba902b7-01", ctx.TraceState); }
private async Task <TelemetrySpan> PreBefore(CapHeader header) { if (!header.ContainsKey(CurrentDeviceId)) { throw new Exception("currentDeviceId不可为空"); } _dbContextFactory.IsTransaction = true; var deviceId = Convert.ToInt32(header[CurrentDeviceId]); var deviceDto = await _deviceService.GetDeviceById_Pref(deviceId); _current.Device = deviceDto; var tracer = _tracerFactory.GetTracer(header[CapMsgName]); var traceId = header.ContainsKey(TraceId) ? header[TraceId] : CommonHelper.NewSequentialGuid().ToString(); var spanId = tracer.CurrentSpan.Context.SpanId; var spanContext = new SpanContext( ActivityTraceId.CreateFromString(traceId), spanId, // ActivitySpanId.CreateFromString(""), ActivityTraceFlags.None); return(tracer.StartSpan(header[CapMsgName], spanContext, SpanKind.Server)); }
internal static Activity CreateTestActivity( bool setAttributes = true, Dictionary <string, object> additionalAttributes = null, bool addEvents = true, bool addLinks = true, Resource resource = null, ActivityKind kind = ActivityKind.Client) { var startTimestamp = DateTime.UtcNow; var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = DateTime.UtcNow; var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, { "int_array", new int[] { 1, 2 } }, { "bool_array", new bool[] { true, false } }, { "double_array", new double[] { 1.0, 1.1 } }, { "string_array", new string[] { "a", "b" } }, }; if (additionalAttributes != null) { foreach (var attribute in additionalAttributes) { attributes.Add(attribute.Key, attribute.Value); } } var events = new List <ActivityEvent> { new ActivityEvent( "Event1", eventTimestamp, new ActivityTagsCollection(new Dictionary <string, object> { { "key", "value" }, })), new ActivityEvent( "Event2", eventTimestamp, new ActivityTagsCollection(new Dictionary <string, object> { { "key", "value" }, })), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var activitySource = new ActivitySource(nameof(CreateTestActivity)); var tags = setAttributes ? attributes : null; var links = addLinks ? new[] { new ActivityLink(new ActivityContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)), } : null; var activity = activitySource.StartActivity( "Name", kind, parentContext: new ActivityContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), tags, links, startTime: startTimestamp); if (addEvents) { foreach (var evnt in events) { activity.AddEvent(evnt); } } activity.SetEndTime(endTimestamp); activity.Stop(); return(activity); }
internal static bool TryExtractTraceparent(string traceparent, out ActivityTraceId traceId, out ActivitySpanId spanId, out ActivityTraceFlags traceOptions) { // from https://github.com/w3c/distributed-tracing/blob/master/trace_context/HTTP_HEADER_FORMAT.md // traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01 traceId = default; spanId = default; traceOptions = default; var bestAttempt = false; if (string.IsNullOrWhiteSpace(traceparent) || traceparent.Length < TraceparentLengthV0) { return(false); } // if version does not end with delimiter if (traceparent[VersionPrefixIdLength - 1] != '-') { return(false); } // or version is not a hex (will throw) var version0 = HexCharToByte(traceparent[0]); var version1 = HexCharToByte(traceparent[1]); if (version0 == 0xf && version1 == 0xf) { return(false); } if (version0 > 0) { // expected version is 00 // for higher versions - best attempt parsing of trace id, span id, etc. bestAttempt = true; } if (traceparent[VersionAndTraceIdLength - 1] != '-') { return(false); } try { traceId = ActivityTraceId.CreateFromString(traceparent.AsSpan().Slice(VersionPrefixIdLength, TraceIdLength)); } catch (ArgumentOutOfRangeException) { // it's ok to still parse tracestate return(false); } if (traceparent[VersionAndTraceIdAndSpanIdLength - 1] != '-') { return(false); } byte options1; try { spanId = ActivitySpanId.CreateFromString(traceparent.AsSpan().Slice(VersionAndTraceIdLength, SpanIdLength)); options1 = HexCharToByte(traceparent[VersionAndTraceIdAndSpanIdLength + 1]); } catch (ArgumentOutOfRangeException) { // it's ok to still parse tracestate return(false); } if ((options1 & 1) == 1) { traceOptions |= ActivityTraceFlags.Recorded; } if ((!bestAttempt) && (traceparent.Length != VersionAndTraceIdAndSpanIdLength + OptionsLength)) { return(false); } if (bestAttempt) { if ((traceparent.Length > TraceparentLengthV0) && (traceparent[TraceparentLengthV0] != '-')) { return(false); } } return(true); }
internal Span CreateTestSpan(bool setAttributes = true, bool addEvents = true, bool addLinks = true) { var startTimestamp = DateTime.UtcNow; var endTimestamp = startTimestamp.AddSeconds(60); var eventTimestamp = DateTime.UtcNow; var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan()); var parentSpanId = ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 }); var attributes = new Dictionary <string, object> { { "stringKey", "value" }, { "longKey", 1L }, { "longKey2", 1 }, { "doubleKey", 1D }, { "doubleKey2", 1F }, { "boolKey", true }, }; var events = new List <Event> { new Event( "Event1", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), new Event( "Event2", eventTimestamp, new Dictionary <string, object> { { "key", "value" }, } ), }; var linkedSpanId = ActivitySpanId.CreateFromString("888915b6286b9c41".AsSpan()); var link = new Link(new SpanContext( traceId, linkedSpanId, ActivityTraceFlags.Recorded)); var span = (Span)tracer .StartSpan("Name", new SpanContext(traceId, parentSpanId, ActivityTraceFlags.Recorded), SpanKind.Client, startTimestamp); if (addLinks) { span.AddLink(link); } if (setAttributes) { foreach (var attribute in attributes) { span.SetAttribute(attribute); } } if (addEvents) { foreach (var evnt in events) { span.AddEvent(evnt); } } span.Status = Status.Ok; span.End(endTimestamp); return(span); }