Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tracer] Set _dd.base_service tag whenever a span's service name is different than the default value (DD_SERVICE) #5502

Merged
merged 31 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
800c97a
Set _dd.base_service correctly
bouwkast Apr 26, 2024
69180a5
Update tests
bouwkast Apr 30, 2024
526c17c
Fix TagsListTests
bouwkast May 2, 2024
368dc8a
Update snapshots
bouwkast May 2, 2024
a253344
Add missing _dd.base_service to meta data rules
bouwkast May 2, 2024
0fdf93c
Update more snapshots
bouwkast May 2, 2024
b273b2d
Update the smoke test snapshots
bouwkast May 2, 2024
84bad6c
Properly dispose of the tracer in test
bouwkast May 3, 2024
87d74fc
Revert to using a mock
bouwkast May 3, 2024
269cea7
Update snapshots
bouwkast May 30, 2024
a4ce52e
Update snapshot
bouwkast Sep 24, 2024
6218341
Cache model.TraceChunk.DefaultServiceName
bouwkast Sep 25, 2024
16134e9
Check for default service name in TagsListTests
bouwkast Sep 25, 2024
9292f30
Fix OldMySql tests
bouwkast Sep 26, 2024
fec904a
Update MySqlCommandTests snapshots
bouwkast Sep 26, 2024
c0a2a7f
Remove no longer updated/used MySqlCommandTests snapshots
bouwkast Sep 26, 2024
75fd8c9
Update untagged NpgsqlCommandTests snapshots
bouwkast Sep 26, 2024
81d8796
Add missing NpgsqlCommandTests snapshots
bouwkast Sep 26, 2024
3f5473d
Update SQS .NET Framework snapshots
bouwkast Sep 26, 2024
300abc1
Update SNS snapshots
bouwkast Sep 26, 2024
6d88067
Add missing SNS snapshots
bouwkast Sep 26, 2024
c075fec
Update Kinesis snapshots
bouwkast Sep 26, 2024
93de148
Ignore .localstack directory
bouwkast Sep 26, 2024
be1b8ac
Update AwsDynamoDbTests snapshots
bouwkast Sep 26, 2024
f6b856a
Remove SystemDataSqlClientTests snapshots no longer created
bouwkast Sep 26, 2024
62cc006
Update Oracle test snapshots
bouwkast Sep 26, 2024
3996b08
Hack to account for _dd.base_service in test data
bouwkast Sep 26, 2024
c3f168f
Update ProcessStart OXS snapshots
bouwkast Sep 26, 2024
bee1a9f
Update test
bouwkast Sep 26, 2024
7e8d7af
Remove StackExchangeRedis snapshots I can't recreate
bouwkast Sep 26, 2024
c3d1cfc
Undo MySqlCommandTests isNewVersion
bouwkast Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"language": "dotnet",
"out.host": "localhost",
"runtime-id": "11c61d09-16bb-477f-87ab-4f81d656c5ca",
"span.kind": "client"
"span.kind": "client",
"_dd.base_service": "AspNetCoreSmokeTest"
},
"metrics": {
"_dd.top_level": 1.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"language": "dotnet",
"out.host": "localhost",
"runtime-id": "b34b2bed-9444-4597-87f6-b8202b03b1b8",
"span.kind": "client"
"span.kind": "client",
"_dd.base_service": "AspNetCoreSmokeTest"
},
"metrics": {
"_dd.top_level": 1.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ internal static class MessagePackStringCache
[ThreadStatic]
private static CachedBytes _origin;

[ThreadStatic]
private static CachedBytes _service;

private static CachedBytes _gitCommitSha;
private static CachedBytes _gitRepositoryUrl;
private static CachedBytes _aasSiteNameBytes;
Expand All @@ -48,6 +51,7 @@ public static void Clear()
_env = default;
_version = default;
_origin = default;
_service = default;
_gitCommitSha = default;
_gitRepositoryUrl = default;
_aasSiteNameBytes = default;
Expand Down Expand Up @@ -88,6 +92,11 @@ public static void Clear()
return GetBytes(origin, ref _origin);
}

