Skip to content

Commit 333d0e2

Browse files
committed
Optimize the handling of OTel tags in OtlpHelpers.AgentConvertSpan to reduce allocations
1 parent 3aab3de commit 333d0e2

File tree

12 files changed

+524
-978
lines changed

12 files changed

+524
-978
lines changed

tracer/src/Datadog.Trace/Activity/OperationNameMapper.cs

Lines changed: 70 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#nullable enable
77
using System;
8+
using Datadog.Trace.SourceGenerators;
89
using Datadog.Trace.Tagging;
910

1011
namespace Datadog.Trace.Activity
@@ -14,15 +15,14 @@ namespace Datadog.Trace.Activity
1415
/// </summary>
1516
internal static class OperationNameMapper
1617
{
18+
[TestingOnly]
1719
internal static void MapToOperationName(Span span)
1820
{
1921
if (!string.IsNullOrEmpty(span.OperationName))
2022
{
2123
return; // if OperationName has a value it means there was an "operation.name" tag
2224
}
2325

24-
string operationName;
25-
2626
if (span.Tags is not OpenTelemetryTags tags)
2727
{
2828
// while span.Tags can be something other than OpenTelemetryTags the
@@ -32,127 +32,99 @@ internal static void MapToOperationName(Span span)
3232
return;
3333
}
3434

35-
if (tags.IsHttpServer())
36-
{
37-
operationName = "http.server.request";
38-
}
39-
else if (tags.IsHttpClient())
35+
span.OperationName = GetOperationName(tags);
36+
}
37+
38+
internal static string GetOperationName(OpenTelemetryTags tags)
39+
{
40+
var httpRequestMethod = tags.GetTag("http.request.method");
41+
if (tags.SpanKind == SpanKinds.Server && !string.IsNullOrEmpty(httpRequestMethod))
4042
{
41-
operationName = "http.client.request";
43+
// IsHttpServer
44+
return "http.server.request";
4245
}
43-
else if (tags.IsDatabase())
46+
47+
if (tags.SpanKind == SpanKinds.Client && !string.IsNullOrEmpty(httpRequestMethod))
4448
{
45-
operationName = $"{tags.DbSystem}.query";
49+
// IsHttpClient
50+
return "http.client.request";
4651
}
47-
else if (tags.IsMessaging())
52+
53+
var dbSystem = tags.GetTag("db.system");
54+
if (tags.SpanKind == SpanKinds.Client && !StringUtil.IsNullOrEmpty(dbSystem))
4855
{
49-
operationName = $"{tags.MessagingSystem}.{tags.MessagingOperation}";
56+
// IsDatabase
57+
return $"{dbSystem.ToLowerInvariant()}.query";
5058
}
51-
else if (tags.IsAwsClient())
59+
60+
var messagingSystem = tags.GetTag(Tags.MessagingSystem);
61+
var messagingOperation = tags.GetTag(Tags.MessagingOperation);
62+
if (tags.SpanKind is SpanKinds.Client or SpanKinds.Server or SpanKinds.Producer or SpanKinds.Consumer
63+
&& !StringUtil.IsNullOrEmpty(messagingSystem) &&
64+
!StringUtil.IsNullOrEmpty(messagingOperation))
5265
{
53-
operationName = !string.IsNullOrEmpty(tags.RpcService) ? $"aws.{tags.RpcService}.request" : "aws.client.request";
66+
// IsMessaging
67+
return $"{messagingSystem}.{messagingOperation}".ToLowerInvariant();
5468
}
55-
else if (tags.IsRpcClient())
69+
70+
var rpcSystem = tags.GetTag(Tags.RpcSystem);
71+
if (tags.SpanKind == SpanKinds.Client && string.Equals(rpcSystem, "aws-api", StringComparison.OrdinalIgnoreCase))
5672
{
57-
operationName = $"{tags.RpcSystem}.client.request";
73+
// IsAwsClient
74+
var service = tags.GetTag(Tags.RpcService)?.ToLowerInvariant();
75+
return !StringUtil.IsNullOrEmpty(service) ? $"aws.{service}.request" : "aws.client.request";
5876
}
59-
else if (tags.IsRpcServer())
77+
78+
if (tags.SpanKind == SpanKinds.Client && !StringUtil.IsNullOrEmpty(rpcSystem))
6079
{
61-
operationName = $"{tags.RpcSystem}.server.request";
80+
// IsRpcClient
81+
return $"{rpcSystem.ToLowerInvariant()}.client.request";
6282
}
63-
else if (tags.IsFaasServer())
83+
84+
if (tags.SpanKind == SpanKinds.Server && !StringUtil.IsNullOrEmpty(rpcSystem))
6485
{
65-
operationName = $"{tags.FaasTrigger}.invoke";
86+
// IsRpcServer
87+
return $"{rpcSystem.ToLowerInvariant()}.server.request";
6688
}
67-
else if (tags.IsFaasClient())
89+
90+
var faasTrigger = tags.GetTag("faas.trigger");
91+
if (tags.SpanKind == SpanKinds.Server && !StringUtil.IsNullOrEmpty(faasTrigger))
6892
{
69-
operationName = $"{tags.FaasInvokedProvider}.{tags.FaasInvokedName}.invoke";
93+
// IsFaasServer
94+
return $"{faasTrigger.ToLowerInvariant()}.invoke";
7095
}
71-
else if (tags.IsGraphQLServer())
96+
97+
var faasInvokedProvider = tags.GetTag("faas.invoked_provider");
98+
var faasInvokedName = tags.GetTag("faas.invoked_name");
99+
if (tags.SpanKind == SpanKinds.Client && !StringUtil.IsNullOrEmpty(faasInvokedProvider) && !StringUtil.IsNullOrEmpty(faasInvokedName))
72100
{
73-
operationName = "graphql.server.request";
101+
// IsFaasClient
102+
return $"{faasInvokedProvider}.{faasInvokedName}.invoke".ToLowerInvariant();
74103
}
75-
else if (tags.IsGenericServer())
104+
105+
if (tags.SpanKind == SpanKinds.Server && !StringUtil.IsNullOrEmpty(tags.GetTag("graphql.operation.type")))
76106
{
77-
operationName = !string.IsNullOrEmpty(tags.NetworkProtocolName) ? $"{tags.NetworkProtocolName}.server.request" : "server.request";
107+
// IsGraphQLServer
108+
return "graphql.server.request";
78109
}
79-
else if (tags.IsGenericClient())
110+
111+
if (tags.SpanKind == SpanKinds.Server)
80112
{
81-
operationName = !string.IsNullOrEmpty(tags.NetworkProtocolName) ? $"{tags.NetworkProtocolName}.client.request" : "client.request";
113+
// IsGenericServer
114+
var name = tags.GetTag("network.protocol.name");
115+
return !StringUtil.IsNullOrEmpty(name) ? $"{name.ToLowerInvariant()}.server.request" : "server.request";
82116
}
83-
else
117+
118+
if (tags.SpanKind == SpanKinds.Client)
84119
{
85-
// when there is no SpanKind defined (possible on Activity objects without "Kind")
86-
// fallback to using "internal" for the name.
87-
operationName = !string.IsNullOrEmpty(tags.SpanKind) ? tags.SpanKind : SpanKinds.Internal;
120+
// IsGenericClient
121+
var name = tags.GetTag("network.protocol.name");
122+
return !StringUtil.IsNullOrEmpty(name) ? $"{name.ToLowerInvariant()}.client.request" : "client.request";
88123
}
89124

90-
span.OperationName = operationName.ToLowerInvariant();
91-
}
92-
93-
private static bool IsHttpServer(this OpenTelemetryTags tags)
94-
{
95-
return tags.SpanKind == SpanKinds.Server && !string.IsNullOrEmpty(tags.HttpRequestMethod);
96-
}
97-
98-
private static bool IsHttpClient(this OpenTelemetryTags tags)
99-
{
100-
return tags.SpanKind == SpanKinds.Client && !string.IsNullOrEmpty(tags.HttpRequestMethod);
101-
}
102-
103-
private static bool IsDatabase(this OpenTelemetryTags tags)
104-
{
105-
return tags.SpanKind == SpanKinds.Client && !string.IsNullOrEmpty(tags.DbSystem);
106-
}
107-
108-
private static bool IsMessaging(this OpenTelemetryTags tags)
109-
{
110-
return (tags.SpanKind == SpanKinds.Client ||
111-
tags.SpanKind == SpanKinds.Server ||
112-
tags.SpanKind == SpanKinds.Producer ||
113-
tags.SpanKind == SpanKinds.Consumer)
114-
&& !string.IsNullOrEmpty(tags.MessagingSystem) &&
115-
!string.IsNullOrEmpty(tags.MessagingOperation);
116-
}
117-
118-
private static bool IsAwsClient(this OpenTelemetryTags tags)
119-
{
120-
return tags.SpanKind == SpanKinds.Client && string.Equals(tags.RpcSystem, "aws-api", StringComparison.OrdinalIgnoreCase);
121-
}
122-
123-
private static bool IsRpcClient(this OpenTelemetryTags tags)
124-
{
125-
return tags.SpanKind == SpanKinds.Client && !string.IsNullOrEmpty(tags.RpcSystem);
126-
}
127-
128-
private static bool IsRpcServer(this OpenTelemetryTags tags)
129-
{
130-
return tags.SpanKind == SpanKinds.Server && !string.IsNullOrEmpty(tags.RpcSystem);
131-
}
132-
133-
private static bool IsFaasServer(this OpenTelemetryTags tags)
134-
{
135-
return tags.SpanKind == SpanKinds.Server && !string.IsNullOrEmpty(tags.FaasTrigger);
136-
}
137-
138-
private static bool IsFaasClient(this OpenTelemetryTags tags)
139-
{
140-
return tags.SpanKind == SpanKinds.Client && !string.IsNullOrEmpty(tags.FaasInvokedProvider) && !string.IsNullOrEmpty(tags.FaasInvokedName);
141-
}
142-
143-
private static bool IsGraphQLServer(this OpenTelemetryTags tags)
144-
{
145-
return tags.SpanKind == SpanKinds.Server && !string.IsNullOrEmpty(tags.GraphQlOperationType);
146-
}
147-
148-
private static bool IsGenericServer(this OpenTelemetryTags tags)
149-
{
150-
return tags.SpanKind == SpanKinds.Server;
151-
}
152-
153-
private static bool IsGenericClient(this OpenTelemetryTags tags)
154-
{
155-
return tags.SpanKind == SpanKinds.Client;
125+
// when there is no SpanKind defined (possible on Activity objects without "Kind")
126+
// fallback to using "internal" for the name.
127+
return !StringUtil.IsNullOrEmpty(tags.SpanKind) ? tags.SpanKind.ToLowerInvariant() : SpanKinds.Internal;
156128
}
157129
}
158130
}

0 commit comments

Comments
 (0)