Skip to content

Commit d7ec963

Browse files
khanayan123claude
andcommitted
Address PR review comments
- Rename private GetRuntimeIdImpl() back to GetImpl() to preserve naming convention - Move session ID headers from per-request in JsonTelemetryTransport to TelemetryHttpHeaderNames default headers (constant for process lifetime) - Move tests from TracerTests.cs to Util/RuntimeIdTests.cs to match source layout - Move eager root session ID init from TracerManager to Instrumentation.InitializeNoNativeParts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 642b76b commit d7ec963

8 files changed

Lines changed: 94 additions & 53 deletions

File tree

tracer/src/Datadog.Trace/ClrProfiler/Instrumentation.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ internal static void InitializeNoNativeParts(ref RefStopwatch sw)
306306
}
307307
#endif
308308

309+
// Eagerly initialize the root session ID so child processes
310+
// inherit it even if spawned before the first telemetry flush.
311+
_ = RuntimeId.GetRootSessionId();
312+
309313
try
310314
{
311315
// ensure global instance is created if it's not already
Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,92 @@
1-
// <copyright file="TelemetryHttpHeaderNames.cs" company="Datadog">
1+
// <copyright file="TelemetryHttpHeaderNames.cs" company="Datadog">
22
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
33
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
44
// </copyright>
55

66
using System.Collections.Generic;
77
using Datadog.Trace.HttpOverStreams;
8+
using Datadog.Trace.Util;
89

910
namespace Datadog.Trace.Telemetry
1011
{
1112
internal static class TelemetryHttpHeaderNames
1213
{
1314
/// <summary>
14-
/// Returns <see cref="GetDefaultAgentHeaders"/>, in the format <c>Key: Value\r\n</c>. For use in HTTP headers
15+
/// Gets the default agent headers in the format <c>Key: Value\r\n</c>. For use in HTTP headers.
16+
/// Not a const because session headers depend on runtime values.
1517
/// </summary>
16-
internal const string HttpSerializedDefaultAgentHeaders =
17-
$"{TelemetryConstants.ClientLibraryLanguageHeader}: {TracerConstants.Language}" + DatadogHttpValues.CrLf +
18-
$"{TelemetryConstants.ClientLibraryVersionHeader}: {TracerConstants.AssemblyVersion}" + DatadogHttpValues.CrLf +
19-
$"{HttpHeaderNames.TracingEnabled}: false" + DatadogHttpValues.CrLf;
18+
internal static string HttpSerializedDefaultAgentHeaders { get; } = BuildSerializedAgentHeaders();
2019

2120
/// <summary>
2221
/// Gets the default constant headers that should be added to any request to the agent
2322
/// </summary>
2423
internal static KeyValuePair<string, string>[] GetDefaultAgentHeaders()
25-
=>
26-
[
24+
{
25+
var headers = new List<KeyValuePair<string, string>>
26+
{
2727
new(TelemetryConstants.ClientLibraryLanguageHeader, TracerConstants.Language),
2828
new(TelemetryConstants.ClientLibraryVersionHeader, TracerConstants.AssemblyVersion),
29-
new(HttpHeaderNames.TracingEnabled, "false") // don't add automatic instrumentation to requests directed to the agent
30-
];
29+
new(HttpHeaderNames.TracingEnabled, "false"), // don't add automatic instrumentation to requests directed to the agent
30+
new(TelemetryConstants.SessionIdHeader, RuntimeId.Get()),
31+
};
32+
33+
AddRootSessionIdHeader(headers);
34+
35+
return headers.ToArray();
36+
}
3137

3238
/// <summary>
3339
/// Gets the default constant headers that should be added to any request to the direct telemetry intake
3440
/// </summary>
3541
internal static KeyValuePair<string, string>[] GetDefaultIntakeHeaders(TelemetrySettings.AgentlessSettings settings)
3642
{
37-
var headerCount = settings.Cloud is null ? 4 : 7;
43+
var headers = new List<KeyValuePair<string, string>>
44+
{
45+
new(TelemetryConstants.ClientLibraryLanguageHeader, TracerConstants.Language),
46+
new(TelemetryConstants.ClientLibraryVersionHeader, TracerConstants.AssemblyVersion),
47+
new(HttpHeaderNames.TracingEnabled, "false"),
48+
new(TelemetryConstants.ApiKeyHeader, settings.ApiKey),
49+
new(TelemetryConstants.SessionIdHeader, RuntimeId.Get()),
50+
};
3851

39-
var headers = new KeyValuePair<string, string>[headerCount];
52+
if (settings.Cloud is { } cloud)
53+
{
54+
headers.Add(new(TelemetryConstants.CloudProviderHeader, cloud.Provider));
55+
headers.Add(new(TelemetryConstants.CloudResourceTypeHeader, cloud.ResourceType));
56+
headers.Add(new(TelemetryConstants.CloudResourceIdentifierHeader, cloud.ResourceIdentifier));
57+
}
4058

41-
headers[0] = new(TelemetryConstants.ClientLibraryLanguageHeader, TracerConstants.Language);
42-
headers[1] = new(TelemetryConstants.ClientLibraryVersionHeader, TracerConstants.AssemblyVersion);
43-
headers[2] = new(HttpHeaderNames.TracingEnabled, "false"); // don't add automatic instrumentation to requests directed to the agent
44-
headers[3] = new(TelemetryConstants.ApiKeyHeader, settings.ApiKey);
59+
AddRootSessionIdHeader(headers);
4560

46-
if (settings.Cloud is { } cloud)
61+
return headers.ToArray();
62+
}
63+
64+
private static void AddRootSessionIdHeader(List<KeyValuePair<string, string>> headers)
65+
{
66+
var sessionId = RuntimeId.Get();
67+
var rootSessionId = RuntimeId.GetRootSessionId();
68+
if (rootSessionId != sessionId)
69+
{
70+
headers.Add(new(TelemetryConstants.RootSessionIdHeader, rootSessionId));
71+
}
72+
}
73+
74+
private static string BuildSerializedAgentHeaders()
75+
{
76+
var serialized =
77+
$"{TelemetryConstants.ClientLibraryLanguageHeader}: {TracerConstants.Language}" + DatadogHttpValues.CrLf +
78+
$"{TelemetryConstants.ClientLibraryVersionHeader}: {TracerConstants.AssemblyVersion}" + DatadogHttpValues.CrLf +
79+
$"{HttpHeaderNames.TracingEnabled}: false" + DatadogHttpValues.CrLf +
80+
$"{TelemetryConstants.SessionIdHeader}: {RuntimeId.Get()}" + DatadogHttpValues.CrLf;
81+
82+
var sessionId = RuntimeId.Get();
83+
var rootSessionId = RuntimeId.GetRootSessionId();
84+
if (rootSessionId != sessionId)
4785
{
48-
headers[4] = new(TelemetryConstants.CloudProviderHeader, cloud.Provider);
49-
headers[5] = new(TelemetryConstants.CloudResourceTypeHeader, cloud.ResourceType);
50-
headers[6] = new(TelemetryConstants.CloudResourceIdentifierHeader, cloud.ResourceIdentifier);
86+
serialized += $"{TelemetryConstants.RootSessionIdHeader}: {rootSessionId}" + DatadogHttpValues.CrLf;
5187
}
5288

53-
return headers;
89+
return serialized;
5490
}
5591
}
5692
}

tracer/src/Datadog.Trace/Telemetry/Transports/JsonTelemetryTransport.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
using Datadog.Trace.Logging;
1414
using Datadog.Trace.PlatformHelpers;
1515
using Datadog.Trace.Telemetry.Metrics;
16-
using Datadog.Trace.Util;
1716
using Datadog.Trace.Util.Http;
1817
using Datadog.Trace.Vendors.Newtonsoft.Json;
1918
using Datadog.Trace.Vendors.Newtonsoft.Json.Serialization;
@@ -57,14 +56,6 @@ public async Task<TelemetryPushResult> PushTelemetry(TelemetryData data)
5756
request.AddHeader(TelemetryConstants.DebugHeader, "true");
5857
}
5958

