private string EncodeTraceId(ActivityTraceId traceId) { var id = traceId.ToHexString(); if (id.Length > 16 && this.options.UseShortTraceIds) { id = id.Substring(id.Length - 16, 16); } return(id); }
private static string EncodeTraceId(ActivityTraceId traceId, bool useShortTraceIds) { var id = traceId.ToHexString(); if (id.Length > 16 && useShortTraceIds) { id = id.Substring(id.Length - 16, 16); } return(id); }
public static ulong ToLSTraceId(this ActivityTraceId traceId) { var id = traceId.ToHexString(); if (id.Length > 16) { id = id.Substring(id.Length - 16, 16); } return(Convert.ToUInt64(id, 16)); }
private static string TraceIdToHexString(ActivityTraceId traceId) { if (EmptyTraceId.Equals(traceId)) { return(string.Empty); } else { return(traceId.ToHexString()); } }
public void LogMessage(Activity?activity, string category, LogLevel level, EventId eventId, int threadId, string message) { if (!IsEnabled(level)) { return; } Guid partitionId = m_serviceContext.PartitionId; long replicaId = m_serviceContext.ReplicaOrInstanceId; string applicationName = m_executionContext.ApplicationName; string serviceName = m_executionContext.ServiceName; string buildVersion = m_executionContext.BuildVersion; string machineId = m_executionContext.MachineId; string tagName = eventId.Name; // In case if tag created using Tag.Create (line number and file in description) it's better to display decimal number string tagId = string.IsNullOrWhiteSpace(eventId.Name) #pragma warning disable CS0618 // Need to be used for to process reserved tags from GitTagger ? TagsExtensions.TagIdAsString(eventId.Id) #pragma warning restore CS0618 : eventId.Id.ToString(CultureInfo.InvariantCulture); string activityId = string.Empty; ActivityTraceId activityTraceId = default; Guid obsoleteCorrelationId = Guid.Empty; uint obsoleteTransactionId = 0u; if (activity != null) { activityId = activity.Id ?? string.Empty; activityTraceId = activity.TraceId; if (m_options.Value.AddObsoleteCorrelationToActivity) { #pragma warning disable CS0618 // We are using obsolete correlation to support logging correlation from old Omex services obsoleteCorrelationId = activity.GetObsoleteCorrelationId() ?? Guid.Empty; obsoleteTransactionId = activity.GetObsolteteTransactionId() ?? 0u; #pragma warning restore CS0618 } } string traceIdAsString = activityTraceId.ToHexString(); //Event methods should have all information as parameters so we are passing them each time // Posible Breaking changes: // 1. ThreadId type Changed from string to avoid useless string creation // 2. New fileds added: // a. tagName to events since it will have more useful information // b. activityId required for tracking net core activity // c. activityTraceId required for tracking net core activity switch (level) { case LogLevel.None: break; case LogLevel.Trace: m_eventSource.LogSpamServiceMessage(applicationName, serviceName, machineId, buildVersion, s_processName, partitionId, replicaId, activityId, traceIdAsString, obsoleteCorrelationId, obsoleteTransactionId, "Spam", category, tagId, tagName, threadId, message); break; case LogLevel.Debug: m_eventSource.LogVerboseServiceMessage(applicationName, serviceName, machineId, buildVersion, s_processName, partitionId, replicaId, activityId, traceIdAsString, obsoleteCorrelationId, obsoleteTransactionId, "Verbose", category, tagId, tagName, threadId, message); break; case LogLevel.Information: m_eventSource.LogInfoServiceMessage(applicationName, serviceName, machineId, buildVersion, s_processName, partitionId, replicaId, activityId, traceIdAsString, obsoleteCorrelationId, obsoleteTransactionId, "Info", category, tagId, tagName, threadId, message); break; case LogLevel.Warning: m_eventSource.LogWarningServiceMessage(applicationName, serviceName, machineId, buildVersion, s_processName, partitionId, replicaId, activityId, traceIdAsString, obsoleteCorrelationId, obsoleteTransactionId, "Warning", category, tagId, tagName, threadId, message); break; case LogLevel.Error: case LogLevel.Critical: m_eventSource.LogErrorServiceMessage(applicationName, serviceName, machineId, buildVersion, s_processName, partitionId, replicaId, activityId, traceIdAsString, obsoleteCorrelationId, obsoleteTransactionId, "Error", category, tagId, eventId.Name, threadId, message); break; default: throw new ArgumentException(FormattableString.Invariant($"Unknown EventLevel: {level}")); } }
public void ActivityTraceFlagsTests() { Activity activity; // Set the 'Recorded' bit by using SetParentId with a -01 flags. activity = new Activity("activity1"); activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString()); Assert.True(IdIsW3CFormat(activity.Id)); Assert.Equal($"00-0123456789abcdef0123456789abcdef-{activity.SpanId.ToHexString()}-01", activity.Id); Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); Assert.True(activity.Recorded); activity.Stop(); // Set the 'Recorded' bit by using SetParentId by using the TraceId, SpanId, ActivityTraceFlags overload activity = new Activity("activity2"); ActivityTraceId activityTraceId = ActivityTraceId.CreateRandom(); activity.SetParentId(activityTraceId, ActivitySpanId.CreateRandom(), ActivityTraceFlags.Recorded); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.Equal(activityTraceId.ToHexString(), activity.TraceId.ToHexString()); Assert.True(IdIsW3CFormat(activity.Id)); Assert.Equal($"00-{activity.TraceId.ToHexString()}-{activity.SpanId.ToHexString()}-01", activity.Id); Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); Assert.True(activity.Recorded); activity.Stop(); /****************************************************/ // Set the 'Recorded' bit explicitly after the fact. activity = new Activity("activity3"); activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString()); Assert.True(IdIsW3CFormat(activity.Id)); Assert.Equal($"00-{activity.TraceId.ToHexString()}-{activity.SpanId.ToHexString()}-00", activity.Id); Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); Assert.False(activity.Recorded); activity.ActivityTraceFlags = ActivityTraceFlags.Recorded; Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); Assert.True(activity.Recorded); activity.Stop(); /****************************************************/ // Confirm that that flags are propagated to children. activity = new Activity("activity4"); activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"); activity.Start(); Assert.Equal(activity, Activity.Current); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString()); Assert.True(IdIsW3CFormat(activity.Id)); Assert.Equal($"00-{activity.TraceId.ToHexString()}-{activity.SpanId.ToHexString()}-01", activity.Id); Assert.Equal(ActivityTraceFlags.Recorded, activity.ActivityTraceFlags); Assert.True(activity.Recorded); // create a child var childActivity = new Activity("activity4Child"); childActivity.Start(); Assert.Equal(childActivity, Activity.Current); Assert.Equal("0123456789abcdef0123456789abcdef", childActivity.TraceId.ToHexString()); Assert.NotEqual(activity.SpanId.ToHexString(), childActivity.SpanId.ToHexString()); Assert.True(IdIsW3CFormat(childActivity.Id)); Assert.Equal($"00-{childActivity.TraceId.ToHexString()}-{childActivity.SpanId.ToHexString()}-01", childActivity.Id); Assert.Equal(ActivityTraceFlags.Recorded, childActivity.ActivityTraceFlags); Assert.True(childActivity.Recorded); childActivity.Stop(); activity.Stop(); }
public void IdFormatTests() { try { Activity activity; // Default format is the default (Hierarchical) activity = new Activity("activity1"); activity.Start(); Assert.Equal(ActivityIdFormat.Hierarchical, activity.IdFormat); activity.Stop(); // Set the parent to something that is W3C by string activity = new Activity("activity2"); activity.SetParentId("00-0123456789abcdef0123456789abcdef-0123456789abcdef-00"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); Assert.Equal("0123456789abcdef", activity.ParentSpanId.ToHexString()); Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); Assert.False(activity.Recorded); Assert.True(IdIsW3CFormat(activity.Id)); activity.Stop(); // Set the parent to something that is W3C but using ActivityTraceId,ActivitySpanId version of SetParentId. activity = new Activity("activity3"); ActivityTraceId activityTraceId = ActivityTraceId.CreateRandom(); activity.SetParentId(activityTraceId, ActivitySpanId.CreateRandom()); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.Equal(activityTraceId.ToHexString(), activity.TraceId.ToHexString()); Assert.Equal(ActivityTraceFlags.None, activity.ActivityTraceFlags); Assert.False(activity.Recorded); Assert.True(IdIsW3CFormat(activity.Id)); activity.Stop(); // Change DefaultIdFormat to W3C, confirm I get the new format. Activity.DefaultIdFormat = ActivityIdFormat.W3C; activity = new Activity("activity4"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.True(IdIsW3CFormat(activity.Id)); activity.Stop(); // But I don't get the default format if parent is hierarchical activity = new Activity("activity5"); string parentId = "|a000b421-5d183ab6.1"; activity.SetParentId(parentId); activity.Start(); Assert.Equal(ActivityIdFormat.Hierarchical, activity.IdFormat); Assert.True(activity.Id.StartsWith(parentId)); // Heirarchical Ids return null ActivityTraceId and ActivitySpanIds Assert.Equal("00000000000000000000000000000000", activity.TraceId.ToHexString()); Assert.Equal("0000000000000000", activity.SpanId.ToHexString()); activity.Stop(); // But if I set ForceDefaultFormat I get what I asked for (W3C format) Activity.ForceDefaultIdFormat = true; activity = new Activity("activity6"); activity.SetParentId(parentId); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.True(IdIsW3CFormat(activity.Id)); Assert.NotEqual("00000000000000000000000000000000", activity.TraceId.ToHexString()); Assert.NotEqual("0000000000000000", activity.SpanId.ToHexString()); /* TraceStateString testing */ // Test TraceStateString (that it inherits from parent) Activity parent = new Activity("parent"); string testString = "MyTestString"; parent.TraceStateString = testString; parent.Start(); Assert.Equal(testString, parent.TraceStateString); activity = new Activity("activity7"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.True(IdIsW3CFormat(activity.Id)); Assert.Equal(testString, activity.TraceStateString); // Update child string childTestString = "ChildTestString"; activity.TraceStateString = childTestString; // Confirm that child sees update, but parent does not Assert.Equal(childTestString, activity.TraceStateString); Assert.Equal(testString, parent.TraceStateString); // Update parent string parentTestString = "newTestString"; parent.TraceStateString = parentTestString; // Confirm that parent sees update but child does not. Assert.Equal(childTestString, activity.TraceStateString); Assert.Equal(parentTestString, parent.TraceStateString); activity.Stop(); parent.Stop(); // Upper-case ids are not supported activity = new Activity("activity8"); activity.SetParentId("00-0123456789ABCDEF0123456789ABCDEF-0123456789ABCDEF-01"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.True(IdIsW3CFormat(activity.Id)); activity.Stop(); // non hex chars are not supported in traceId activity = new Activity("activity9"); activity.SetParentId("00-xyz3456789abcdef0123456789abcdef-0123456789abcdef-01"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.True(IdIsW3CFormat(activity.Id)); activity.Stop(); // non hex chars are not supported in parentSpanId activity = new Activity("activity10"); activity.SetParentId("00-0123456789abcdef0123456789abcdef-x123456789abcdef-01"); activity.Start(); Assert.Equal(ActivityIdFormat.W3C, activity.IdFormat); Assert.True(IdIsW3CFormat(activity.Id)); Assert.Equal("0000000000000000", activity.ParentSpanId.ToHexString()); Assert.Equal("0123456789abcdef0123456789abcdef", activity.TraceId.ToHexString()); activity.Stop(); // ParentSpanId from parent Activity Activity.DefaultIdFormat = ActivityIdFormat.W3C; Activity.ForceDefaultIdFormat = true; parent = new Activity("parent").Start(); activity = new Activity("parent").Start(); Assert.Equal(parent.SpanId.ToHexString(), activity.ParentSpanId.ToHexString()); activity.Stop(); parent.Stop(); } finally { // Set global settings back to the default, just to put the state back. Activity.ForceDefaultIdFormat = false; Activity.DefaultIdFormat = ActivityIdFormat.Hierarchical; Activity.Current = null; } }
public void ActivityTraceIdTests() { Span <byte> idBytes1 = stackalloc byte[16]; Span <byte> idBytes2 = stackalloc byte[16]; // Empty Constructor string zeros = "00000000000000000000000000000000"; ActivityTraceId emptyId = new ActivityTraceId(); Assert.Equal(zeros, emptyId.ToHexString()); emptyId.CopyTo(idBytes1); Assert.Equal(new byte[16], idBytes1.ToArray()); Assert.True(emptyId == new ActivityTraceId()); Assert.True(!(emptyId != new ActivityTraceId())); Assert.True(emptyId.Equals(new ActivityTraceId())); Assert.True(emptyId.Equals((object)new ActivityTraceId())); Assert.Equal(new ActivityTraceId().GetHashCode(), emptyId.GetHashCode()); // NewActivityTraceId ActivityTraceId newId1 = ActivityTraceId.CreateRandom(); Assert.True(IsLowerCaseHex(newId1.ToHexString())); Assert.Equal(32, newId1.ToHexString().Length); ActivityTraceId newId2 = ActivityTraceId.CreateRandom(); Assert.Equal(32, newId1.ToHexString().Length); Assert.NotEqual(newId1.ToHexString(), newId2.ToHexString()); // Test equality Assert.True(newId1 != newId2); Assert.True(!(newId1 == newId2)); Assert.True(!(newId1.Equals(newId2))); Assert.True(!(newId1.Equals((object)newId2))); Assert.NotEqual(newId1.GetHashCode(), newId2.GetHashCode()); ActivityTraceId newId3 = ActivityTraceId.CreateFromString("00000000000000000000000000000001".AsSpan()); Assert.True(newId3 != emptyId); Assert.True(!(newId3 == emptyId)); Assert.True(!(newId3.Equals(emptyId))); Assert.True(!(newId3.Equals((object)emptyId))); Assert.NotEqual(newId3.GetHashCode(), emptyId.GetHashCode()); // Use in Dictionary (this does assume we have no collisions in IDs over 100 tries (very good). var dict = new Dictionary <ActivityTraceId, string>(); for (int i = 0; i < 100; i++) { var newId7 = ActivityTraceId.CreateRandom(); dict[newId7] = newId7.ToHexString(); } int ctr = 0; foreach (string value in dict.Values) { string valueInDict; Assert.True(dict.TryGetValue(ActivityTraceId.CreateFromString(value.AsSpan()), out valueInDict)); Assert.Equal(value, valueInDict); ctr++; } Assert.Equal(100, ctr); // We got out what we put in. // AsBytes and Byte constructor. newId2.CopyTo(idBytes2); ActivityTraceId newId2Clone = ActivityTraceId.CreateFromBytes(idBytes2); Assert.Equal(newId2.ToHexString(), newId2Clone.ToHexString()); newId2Clone.CopyTo(idBytes1); Assert.Equal(idBytes2.ToArray(), idBytes1.ToArray()); Assert.True(newId2 == newId2Clone); Assert.True(newId2.Equals(newId2Clone)); Assert.True(newId2.Equals((object)newId2Clone)); Assert.Equal(newId2.GetHashCode(), newId2Clone.GetHashCode()); // String constructor and ToHexString(). string idStr = "0123456789abcdef0123456789abcdef"; ActivityTraceId id = ActivityTraceId.CreateFromString(idStr.AsSpan()); Assert.Equal(idStr, id.ToHexString()); // Utf8 Constructor. byte[] idUtf8 = Encoding.UTF8.GetBytes(idStr); ActivityTraceId id1 = ActivityTraceId.CreateFromUtf8String(idUtf8); Assert.Equal(idStr, id1.ToHexString()); // ToString Assert.Equal(idStr, id.ToString()); }