diff --git a/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerActivityExtensions.cs b/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerActivityExtensions.cs index 90760e736d1..2f0a33f79e2 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerActivityExtensions.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/Implementation/JaegerActivityExtensions.cs @@ -257,6 +257,42 @@ public static long ToEpochMicroseconds(this DateTimeOffset timestamp) return microseconds - UnixEpochMicroseconds; } + private static void ProcessJaegerTagArray(ref PooledList tags, KeyValuePair activityTag) + { + if (activityTag.Value is int[] intArray) + { + foreach (var item in intArray) + { + JaegerTag jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.LONG, vLong: Convert.ToInt64(item)); + PooledList.Add(ref tags, jaegerTag); + } + } + else if (activityTag.Value is string[] stringArray) + { + foreach (var item in stringArray) + { + JaegerTag jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.STRING, vStr: item); + PooledList.Add(ref tags, jaegerTag); + } + } + else if (activityTag.Value is bool[] boolArray) + { + foreach (var item in boolArray) + { + JaegerTag jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.BOOL, vBool: item); + PooledList.Add(ref tags, jaegerTag); + } + } + else if (activityTag.Value is double[] doubleArray) + { + foreach (var item in doubleArray) + { + JaegerTag jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.DOUBLE, vDouble: item); + PooledList.Add(ref tags, jaegerTag); + } + } + } + private static void ProcessJaegerTag(ref TagState state, string key, JaegerTag jaegerTag) { if (jaegerTag.VStr != null) @@ -315,7 +351,15 @@ private static bool ProcessActivityEvent(ref PooledListState state, A private static bool ProcessTag(ref PooledListState state, KeyValuePair attribute) { - PooledList.Add(ref state.List, attribute.ToJaegerTag()); + if (attribute.Value is Array) + { + ProcessJaegerTagArray(ref state.List, attribute); + } + else if (attribute.Value != null) + { + PooledList.Add(ref state.List, attribute.ToJaegerTag()); + } + return true; } @@ -335,43 +379,13 @@ private struct TagState : IActivityTagEnumerator public bool ForEach(KeyValuePair activityTag) { - JaegerTag jaegerTag; - if (activityTag.Value is int[] intArray) - { - foreach (var item in intArray) - { - jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.LONG, vLong: Convert.ToInt64(item)); - ProcessJaegerTag(ref this, activityTag.Key, jaegerTag); - } - } - else if (activityTag.Value is string[] stringArray) - { - foreach (var item in stringArray) - { - jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.STRING, vStr: item); - ProcessJaegerTag(ref this, activityTag.Key, jaegerTag); - } - } - else if (activityTag.Value is bool[] boolArray) - { - foreach (var item in boolArray) - { - jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.BOOL, vBool: item); - ProcessJaegerTag(ref this, activityTag.Key, jaegerTag); - } - } - else if (activityTag.Value is double[] doubleArray) + if (activityTag.Value is Array) { - foreach (var item in doubleArray) - { - jaegerTag = new JaegerTag(activityTag.Key, JaegerTagType.DOUBLE, vDouble: item); - ProcessJaegerTag(ref this, activityTag.Key, jaegerTag); - } + ProcessJaegerTagArray(ref this.Tags, activityTag); } - else + else if (activityTag.Value != null) { - jaegerTag = activityTag.ToJaegerTag(); - ProcessJaegerTag(ref this, activityTag.Key, jaegerTag); + ProcessJaegerTag(ref this, activityTag.Key, activityTag.ToJaegerTag()); } return true; diff --git a/test/OpenTelemetry.Exporter.Jaeger.Tests/Implementation/JaegerActivityConversionTest.cs b/test/OpenTelemetry.Exporter.Jaeger.Tests/Implementation/JaegerActivityConversionTest.cs index c1c211c2db5..8f9ecca0ad7 100644 --- a/test/OpenTelemetry.Exporter.Jaeger.Tests/Implementation/JaegerActivityConversionTest.cs +++ b/test/OpenTelemetry.Exporter.Jaeger.Tests/Implementation/JaegerActivityConversionTest.cs @@ -101,12 +101,18 @@ public void JaegerActivityConverterTest_ConvertActivityToJaegerSpan_AllPropertie var logs = jaegerSpan.Logs.ToArray(); var jaegerLog = logs[0]; Assert.Equal(activity.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); - Assert.Equal(2, jaegerLog.Fields.Count()); + Assert.Equal(4, jaegerLog.Fields.Count()); var eventFields = jaegerLog.Fields.ToArray(); var eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); eventField = eventFields[1]; + Assert.Equal("string_array", eventField.Key); + Assert.Equal("a", eventField.VStr); + eventField = eventFields[2]; + Assert.Equal("string_array", eventField.Key); + Assert.Equal("b", eventField.VStr); + eventField = eventFields[3]; Assert.Equal("message", eventField.Key); Assert.Equal("Event1", eventField.VStr); @@ -160,12 +166,12 @@ public void JaegerActivityConverterTest_ConvertActivityToJaegerSpan_NoAttributes var logs = jaegerSpan.Logs.ToArray(); var jaegerLog = logs[0]; Assert.Equal(activity.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); - Assert.Equal(2, jaegerLog.Fields.Count()); + Assert.Equal(4, jaegerLog.Fields.Count()); var eventFields = jaegerLog.Fields.ToArray(); var eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); - eventField = eventFields[1]; + eventField = eventFields[3]; Assert.Equal("message", eventField.Key); Assert.Equal("Event1", eventField.VStr); @@ -325,12 +331,12 @@ public void JaegerActivityConverterTest_ConvertActivityToJaegerSpan_NoLinks() var logs = jaegerSpan.Logs.ToArray(); var jaegerLog = logs[0]; Assert.Equal(activity.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); - Assert.Equal(2, jaegerLog.Fields.Count()); + Assert.Equal(4, jaegerLog.Fields.Count()); var eventFields = jaegerLog.Fields.ToArray(); var eventField = eventFields[0]; Assert.Equal("key", eventField.Key); Assert.Equal("value", eventField.VStr); - eventField = eventFields[1]; + eventField = eventFields[3]; Assert.Equal("message", eventField.Key); Assert.Equal("Event1", eventField.VStr); Assert.Equal(activity.Events.First().Timestamp.ToEpochMicroseconds(), jaegerLog.Timestamp); @@ -413,6 +419,19 @@ public void JaegerActivityConverterTest_GenerateJaegerSpan_RemoteEndpointResolut Assert.Equal(testCase.ExpectedResult, tag.VStr); } + [Fact] + public void JaegerActivityConverterTest_NullTagValueTest() + { + // Arrange + var activity = CreateTestActivity(additionalAttributes: new Dictionary { ["nullTag"] = null }); + + // Act + var jaegerSpan = activity.ToJaegerSpan(); + + // Assert + Assert.DoesNotContain(jaegerSpan.Tags, t => t.Key == "nullTag"); + } + internal static Activity CreateTestActivity( bool setAttributes = true, Dictionary additionalAttributes = null, @@ -457,6 +476,7 @@ internal static Activity CreateTestActivity( new ActivityTagsCollection(new Dictionary { { "key", "value" }, + { "string_array", new string[] { "a", "b" } }, })), new ActivityEvent( "Event2",