Skip to content

Commit 4af3df9

Browse files
authored
[shared] Use CultureInfo.InvariantCulture in TagWriter (#5700)
1 parent b1a21cc commit 4af3df9

File tree

5 files changed

+52
-6
lines changed

5 files changed

+52
-6
lines changed

src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Unreleased
44

5+
* **Breaking change**: Non-primitive attribute (logs) and tag (traces) values
6+
converted using `Convert.ToString` will now format using
7+
`CultureInfo.InvariantCulture`.
8+
([#5700](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5700))
9+
510
## 1.9.0
611

712
Released 2024-Jun-14

src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
* **Breaking change**: Non-primitive tag values converted using
6+
`Convert.ToString` will now format using `CultureInfo.InvariantCulture`.
7+
([#5700](https://github.com/open-telemetry/opentelemetry-dotnet/pull/5700))
8+
59
## 1.9.0
610

711
Released 2024-Jun-14

src/Shared/TagWriter/TagWriter.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#nullable enable
55

66
using System.Diagnostics;
7+
using System.Globalization;
78

89
namespace OpenTelemetry.Internal;
910

@@ -82,7 +83,7 @@ public bool TryWriteTag(
8283
default:
8384
try
8485
{
85-
var stringValue = Convert.ToString(tag.Value/*TODO: , CultureInfo.InvariantCulture*/);
86+
var stringValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture);
8687
if (stringValue == null)
8788
{
8889
return this.LogUnsupportedTagTypeAndReturnFalse(tag.Key, tag.Value);
@@ -247,7 +248,7 @@ private void WriteToArrayTypeChecked(ref TArrayState arrayState, Array array, in
247248
// case ulong: May throw an exception on overflow.
248249
// case decimal: Converting to double produces rounding errors.
249250
default:
250-
var stringValue = Convert.ToString(item/*TODO: , CultureInfo.InvariantCulture*/);
251+
var stringValue = Convert.ToString(item, CultureInfo.InvariantCulture);
251252
if (stringValue == null)
252253
{
253254
this.arrayWriter.WriteNullValue(ref arrayState);

test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpTestHelpers.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4+
using System.Globalization;
45
using Google.Protobuf.Collections;
56
using Xunit;
67
using OtlpCommon = OpenTelemetry.Proto.Common.V1;
@@ -110,7 +111,7 @@ private static void AssertOtlpAttributeValue(object expected, OtlpCommon.AnyValu
110111
Assert.Equal(i, actual.IntValue);
111112
break;
112113
default:
113-
Assert.Equal(expected.ToString(), actual.StringValue);
114+
Assert.Equal(Convert.ToString(expected, CultureInfo.InvariantCulture), actual.StringValue);
114115
break;
115116
}
116117
}

test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs

+38-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Concurrent;
55
using System.Diagnostics;
6+
using System.Globalization;
67
using System.Net;
78
#if NETFRAMEWORK
89
using System.Net.Http;
@@ -358,7 +359,8 @@ public void IntegrationTest(
358359
var serviceName = (string)exporter.ParentProvider.GetDefaultResource().Attributes
359360
.Where(pair => pair.Key == ResourceSemanticConventions.AttributeServiceName).FirstOrDefault().Value;
360361
var resourceTags = string.Empty;
361-
var activity = CreateTestActivity(isRootSpan: isRootSpan, status: status);
362+
var dateTime = DateTime.UtcNow;
363+
var activity = CreateTestActivity(isRootSpan: isRootSpan, status: status, dateTime: dateTime);
362364
if (useTestResource)
363365
{
364366
serviceName = "MyService";
@@ -422,7 +424,35 @@ public void IntegrationTest(
422424
}
423425

424426
Assert.Equal(
425-
$@"[{{""traceId"":""{traceId}"",""name"":""Name"",{parentId}""id"":""{ZipkinActivityConversionExtensions.EncodeSpanId(context.SpanId)}"",""kind"":""CLIENT"",""timestamp"":{timestamp},""duration"":60000000,""localEndpoint"":{{""serviceName"":""{serviceName}""{ipInformation}}},""remoteEndpoint"":{{""serviceName"":""http://localhost:44312/""}},""annotations"":[{{""timestamp"":{eventTimestamp},""value"":""Event1""}},{{""timestamp"":{eventTimestamp},""value"":""Event2""}}],""tags"":{{{resourceTags}""stringKey"":""value"",""longKey"":""1"",""longKey2"":""1"",""doubleKey"":""1"",""doubleKey2"":""1"",""longArrayKey"":""[1,2]"",""boolKey"":""true"",""boolArrayKey"":""[true,false]"",""http.host"":""http://localhost:44312/"",{statusTag}{errorTag}""otel.scope.name"":""CreateTestActivity"",""otel.library.name"":""CreateTestActivity"",""peer.service"":""http://localhost:44312/""}}}}]",
427+
$@"[{{""traceId"":""{traceId}"","
428+
+ @"""name"":""Name"","
429+
+ parentId
430+
+ $@"""id"":""{ZipkinActivityConversionExtensions.EncodeSpanId(context.SpanId)}"","
431+
+ @"""kind"":""CLIENT"","
432+
+ $@"""timestamp"":{timestamp},"
433+
+ @"""duration"":60000000,"
434+
+ $@"""localEndpoint"":{{""serviceName"":""{serviceName}""{ipInformation}}},"
435+
+ @"""remoteEndpoint"":{""serviceName"":""http://localhost:44312/""},"
436+
+ $@"""annotations"":[{{""timestamp"":{eventTimestamp},""value"":""Event1""}},{{""timestamp"":{eventTimestamp},""value"":""Event2""}}],"
437+
+ @"""tags"":{"
438+
+ resourceTags
439+
+ $@"""stringKey"":""value"","
440+
+ @"""longKey"":""1"","
441+
+ @"""longKey2"":""1"","
442+
+ @"""doubleKey"":""1"","
443+
+ @"""doubleKey2"":""1"","
444+
+ @"""longArrayKey"":""[1,2]"","
445+
+ @"""boolKey"":""true"","
446+
+ @"""boolArrayKey"":""[true,false]"","
447+
+ @"""http.host"":""http://localhost:44312/"","
448+
+ $@"""dateTimeKey"":""{Convert.ToString(dateTime, CultureInfo.InvariantCulture)}"","
449+
+ $@"""dateTimeArrayKey"":""[\u0022{Convert.ToString(dateTime, CultureInfo.InvariantCulture)}\u0022]"","
450+
+ statusTag
451+
+ errorTag
452+
+ @"""otel.scope.name"":""CreateTestActivity"","
453+
+ @"""otel.library.name"":""CreateTestActivity"","
454+
+ @"""peer.service"":""http://localhost:44312/"""
455+
+ "}}]",
426456
Responses[requestId]);
427457
}
428458

@@ -434,13 +464,16 @@ internal static Activity CreateTestActivity(
434464
bool addLinks = true,
435465
Resource resource = null,
436466
ActivityKind kind = ActivityKind.Client,
437-
Status? status = null)
467+
Status? status = null,
468+
DateTime? dateTime = null)
438469
{
439470
var startTimestamp = DateTime.UtcNow;
440471
var endTimestamp = startTimestamp.AddSeconds(60);
441472
var eventTimestamp = DateTime.UtcNow;
442473
var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());
443474

475+
dateTime ??= DateTime.UtcNow;
476+
444477
var parentSpanId = isRootSpan ? default : ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });
445478

446479
var attributes = new Dictionary<string, object>
@@ -454,6 +487,8 @@ internal static Activity CreateTestActivity(
454487
{ "boolKey", true },
455488
{ "boolArrayKey", new bool[] { true, false } },
456489
{ "http.host", "http://localhost:44312/" }, // simulating instrumentation tag adding http.host
490+
{ "dateTimeKey", dateTime.Value },
491+
{ "dateTimeArrayKey", new DateTime[] { dateTime.Value } },
457492
};
458493
if (additionalAttributes != null)
459494
{

0 commit comments

Comments
 (0)