60-
var sessionId = RuntimeId.Get();
61-
request.AddHeader(TelemetryConstants.SessionIdHeader, sessionId);
62-
var rootSessionId = RuntimeId.GetRootSessionId();
63-
if (rootSessionId != sessionId)
64-
{
65-
request.AddHeader(TelemetryConstants.RootSessionIdHeader, rootSessionId);
66-
}
67-
6859
request.AddContainerMetadataHeaders(_containerMetadata);
6960

7061
TelemetryFactory.Metrics.RecordCountTelemetryApiRequests(endpointMetricTag);

tracer/src/Datadog.Trace/TracerManager.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,6 @@ public TracerManager(
114114

115115
SpanContextPropagator = SpanContextPropagatorFactory.GetSpanContextPropagator(settings.PropagationStyleInject, settings.PropagationStyleExtract, settings.PropagationExtractFirstOnly, settings.PropagationBehaviorExtract);
116116

117-
// Eagerly initialize the root session ID so child processes inherit it
118-
// even if spawned before the first telemetry flush.
119-
_ = RuntimeId.GetRootSessionId();
120-
121117
UpdatePerTraceSettings(settings.Manager.InitialMutableSettings);
122118
_settingSubscription = settings.Manager.SubscribeToChanges(changes =>
123119
{

tracer/src/Datadog.Trace/Util/RuntimeId.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ internal static class RuntimeId
1616
private static string _runtimeId;
1717
private static string _rootSessionId;
1818

19-
public static string Get() => LazyInitializer.EnsureInitialized(ref _runtimeId, () => GetRuntimeIdImpl());
19+
public static string Get() => LazyInitializer.EnsureInitialized(ref _runtimeId, () => GetImpl());
2020

2121
public static string GetRootSessionId() => LazyInitializer.EnsureInitialized(ref _rootSessionId, () => GetRootSessionIdImpl());
2222

23-
private static string GetRuntimeIdImpl()
23+
private static string GetImpl()
2424
{
2525
if (NativeLoader.TryGetRuntimeIdFromNative(out var runtimeId))
2626
{

tracer/test/Datadog.Trace.Tests/Telemetry/Transports/JsonTelemetryTransportTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
using Datadog.Trace.Telemetry.Transports;
1515
using Datadog.Trace.TestHelpers.FluentAssertionsExtensions.Json;
1616
using Datadog.Trace.TestHelpers.TransportHelpers;
17-
using Datadog.Trace.Util;
1817
using Datadog.Trace.Vendors.Newtonsoft.Json;
1918
using Datadog.Trace.Vendors.Newtonsoft.Json.Linq;
2019
using FluentAssertions;
@@ -76,7 +75,6 @@ public async Task ShouldContainRequiredHeaders(bool debugEnabled, [Combinatorial
7675
{ "DD-Telemetry-Request-Type", "my-request-type" },
7776
{ "Datadog-Container-ID", "my-container-id" },
7877
{ "Datadog-Entity-ID", "my-entity-id" },
79-
{ TelemetryConstants.SessionIdHeader, RuntimeId.Get() },
8078
};
8179
if (debugEnabled)
8280
{

tracer/test/Datadog.Trace.Tests/TracerTests.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -561,21 +561,6 @@ public void RuntimeId()
561561
Guid.TryParse(runtimeId, out _).Should().BeTrue();
562562
}
563563

564-
[Fact]
565-
public void RootSessionId_DefaultsToRuntimeId()
566-
{
567-
var rootSessionId = Datadog.Trace.Util.RuntimeId.GetRootSessionId();
568-
rootSessionId.Should().Be(Datadog.Trace.Util.RuntimeId.Get());
569-
}
570-
571-
[Fact]
572-
public void RootSessionId_SetsEnvVar()
573-
{
574-
var rootSessionId = Datadog.Trace.Util.RuntimeId.GetRootSessionId();
575-
Environment.GetEnvironmentVariable(ConfigurationKeys.Telemetry.RootSessionId)
576-
.Should().Be(rootSessionId);
577-
}
578-
579564
[Fact]
580565
public async Task ForceFlush()
581566
{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// <copyright file="RuntimeIdTests.cs" company="Datadog">
2+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
3+
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc.
4+
// </copyright>
5+
6+
using System;
7+
using Datadog.Trace.Configuration;
8+
using Datadog.Trace.Util;
9+
using FluentAssertions;
10+
using Xunit;
11+
12+
namespace Datadog.Trace.Tests.Util
13+
{
14+
public class RuntimeIdTests
15+
{
16+
[Fact]
17+
public void RootSessionId_DefaultsToRuntimeId()
18+
{
19+
var rootSessionId = RuntimeId.GetRootSessionId();
20+
rootSessionId.Should().Be(RuntimeId.Get());
21+
}
22+
23+
[Fact]
24+
public void RootSessionId_SetsEnvVar()
25+
{
26+
var rootSessionId = RuntimeId.GetRootSessionId();
27+
Environment.GetEnvironmentVariable(ConfigurationKeys.Telemetry.RootSessionId)
28+
.Should().Be(rootSessionId);
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)