Skip to content

Commit 60a3839

Browse files
ysolomchenkoKielek
andauthored
[Exporter.Zipkin] Update remote endpoint and remove the peer.service attribute (#6191)
Co-authored-by: Piotr Kiełkowicz <[email protected]>
1 parent 805dd6b commit 60a3839

11 files changed

+399
-336
lines changed

OpenTelemetry.sln

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A49299
254254
src\Shared\ExceptionExtensions.cs = src\Shared\ExceptionExtensions.cs
255255
src\Shared\Guard.cs = src\Shared\Guard.cs
256256
src\Shared\MathHelper.cs = src\Shared\MathHelper.cs
257-
src\Shared\PeerServiceResolver.cs = src\Shared\PeerServiceResolver.cs
258257
src\Shared\PeriodicExportingMetricReaderHelper.cs = src\Shared\PeriodicExportingMetricReaderHelper.cs
259258
src\Shared\PooledList.cs = src\Shared\PooledList.cs
260259
src\Shared\ResourceSemanticConventions.cs = src\Shared\ResourceSemanticConventions.cs

src/OpenTelemetry.Exporter.Zipkin/CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ Notes](../../RELEASENOTES.md).
66

77
## Unreleased
88

9+
* Removed the peer service resolver, which was based on earlier experimental
10+
semantic conventions that are not part of the stable specification. This
11+
change ensures that the exporter no longer modifies or assumes the value of
12+
peer service attributes.
13+
([#6191](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6191))
14+
15+
* Extended remote endpoint calculation to align with the [opentelemetry-specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.40.0/specification/trace/sdk_exporters/zipkin.md#otlp---zipkin).
16+
([#6191](https://github.com/open-telemetry/opentelemetry-dotnet/pull/6191))
17+
918
## 1.12.0
1019

1120
Released 2025-Apr-29
@@ -217,7 +226,7 @@ Released 2022-June-1
217226
([#3281](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3281))
218227
* Fix exporting of array-valued attributes on an `Activity`. Previously, each
219228
item in the array would result in a new tag on an exported `Activity`. Now,
220-
array-valued attributes are serialzed to a JSON-array representation.
229+
array-valued attributes are serialized to a JSON-array representation.
221230
([#3281](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3281))
222231

223232
## 1.3.0-beta.2

src/OpenTelemetry.Exporter.Zipkin/Implementation/ZipkinActivityConversionExtensions.cs

Lines changed: 215 additions & 154 deletions
Large diffs are not rendered by default.

src/OpenTelemetry.Exporter.Zipkin/OpenTelemetry.Exporter.Zipkin.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
<Compile Include="$(RepoRoot)\src\Shared\EnvironmentVariables\*.cs" Link="Includes\EnvironmentVariables\%(Filename).cs" />
1818
<Compile Include="$(RepoRoot)\src\Shared\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />
1919
<Compile Include="$(RepoRoot)\src\Shared\Options\*.cs" Link="Includes\Options\%(Filename).cs" />
20-
<Compile Include="$(RepoRoot)\src\Shared\PeerServiceResolver.cs" Link="Includes\PeerServiceResolver.cs" />
2120
<Compile Include="$(RepoRoot)\src\Shared\SemanticConventions.cs" Link="Includes\SemanticConventions.cs" />
2221
<Compile Include="$(RepoRoot)\src\Shared\Shims\NullableAttributes.cs" Link="Includes\Shims\NullableAttributes.cs" />
2322
<Compile Include="$(RepoRoot)\src\Shared\SpanAttributeConstants.cs" Link="Includes\SpanAttributeConstants.cs" />

src/Shared/PeerServiceResolver.cs

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/Shared/SemanticConventions.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,22 @@ internal static class SemanticConventions
2424
public const string AttributeExceptionType = "exception.type";
2525
public const string AttributeExceptionMessage = "exception.message";
2626
public const string AttributeExceptionStacktrace = "exception.stacktrace";
27+
28+
public const string AttributeServerAddress = "server.address";
29+
30+
public const string AttributeNetworkPeerAddress = "network.peer.address";
31+
public const string AttributeNetworkPeerPort = "network.peer.port";
32+
33+
public const string AttributeServerSocketDomain = "server.socket.domain";
34+
public const string AttributeServerSocketAddress = "server.socket.address";
35+
public const string AttributeServerSocketPort = "server.socket.port";
36+
37+
public const string AttributeNetSockPeerName = "net.sock.peer.name";
38+
public const string AttributeNetSockPeerAddr = "net.sock.peer.addr";
39+
public const string AttributeNetSockPeerPort = "net.sock.peer.port";
40+
41+
public const string AttributePeerHostname = "peer.hostname";
42+
public const string AttributePeerAddress = "peer.address";
43+
44+
public const string AttributeDbName = "db.name";
2745
}

test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/RemoteEndpointPriorityTestCase.cs

Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,83 +14,135 @@ public class RemoteEndpointPriorityTestCase
1414
[
1515
new()
1616
{
17-
Name = "Highest priority name = net.peer.name",
18-
ExpectedResult = "RemoteServiceName",
17+
Name = "Rank 1: Only peer.service provided",
18+
ExpectedResult = "PeerService",
1919
RemoteEndpointAttributes = new Dictionary<string, object>
2020
{
21-
["http.host"] = "DiscardedRemoteServiceName",
22-
["net.peer.name"] = "RemoteServiceName",
23-
["peer.hostname"] = "DiscardedRemoteServiceName",
21+
[SemanticConventions.AttributePeerService] = "PeerService",
2422
},
2523
},
2624
new()
2725
{
28-
Name = "Highest priority name = SemanticConventions.AttributePeerService",
29-
ExpectedResult = "RemoteServiceName",
26+
Name = "Rank 2: Only server.address provided",
27+
ExpectedResult = "ServerAddress",
3028
RemoteEndpointAttributes = new Dictionary<string, object>
3129
{
32-
[SemanticConventions.AttributePeerService] = "RemoteServiceName",
33-
["http.host"] = "DiscardedRemoteServiceName",
34-
["net.peer.name"] = "DiscardedRemoteServiceName",
35-
["net.peer.port"] = "1234",
36-
["peer.hostname"] = "DiscardedRemoteServiceName",
30+
[SemanticConventions.AttributeServerAddress] = "ServerAddress",
3731
},
3832
},
3933
new()
4034
{
41-
Name = "Only has net.peer.name and net.peer.port",
42-
ExpectedResult = "RemoteServiceName:1234",
35+
Name = "Rank 3: Only net.peer.name provided",
36+
ExpectedResult = "NetPeerName",
4337
RemoteEndpointAttributes = new Dictionary<string, object>
4438
{
45-
["net.peer.name"] = "RemoteServiceName",
46-
["net.peer.port"] = "1234",
39+
[SemanticConventions.AttributeNetPeerName] = "NetPeerName",
4740
},
4841
},
4942
new()
5043
{
51-
Name = "net.peer.port is an int",
52-
ExpectedResult = "RemoteServiceName:1234",
44+
Name = "Rank 4: network.peer.address and network.peer.port provided",
45+
ExpectedResult = "1.2.3.4:5678",
5346
RemoteEndpointAttributes = new Dictionary<string, object>
5447
{
55-
["net.peer.name"] = "RemoteServiceName",
56-
["net.peer.port"] = 1234,
48+
[SemanticConventions.AttributeNetworkPeerAddress] = "1.2.3.4",
49+
[SemanticConventions.AttributeNetworkPeerPort] = "5678",
5750
},
5851
},
5952
new()
6053
{
61-
Name = "Has net.peer.name and net.peer.port",
62-
ExpectedResult = "RemoteServiceName:1234",
54+
Name = "Rank 4: Only network.peer.address provided",
55+
ExpectedResult = "1.2.3.4",
6356
RemoteEndpointAttributes = new Dictionary<string, object>
6457
{
65-
["http.host"] = "DiscardedRemoteServiceName",
66-
["net.peer.name"] = "RemoteServiceName",
67-
["net.peer.port"] = "1234",
68-
["peer.hostname"] = "DiscardedRemoteServiceName",
58+
[SemanticConventions.AttributeNetworkPeerAddress] = "1.2.3.4",
6959
},
7060
},
7161
new()
7262
{
73-
Name = "Has net.peer.ip and net.peer.port",
74-
ExpectedResult = "1.2.3.4:1234",
63+
Name = "Rank 5: Only server.socket.domain provided",
64+
ExpectedResult = "SocketDomain",
7565
RemoteEndpointAttributes = new Dictionary<string, object>
7666
{
77-
["http.host"] = "DiscardedRemoteServiceName",
78-
["net.peer.ip"] = "1.2.3.4",
79-
["net.peer.port"] = "1234",
80-
["peer.hostname"] = "DiscardedRemoteServiceName",
67+
[SemanticConventions.AttributeServerSocketDomain] = "SocketDomain",
8168
},
8269
},
8370
new()
8471
{
85-
Name = "Has net.peer.name, net.peer.ip, and net.peer.port",
86-
ExpectedResult = "RemoteServiceName:1234",
72+
Name = "Rank 6: server.socket.address and server.socket.port provided",
73+
ExpectedResult = "SocketAddress:4321",
8774
RemoteEndpointAttributes = new Dictionary<string, object>
8875
{
89-
["http.host"] = "DiscardedRemoteServiceName",
90-
["net.peer.name"] = "RemoteServiceName",
91-
["net.peer.ip"] = "1.2.3.4",
92-
["net.peer.port"] = "1234",
93-
["peer.hostname"] = "DiscardedRemoteServiceName",
76+
[SemanticConventions.AttributeServerSocketAddress] = "SocketAddress",
77+
[SemanticConventions.AttributeServerSocketPort] = "4321",
78+
},
79+
},
80+
new()
81+
{
82+
Name = "Rank 7: Only net.sock.peer.name provided",
83+
ExpectedResult = "NetSockPeerName",
84+
RemoteEndpointAttributes = new Dictionary<string, object>
85+
{
86+
[SemanticConventions.AttributeNetSockPeerName] = "NetSockPeerName",
87+
},
88+
},
89+
new()
90+
{
91+
Name = "Rank 8: net.sock.peer.addr and net.sock.peer.port provided",
92+
ExpectedResult = "5.6.7.8:8765",
93+
RemoteEndpointAttributes = new Dictionary<string, object>
94+
{
95+
[SemanticConventions.AttributeNetSockPeerAddr] = "5.6.7.8",
96+
[SemanticConventions.AttributeNetSockPeerPort] = "8765",
97+
},
98+
},
99+
new()
100+
{
101+
Name = "Rank 9: Only peer.hostname provided",
102+
ExpectedResult = "PeerHostname",
103+
RemoteEndpointAttributes = new Dictionary<string, object>
104+
{
105+
[SemanticConventions.AttributePeerHostname] = "PeerHostname",
106+
},
107+
},
108+
new()
109+
{
110+
Name = "Rank 10: Only peer.address provided",
111+
ExpectedResult = "PeerAddress",
112+
RemoteEndpointAttributes = new Dictionary<string, object>
113+
{
114+
[SemanticConventions.AttributePeerAddress] = "PeerAddress",
115+
},
116+
},
117+
new()
118+
{
119+
Name = "Rank 11: Only db.name provided",
120+
ExpectedResult = "DbName",
121+
RemoteEndpointAttributes = new Dictionary<string, object>
122+
{
123+
[SemanticConventions.AttributeDbName] = "DbName",
124+
},
125+
},
126+
new()
127+
{
128+
Name = "Multiple attributes: highest rank wins",
129+
ExpectedResult = "PeerService",
130+
RemoteEndpointAttributes = new Dictionary<string, object>
131+
{
132+
[SemanticConventions.AttributeDbName] = "DbName",
133+
[SemanticConventions.AttributePeerAddress] = "PeerAddress",
134+
[SemanticConventions.AttributePeerHostname] = "PeerHostname",
135+
[SemanticConventions.AttributeNetSockPeerAddr] = "5.6.7.8",
136+
[SemanticConventions.AttributeNetSockPeerPort] = "8765",
137+
[SemanticConventions.AttributeNetSockPeerName] = "NetSockPeerName",
138+
[SemanticConventions.AttributeServerSocketAddress] = "SocketAddress",
139+
[SemanticConventions.AttributeServerSocketPort] = "4321",
140+
[SemanticConventions.AttributeServerSocketDomain] = "SocketDomain",
141+
[SemanticConventions.AttributeNetworkPeerAddress] = "1.2.3.4",
142+
[SemanticConventions.AttributeNetworkPeerPort] = "5678",
143+
[SemanticConventions.AttributeNetPeerName] = "NetPeerName",
144+
[SemanticConventions.AttributeServerAddress] = "ServerAddress",
145+
[SemanticConventions.AttributePeerService] = "PeerService",
94146
},
95147
},
96148
];

test/OpenTelemetry.Exporter.Zipkin.Tests/Implementation/ZipkinActivityConversionExtensionsTests.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System.Diagnostics;
55
using OpenTelemetry.Internal;
66
using Xunit;
7-
using static OpenTelemetry.Exporter.Zipkin.Implementation.ZipkinActivityConversionExtensions;
87

98
namespace OpenTelemetry.Exporter.Zipkin.Implementation.Tests;
109

@@ -17,18 +16,15 @@ public class ZipkinActivityConversionExtensionsTests
1716
[InlineData("double", 1.0)]
1817
public void CheckProcessTag(string key, object value)
1918
{
20-
var attributeEnumerationState = new TagEnumerationState
21-
{
22-
Tags = PooledList<KeyValuePair<string, object?>>.Create(),
23-
};
24-
2519
using var activity = new Activity("TestActivity");
2620
activity.SetTag(key, value);
2721

28-
attributeEnumerationState.EnumerateTags(activity);
22+
var tags = PooledList<KeyValuePair<string, object?>>.Create();
23+
ExtractTags(activity, ref tags);
2924

30-
Assert.Equal(key, attributeEnumerationState.Tags[0].Key);
31-
Assert.Equal(value, attributeEnumerationState.Tags[0].Value);
25+
var tag = Assert.Single(tags);
26+
Assert.Equal(key, tag.Key);
27+
Assert.Equal(value, tag.Value);
3228
}
3329

3430
[Theory]
@@ -38,16 +34,23 @@ public void CheckProcessTag(string key, object value)
3834
[InlineData("double", null)]
3935
public void CheckNullValueProcessTag(string key, object? value)
4036
{
41-
var attributeEnumerationState = new TagEnumerationState
42-
{
43-
Tags = PooledList<KeyValuePair<string, object?>>.Create(),
44-
};
45-
4637
using var activity = new Activity("TestActivity");
4738
activity.SetTag(key, value);
4839

49-
attributeEnumerationState.EnumerateTags(activity);
40+
var tags = PooledList<KeyValuePair<string, object?>>.Create();
41+
ExtractTags(activity, ref tags);
5042

51-
Assert.Empty(attributeEnumerationState.Tags);
43+
Assert.Empty(tags);
44+
}
45+
46+
private static void ExtractTags(Activity activity, ref PooledList<KeyValuePair<string, object?>> tags)
47+
{
48+
foreach (var tag in activity.TagObjects)
49+
{
50+
if (tag.Value != null)
51+
{
52+
PooledList<KeyValuePair<string, object?>>.Add(ref tags, new KeyValuePair<string, object?>(tag.Key, tag.Value));
53+
}
54+
}
5255
}
5356
}

0 commit comments

Comments
 (0)