public static byte[]? GetServiceBytes(string? service)
{
return GetBytes(service, ref _service);
}

public static byte[]? GetAzureAppServiceKeyBytes(string key, string? value)
{
switch (key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ internal class SpanMessagePackFormatter : IMessagePackFormatter<TraceChunkModel>

private readonly byte[] _originNameBytes = StringEncoding.UTF8.GetBytes(Trace.Tags.Origin);
private readonly byte[] _lastParentIdBytes = StringEncoding.UTF8.GetBytes(Trace.Tags.LastParentId);
private readonly byte[] _baseServiceNameBytes = StringEncoding.UTF8.GetBytes(Trace.Tags.BaseService);

// numeric tags
private readonly byte[] _metricsBytes = StringEncoding.UTF8.GetBytes("metrics");
Expand Down Expand Up @@ -412,7 +413,8 @@ private int WriteTags(ref byte[] bytes, int offset, in SpanModel model, ITagProc
offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, _languageValueBytes);

// add "version" tags to all spans whose service name is the default service name
if (string.Equals(span.Context.ServiceNameInternal, model.TraceChunk.DefaultServiceName, StringComparison.OrdinalIgnoreCase))
var serviceNameEqualsDefault = string.Equals(span.Context.ServiceNameInternal, model.TraceChunk.DefaultServiceName, StringComparison.OrdinalIgnoreCase);
andrewlock marked this conversation as resolved.
Show resolved Hide resolved
if (serviceNameEqualsDefault)
{
var versionRawBytes = MessagePackStringCache.GetVersionBytes(model.TraceChunk.ServiceVersion);

Expand All @@ -424,7 +426,20 @@ private int WriteTags(ref byte[] bytes, int offset, in SpanModel model, ITagProc
}
}

// SCI tags will be sent only once per trace chunk
// add _dd.base_service tag to spans where the service name has been overrideen
if (!serviceNameEqualsDefault && !string.IsNullOrEmpty(model.TraceChunk.DefaultServiceName))
{
var serviceNameRawBytes = MessagePackStringCache.GetServiceBytes(model.TraceChunk.DefaultServiceName);

if (serviceNameRawBytes is not null)
{
count++;
offset += MessagePackBinary.WriteStringBytes(ref bytes, offset, _baseServiceNameBytes);
offset += MessagePackBinary.WriteRaw(ref bytes, offset, serviceNameRawBytes);
}
}

// SCI tags will be sent only once per trace
if (model.IsFirstSpanInChunk)
{
var gitCommitShaRawBytes = MessagePackStringCache.GetGitCommitShaBytes(model.TraceChunk.GitCommitSha);
Expand Down
8 changes: 0 additions & 8 deletions tracer/src/Datadog.Trace/Span.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ internal partial class Span : ISpan
private static readonly bool IsLogLevelDebugEnabled = Log.IsEnabled(LogEventLevel.Debug);

private int _isFinished;
private bool _baseServiceTagSet;

internal Span(SpanContext context, DateTimeOffset? start)
: this(context, start, null)
Expand Down Expand Up @@ -80,13 +79,6 @@ internal string ServiceName
get => Context.ServiceNameInternal;
set
{
// Ignore case because service name and _dd.base_service are normalized in the agent and backend
if (!_baseServiceTagSet && !string.Equals(value, Context.ServiceNameInternal, StringComparison.OrdinalIgnoreCase))
{
Tags.SetTag(Trace.Tags.BaseService, Context.ServiceNameInternal);
_baseServiceTagSet = true;
}

Context.ServiceNameInternal = value;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public static Result IsAwsDynamoDbV0(this MockSpan span) => Result.FromSpan(span
.IsPresent("http.status_code")
.IsPresent("http.url")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsAwsKinesisOutboundV0(this MockSpan span) => Result.FromSpan(span)
Expand All @@ -170,6 +171,7 @@ public static Result IsAwsKinesisOutboundV0(this MockSpan span) => Result.FromSp
.IsPresent("http.status_code")
.IsPresent("http.url")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "producer"));

public static Result IsAwsSqsRequestV0(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -237,6 +239,7 @@ public static Result IsAzureServiceBusInboundV0(this MockSpan span, ISet<string>
.IsOptional("otel.status_description")
.IfPresentMatches("component", "servicebus")
.IfPresentMatches("kind", "consumer")
.IsOptional("_dd.base_service")
.Matches("span.kind", "consumer"));

public static Result IsAzureServiceBusOutboundV0(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
Expand All @@ -258,6 +261,7 @@ public static Result IsAzureServiceBusOutboundV0(this MockSpan span, ISet<string
.IsOptional("otel.status_description")
.IfPresentMatches("component", "servicebus")
.IfPresentMatches("kind", "producer")
.IsOptional("_dd.base_service")
.Matches("span.kind", "producer"));

public static Result IsAzureServiceBusRequestV0(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
Expand All @@ -281,6 +285,7 @@ public static Result IsAzureServiceBusRequestV0(this MockSpan span, ISet<string>
.IsOptional("otel.status_description")
.IfPresentMatches("component", "servicebus")
.IfPresentMatches("kind", "client")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsCosmosDbV0(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -379,6 +384,7 @@ public static Result IsHotChocolateV0(this MockSpan span) => Result.FromSpan(spa
.IsOptional("graphql.operation.type")
.IsPresent("graphql.source")
.Matches("component", "HotChocolate")
.IsOptional("_dd.base_service")
.Matches("span.kind", "server"));

public static Result IsHttpMessageHandlerV0(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -470,6 +476,7 @@ public static Result IsMySqlV0(this MockSpan span) => Result.FromSpan(span)
.Matches("db.type", "mysql")
.Matches("component", "MySql")
.Matches("span.kind", "client")
.IsOptional("_dd.base_service")
.IsOptional("_dd.dbm_trace_injected"));

public static Result IsNpgsqlV0(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -547,6 +554,7 @@ public static Result IsRemotingClientV0(this MockSpan span) => Result.FromSpan(s
.IsPresent("rpc.method")
.Matches("rpc.system", "dotnet_remoting")
.Matches("component", "Remoting")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsRemotingServerV0(this MockSpan span) => Result.FromSpan(span)
Expand All @@ -556,6 +564,7 @@ public static Result IsRemotingServerV0(this MockSpan span) => Result.FromSpan(s
.IsPresent("rpc.method")
.Matches("rpc.system", "dotnet_remoting")
.Matches("component", "Remoting")
.IsOptional("_dd.base_service")
.Matches("span.kind", "server"));

public static Result IsServiceRemotingClientV0(this MockSpan span) => Result.FromSpan(span)
Expand Down
11 changes: 11 additions & 0 deletions tracer/test/Datadog.Trace.TestHelpers/SpanMetadataV1Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ public static Result IsAwsDynamoDbV1(this MockSpan span) => Result.FromSpan(span
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "tablename", "peer.service")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsAwsKinesisOutboundV1(this MockSpan span) => Result.FromSpan(span)
Expand All @@ -181,6 +182,7 @@ public static Result IsAwsKinesisOutboundV1(this MockSpan span) => Result.FromSp
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "streamname", "peer.service")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "producer"));

public static Result IsAwsSqsInboundV1(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -252,6 +254,7 @@ public static Result IsAwsSqsRequestV1(this MockSpan span) => Result.FromSpan(sp
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "queuename", "peer.service")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsAwsSnsInboundV1(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -298,6 +301,7 @@ public static Result IsAwsSnsOutboundV1(this MockSpan span) => Result.FromSpan(s
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "topicname", "peer.service")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "producer"));

public static Result IsAwsSnsRequestV1(this MockSpan span) => Result.FromSpan(span)
Expand All @@ -322,6 +326,7 @@ public static Result IsAwsSnsRequestV1(this MockSpan span) => Result.FromSpan(sp
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "topicname", "peer.service")
.Matches("component", "aws-sdk")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsAzureServiceBusInboundV1(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
Expand All @@ -345,6 +350,7 @@ public static Result IsAzureServiceBusInboundV1(this MockSpan span, ISet<string>
.IsOptional("otel.status_description")
.IfPresentMatches("component", "servicebus")
.IfPresentMatches("kind", "consumer")
.IsOptional("_dd.base_service")
.Matches("span.kind", "consumer"));

public static Result IsAzureServiceBusOutboundV1(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
Expand All @@ -369,6 +375,7 @@ public static Result IsAzureServiceBusOutboundV1(this MockSpan span, ISet<string
.MatchesOneOf("_dd.peer.service.source", "messaging.destination.name", "message_bus.destination", "peer.service")
.IfPresentMatches("component", "servicebus")
.IfPresentMatches("kind", "producer")
.IsOptional("_dd.base_service")
.Matches("span.kind", "producer"));

public static Result IsAzureServiceBusRequestV1(this MockSpan span, ISet<string> excludeTags = null) => Result.FromSpan(span, excludeTags)
Expand All @@ -395,6 +402,7 @@ public static Result IsAzureServiceBusRequestV1(this MockSpan span, ISet<string>
.MatchesOneOf("_dd.peer.service.source", "messaging.destination.name", "message_bus.destination", "peer.service")
.IfPresentMatches("component", "servicebus")
.IfPresentMatches("kind", "client")
.IsOptional("_dd.base_service")
.Matches("span.kind", "client"));

public static Result IsCosmosDbV1(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -612,6 +620,7 @@ public static Result IsMsmqOutboundV1(this MockSpan span) => Result.FromSpan(spa
.IsOptional("peer.service.remapped_from")
.MatchesOneOf("_dd.peer.service.source", "out.host", "peer.service")
.Matches("component", "msmq")
.IsOptional("_dd.base_service")
.Matches("span.kind", "producer"));

public static Result IsMsmqClientV1(this MockSpan span) => Result.FromSpan(span)
Expand Down Expand Up @@ -773,6 +782,7 @@ public static Result IsRemotingClientV1(this MockSpan span) => Result.FromSpan(s
.Matches("rpc.system", "dotnet_remoting")
.Matches("component", "Remoting")
.IfPresentMatchesOneOf("_dd.peer.service.source", "peer.service", "rpc.service")
.IsOptional("_dd.base_service")
.MatchesOneOf("span.kind", "client", "server"));

public static Result IsRemotingServerV1(this MockSpan span) => Result.FromSpan(span)
Expand All @@ -782,6 +792,7 @@ public static Result IsRemotingServerV1(this MockSpan span) => Result.FromSpan(s
.IsPresent("rpc.method")
.Matches("rpc.system", "dotnet_remoting")
.Matches("component", "Remoting")
.IsOptional("_dd.base_service")
.MatchesOneOf("span.kind", "client", "server"));

public static Result IsServiceRemotingClientV1(this MockSpan span) => Result.FromSpan(span)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ public class SpanMessagePackFormatterTests
public void SerializeSpans()
{
var formatter = SpanFormatterResolver.Instance.GetFormatter<TraceChunkModel>();

var traceContext = new TraceContext(Mock.Of<IDatadogTracer>());
var parentContext = new SpanContext(new TraceId(0, 1), 2, (int)SamplingPriority.UserKeep, "ServiceName1", "origin1");

var spans = new[]
{
new Span(parentContext, DateTimeOffset.UtcNow),
new Span(new SpanContext(parentContext, new TraceContext(Mock.Of<IDatadogTracer>()), "ServiceName1"), DateTimeOffset.UtcNow),
new Span(new SpanContext(parentContext, traceContext, "ServiceName1"), DateTimeOffset.UtcNow),
new Span(new SpanContext(new TraceId(0, 5), 6, (int)SamplingPriority.UserKeep, "ServiceName3", "origin3"), DateTimeOffset.UtcNow),
};

Expand Down
58 changes: 0 additions & 58 deletions tracer/test/Datadog.Trace.Tests/SpanTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,63 +357,5 @@ public void SetTag_Double()
span.GetTag(stringKey).Should().Be(stringValue);
span.GetTag(numericKey).Should().BeNull();
}

[Fact]
public void ServiceOverride_WhenSet_HasBaseService()
{
var origName = "MyServiceA";
var newName = "MyServiceB";
var span = _tracer.StartSpan(nameof(SetTag_Double), serviceName: origName);
span.ServiceName = newName;

span.ServiceName.Should().Be(newName);
span.GetTag(Tags.BaseService).Should().Be(origName);
}

[Fact]
public void ServiceOverride_WhenNotSet_HasNoBaseService()
{
var origName = "MyServiceA";
var span = _tracer.StartSpan(nameof(SetTag_Double), serviceName: origName);

span.ServiceName.Should().Be(origName);
span.GetTag(Tags.BaseService).Should().BeNull();
}

[Fact]
public void ServiceOverride_WhenSetSame_HasNoBaseService()
{
var origName = "MyServiceA";
var span = _tracer.StartSpan(nameof(SetTag_Double), serviceName: origName);
span.ServiceName = origName;

span.ServiceName.Should().Be(origName);
span.GetTag(Tags.BaseService).Should().BeNull();
}

[Fact]
public void ServiceOverride_WhenSetSameWithDifferentCase_HasNoBaseService()
{
var origName = "MyServiceA";
var newName = origName.ToUpper();
var span = _tracer.StartSpan(nameof(SetTag_Double), serviceName: origName);
span.ServiceName = newName;

span.ServiceName.Should().Be(newName); // ServiceName should change although _dd.base_service has not been added
span.GetTag(Tags.BaseService).Should().BeNull();
}

[Fact]
public void ServiceOverride_WhenSetTwice_HasBaseService()
{
var origName = "MyServiceA";
var newName = "MyServiceC";
var span = _tracer.StartSpan(nameof(SetTag_Double), serviceName: origName);
span.ServiceName = "MyServiceB";
span.ServiceName = newName;

span.ServiceName.Should().Be(newName);
span.GetTag(Tags.BaseService).Should().Be(origName);
}
}
}
8 changes: 6 additions & 2 deletions tracer/test/Datadog.Trace.Tests/Tagging/TagsListTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ public async Task Serialization_ServiceEntrySpan()
deserializedSpan.Tags.Should().Contain(Tags.RuntimeId, Tracer.RuntimeId);
deserializedSpan.Tags.Should().Contain(Tags.Propagated.DecisionMaker, "-0"); // the child span is serialized first in the trace chunk
deserializedSpan.Tags.Should().Contain(Tags.Propagated.TraceIdUpper, hexStringTraceId);
deserializedSpan.Tags.Count.Should().Be(customTagCount + 5);
deserializedSpan.Tags.Should().ContainKey(Tags.BaseService);
deserializedSpan.Tags[Tags.BaseService].Should().Be(_tracer.DefaultServiceName);
deserializedSpan.Tags.Count.Should().Be(customTagCount + 6);

deserializedSpan.Metrics.Should().Contain(Metrics.SamplingLimitDecision, 0.75);
deserializedSpan.Metrics.Should().Contain(Metrics.TopLevelSpan, 1);
Expand Down Expand Up @@ -186,7 +188,9 @@ public async Task Serialization_ChildSpan()
deserializedSpan.Tags.Should().Contain(Tags.Language, TracerConstants.Language);
deserializedSpan.Tags.Should().Contain(Tags.Propagated.DecisionMaker, "-0"); // the child span is serialize first in the trace chunk
deserializedSpan.Tags.Should().Contain(Tags.Propagated.TraceIdUpper, hexStringTraceId);
deserializedSpan.Tags.Count.Should().Be(customTagCount + 4);
deserializedSpan.Tags.Should().ContainKey(Tags.BaseService);
deserializedSpan.Tags[Tags.BaseService].Should().BeOneOf(TestRunners.ValidNames);
deserializedSpan.Tags.Count.Should().Be(customTagCount + 5);

deserializedSpan.Metrics.Should().Contain(Metrics.SamplingLimitDecision, 0.75);
deserializedSpan.Metrics.Count.Should().Be(customTagCount + 1);
Expand Down
Loading
Loading