Skip to content

Commit

Permalink
[shared] Use CultureInfo.InvariantCulture in TagWriter (#5700)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeBlanch authored Jun 18, 2024
1 parent b1a21cc commit 4af3df9
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 6 deletions.
5 changes: 5 additions & 0 deletions src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

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

## 1.9.0

Released 2024-Jun-14
Expand Down
4 changes: 4 additions & 0 deletions src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

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

## 1.9.0

Released 2024-Jun-14
Expand Down
5 changes: 3 additions & 2 deletions src/Shared/TagWriter/TagWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#nullable enable

using System.Diagnostics;
using System.Globalization;

namespace OpenTelemetry.Internal;

Expand Down Expand Up @@ -82,7 +83,7 @@ public bool TryWriteTag(
default:
try
{
var stringValue = Convert.ToString(tag.Value/*TODO: , CultureInfo.InvariantCulture*/);
var stringValue = Convert.ToString(tag.Value, CultureInfo.InvariantCulture);
if (stringValue == null)
{
return this.LogUnsupportedTagTypeAndReturnFalse(tag.Key, tag.Value);
Expand Down Expand Up @@ -247,7 +248,7 @@ private void WriteToArrayTypeChecked(ref TArrayState arrayState, Array array, in
// case ulong: May throw an exception on overflow.
// case decimal: Converting to double produces rounding errors.
default:
var stringValue = Convert.ToString(item/*TODO: , CultureInfo.InvariantCulture*/);
var stringValue = Convert.ToString(item, CultureInfo.InvariantCulture);
if (stringValue == null)
{
this.arrayWriter.WriteNullValue(ref arrayState);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Globalization;
using Google.Protobuf.Collections;
using Xunit;
using OtlpCommon = OpenTelemetry.Proto.Common.V1;
Expand Down Expand Up @@ -110,7 +111,7 @@ private static void AssertOtlpAttributeValue(object expected, OtlpCommon.AnyValu
Assert.Equal(i, actual.IntValue);
break;
default:
Assert.Equal(expected.ToString(), actual.StringValue);
Assert.Equal(Convert.ToString(expected, CultureInfo.InvariantCulture), actual.StringValue);
break;
}
}
Expand Down
41 changes: 38 additions & 3 deletions test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Concurrent;
using System.Diagnostics;
using System.Globalization;
using System.Net;
#if NETFRAMEWORK
using System.Net.Http;
Expand Down Expand Up @@ -358,7 +359,8 @@ public void IntegrationTest(
var serviceName = (string)exporter.ParentProvider.GetDefaultResource().Attributes
.Where(pair => pair.Key == ResourceSemanticConventions.AttributeServiceName).FirstOrDefault().Value;
var resourceTags = string.Empty;
var activity = CreateTestActivity(isRootSpan: isRootSpan, status: status);
var dateTime = DateTime.UtcNow;
var activity = CreateTestActivity(isRootSpan: isRootSpan, status: status, dateTime: dateTime);
if (useTestResource)
{
serviceName = "MyService";
Expand Down Expand Up @@ -422,7 +424,35 @@ public void IntegrationTest(
}

Assert.Equal(
$@"[{{""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/""}}}}]",
$@"[{{""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/"","
+ $@"""dateTimeKey"":""{Convert.ToString(dateTime, CultureInfo.InvariantCulture)}"","
+ $@"""dateTimeArrayKey"":""[\u0022{Convert.ToString(dateTime, CultureInfo.InvariantCulture)}\u0022]"","
+ statusTag
+ errorTag
+ @"""otel.scope.name"":""CreateTestActivity"","
+ @"""otel.library.name"":""CreateTestActivity"","
+ @"""peer.service"":""http://localhost:44312/"""
+ "}}]",
Responses[requestId]);
}

Expand All @@ -434,13 +464,16 @@ internal static Activity CreateTestActivity(
bool addLinks = true,
Resource resource = null,
ActivityKind kind = ActivityKind.Client,
Status? status = null)
Status? status = null,
DateTime? dateTime = null)
{
var startTimestamp = DateTime.UtcNow;
var endTimestamp = startTimestamp.AddSeconds(60);
var eventTimestamp = DateTime.UtcNow;
var traceId = ActivityTraceId.CreateFromString("e8ea7e9ac72de94e91fabc613f9686b2".AsSpan());

dateTime ??= DateTime.UtcNow;

var parentSpanId = isRootSpan ? default : ActivitySpanId.CreateFromBytes(new byte[] { 12, 23, 34, 45, 56, 67, 78, 89 });

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

0 comments on commit 4af3df9

Please sign in to comment.