Skip to content

Commit f1940c3

Browse files
committed
Support debugger V2 and send logs to V1
1 parent ef7cec1 commit f1940c3

File tree

9 files changed

+131
-33
lines changed

9 files changed

+131
-33
lines changed

tracer/src/Datadog.Trace/Agent/DiscoveryService/AgentConfiguration.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ internal record AgentConfiguration
1212
public AgentConfiguration(
1313
string? configurationEndpoint,
1414
string? debuggerEndpoint,
15+
string? debuggerV2Endpoint,
1516
string? symbolDbEndpoint,
1617
string? agentVersion,
1718
string? statsEndpoint,
@@ -26,6 +27,7 @@ public AgentConfiguration(
2627
{
2728
ConfigurationEndpoint = configurationEndpoint;
2829
DebuggerEndpoint = debuggerEndpoint;
30+
DebuggerV2Endpoint = debuggerV2Endpoint;
2931
DiagnosticsEndpoint = diagnosticsEndpoint;
3032
SymbolDbEndpoint = symbolDbEndpoint;
3133
AgentVersion = agentVersion;
@@ -43,6 +45,8 @@ public AgentConfiguration(
4345

4446
public string? DebuggerEndpoint { get; }
4547

48+
public string? DebuggerV2Endpoint { get; }
49+
4650
public string? DiagnosticsEndpoint { get; }
4751

4852
public string? SymbolDbEndpoint { get; }

tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace Datadog.Trace.Agent.DiscoveryService
2020
internal class DiscoveryService : IDiscoveryService
2121
{
2222
private const string SupportedDebuggerEndpoint = "debugger/v1/input";
23+
private const string SupportedDebuggerV2Endpoint = "debugger/v2/input";
2324
private const string SupportedDiagnosticsEndpoint = "debugger/v1/diagnostics";
2425
private const string SupportedSymbolDbEndpoint = "symdb/v1/input";
2526
private const string SupportedConfigurationEndpoint = "v0.7/config";
@@ -66,6 +67,7 @@ public DiscoveryService(
6667
new[]
6768
{
6869
SupportedDebuggerEndpoint,
70+
SupportedDebuggerV2Endpoint,
6971
SupportedDiagnosticsEndpoint,
7072
SupportedSymbolDbEndpoint,
7173
SupportedConfigurationEndpoint,
@@ -223,6 +225,7 @@ private async Task ProcessDiscoveryResponse(IApiResponse response)
223225
var discoveredEndpoints = (jObject["endpoints"] as JArray)?.Values<string>().ToArray();
224226
string? configurationEndpoint = null;
225227
string? debuggerEndpoint = null;
228+
string? debuggerV2Endpoint = null;
226229
string? diagnosticsEndpoint = null;
227230
string? symbolDbEndpoint = null;
228231
string? statsEndpoint = null;
@@ -246,6 +249,10 @@ private async Task ProcessDiscoveryResponse(IApiResponse response)
246249
{
247250
debuggerEndpoint = endpoint;
248251
}
252+
else if (endpoint.Equals(SupportedDebuggerV2Endpoint, StringComparison.OrdinalIgnoreCase))
253+
{
254+
debuggerV2Endpoint = endpoint;
255+
}
249256
else if (endpoint.Equals(SupportedDiagnosticsEndpoint, StringComparison.OrdinalIgnoreCase))
250257
{
251258
diagnosticsEndpoint = endpoint;
@@ -290,6 +297,7 @@ private async Task ProcessDiscoveryResponse(IApiResponse response)
290297
var newConfig = new AgentConfiguration(
291298
configurationEndpoint: configurationEndpoint,
292299
debuggerEndpoint: debuggerEndpoint,
300+
debuggerV2Endpoint: debuggerV2Endpoint ?? diagnosticsEndpoint ?? debuggerEndpoint,
293301
diagnosticsEndpoint: diagnosticsEndpoint ?? debuggerEndpoint,
294302
symbolDbEndpoint: symbolDbEndpoint,
295303
agentVersion: agentVersion,

tracer/src/Datadog.Trace/Debugger/DebuggerFactory.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ internal class DebuggerFactory
3030
internal static DynamicInstrumentation CreateDynamicInstrumentation(IDiscoveryService discoveryService, IRcmSubscriptionManager remoteConfigurationManager, TracerSettings tracerSettings, string serviceName, DebuggerSettings debuggerSettings, IGitMetadataTagsProvider gitMetadataTagsProvider)
3131
{
3232
var snapshotSlicer = SnapshotSlicer.Create(debuggerSettings);
33-
var snapshotStatusSink = SnapshotSink.Create(debuggerSettings, snapshotSlicer);
33+
var snapshotSink = SnapshotSink.Create(debuggerSettings, snapshotSlicer);
34+
var logSink = SnapshotSink.Create(debuggerSettings, snapshotSlicer);
3435
var diagnosticsSink = DiagnosticsSink.Create(serviceName, debuggerSettings);
3536

36-
var debuggerUploader = CreateSnapshotUploader(discoveryService, debuggerSettings, gitMetadataTagsProvider, GetApiFactory(tracerSettings, true), snapshotStatusSink);
37+
var snapshotUploader = CreateSnapshotUploader(discoveryService, debuggerSettings, gitMetadataTagsProvider, GetApiFactory(tracerSettings, true), snapshotSink);
38+
var logUploader = CreateSnapshotUploader(discoveryService, debuggerSettings, gitMetadataTagsProvider, GetApiFactory(tracerSettings, false), logSink);
3739
var diagnosticsUploader = CreateDiagnosticsUploader(discoveryService, debuggerSettings, gitMetadataTagsProvider, GetApiFactory(tracerSettings, true), diagnosticsSink);
3840
var lineProbeResolver = LineProbeResolver.Create(debuggerSettings.ThirdPartyDetectionExcludes, debuggerSettings.ThirdPartyDetectionIncludes);
3941
var probeStatusPoller = ProbeStatusPoller.Create(diagnosticsSink, debuggerSettings);
@@ -46,7 +48,8 @@ internal static DynamicInstrumentation CreateDynamicInstrumentation(IDiscoverySe
4648
discoveryService: discoveryService,
4749
remoteConfigurationManager: remoteConfigurationManager,
4850
lineProbeResolver: lineProbeResolver,
49-
snapshotUploader: debuggerUploader,
51+
snapshotUploader: snapshotUploader,
52+
logUploader: logUploader,
5053
diagnosticsUploader: diagnosticsUploader,
5154
probeStatusPoller: probeStatusPoller,
5255
configurationUpdater: configurationUpdater,
@@ -70,12 +73,22 @@ private static IDogStatsd GetDogStatsd(TracerSettings tracerSettings, string ser
7073
return statsd;
7174
}
7275

73-
private static SnapshotUploader CreateSnapshotUploader(IDiscoveryService discoveryService, DebuggerSettings debuggerSettings, IGitMetadataTagsProvider gitMetadataTagsProvider, IApiRequestFactory apiFactory, SnapshotSink snapshotStatusSink)
76+
private static SnapshotUploader CreateSnapshotUploader(IDiscoveryService discoveryService, DebuggerSettings debuggerSettings, IGitMetadataTagsProvider gitMetadataTagsProvider, IApiRequestFactory apiFactory, SnapshotSink snapshotSink)
7477
{
7578
var snapshotBatchUploadApi = DebuggerUploadApiFactory.CreateSnapshotUploadApi(apiFactory, discoveryService, gitMetadataTagsProvider);
7679
var snapshotBatchUploader = BatchUploader.Create(snapshotBatchUploadApi);
7780

78-
var debuggerSink = SnapshotUploader.Create(snapshotStatusSink, snapshotBatchUploader, debuggerSettings);
81+
var debuggerSink = SnapshotUploader.Create(snapshotSink, snapshotBatchUploader, debuggerSettings);
82+
83+
return debuggerSink;
84+
}
85+
86+
private static SnapshotUploader CreateLogUploader(IDiscoveryService discoveryService, DebuggerSettings debuggerSettings, IGitMetadataTagsProvider gitMetadataTagsProvider, IApiRequestFactory apiFactory, SnapshotSink snapshotSink)
87+
{
88+
var logUploaderApi = DebuggerUploadApiFactory.CreateLogUploadApi(apiFactory, discoveryService, gitMetadataTagsProvider);
89+
var logBatchUploader = BatchUploader.Create(logUploaderApi);
90+
91+
var debuggerSink = SnapshotUploader.Create(snapshotSink, logBatchUploader, debuggerSettings);
7992

8093
return debuggerSink;
8194
}

tracer/src/Datadog.Trace/Debugger/DynamicInstrumentation.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ internal class DynamicInstrumentation : IDisposable
3939
private readonly IRcmSubscriptionManager _subscriptionManager;
4040
private readonly ISubscription _subscription;
4141
private readonly ISnapshotUploader _snapshotUploader;
42+
private readonly ISnapshotUploader _logUploader;
4243
private readonly IDebuggerUploader _diagnosticsUploader;
4344
private readonly ILineProbeResolver _lineProbeResolver;
4445
private readonly List<ProbeDefinition> _unboundProbes;
@@ -57,6 +58,7 @@ internal DynamicInstrumentation(
5758
IRcmSubscriptionManager remoteConfigurationManager,
5859
ILineProbeResolver lineProbeResolver,
5960
ISnapshotUploader snapshotUploader,
61+
ISnapshotUploader logUploader,
6062
IDebuggerUploader diagnosticsUploader,
6163
IProbeStatusPoller probeStatusPoller,
6264
ConfigurationUpdater configurationUpdater,
@@ -68,6 +70,7 @@ internal DynamicInstrumentation(
6870
_discoveryService = discoveryService;
6971
_lineProbeResolver = lineProbeResolver;
7072
_snapshotUploader = snapshotUploader;
73+
_logUploader = logUploader;
7174
_diagnosticsUploader = diagnosticsUploader;
7275
_probeStatusPoller = probeStatusPoller;
7376
_subscriptionManager = remoteConfigurationManager;
@@ -168,6 +171,7 @@ private void StartInBackground()
168171
_probeStatusPoller.StartPolling();
169172
_ = _diagnosticsUploader.StartFlushingAsync();
170173
_ = _snapshotUploader.StartFlushingAsync();
174+
_ = _logUploader.StartFlushingAsync();
171175
}
172176

173177
internal void UpdateAddedProbeInstrumentations(IReadOnlyList<ProbeDefinition> addedProbes)
@@ -493,10 +497,27 @@ internal void AddSnapshot(ProbeInfo probe, string snapshot)
493497
return;
494498
}
495499

500+
if (!probe.IsFullSnapshot)
501+
{
502+
AddLog(probe, snapshot);
503+
return;
504+
}
505+
496506
_snapshotUploader.Add(probe.ProbeId, snapshot);
497507
SetProbeStatusToEmitting(probe);
498508
}
499509

510+
internal void AddLog(ProbeInfo probe, string log)
511+
{
512+
if (IsDisposed)
513+
{
514+
return;
515+
}
516+
517+
_logUploader.Add(probe.ProbeId, log);
518+
SetProbeStatusToEmitting(probe);
519+
}
520+
500521
internal void SetProbeStatusToEmitting(ProbeInfo probe)
501522
{
502523
if (IsDisposed)

tracer/src/Datadog.Trace/Debugger/Upload/DebuggerUploadApiBase.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Threading.Tasks;
1010
using System.Web;
1111
using Datadog.Trace.Agent;
12+
using Datadog.Trace.Agent.Transports;
1213
using Datadog.Trace.Ci.Tags;
1314
using Datadog.Trace.Configuration;
1415
using Datadog.Trace.Processors;
@@ -18,6 +19,8 @@ namespace Datadog.Trace.Debugger.Upload;
1819

1920
internal abstract class DebuggerUploadApiBase : IBatchUploadApi
2021
{
22+
protected const string Debuggerv1Endpoint = "debugger/v1/input";
23+
2124
private readonly IApiRequestFactory _apiRequestFactory;
2225
private readonly IGitMetadataTagsProvider? _gitMetadataTagsProvider;
2326

@@ -54,6 +57,16 @@ protected string? Endpoint
5457
return builder.ToString();
5558
}
5659

60+
protected Task<IApiResponse> PostAsync(string uri, ArraySegment<byte> data)
61+
{
62+
var request = _apiRequestFactory.Create(new Uri(uri));
63+
var isDebuggerV1 = uri.Contains(Debuggerv1Endpoint);
64+
65+
return isDebuggerV1
66+
? request.PostAsync(data, MimeTypes.Json)
67+
: request.PostAsync([new("event", MimeTypes.Json, "event.json", data)]);
68+
}
69+
5770
private string GetDefaultTagsMergedWithGlobalTags()
5871
{
5972
var sb = StringBuilderCache.Acquire();

tracer/src/Datadog.Trace/Debugger/Upload/DebuggerUploadApiFactory.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ internal static IBatchUploadApi CreateSnapshotUploadApi(IApiRequestFactory apiRe
1717
return SnapshotUploadApi.Create(apiRequestFactory, discoveryService, gitMetadataTagsProvider);
1818
}
1919

20+
internal static IBatchUploadApi CreateLogUploadApi(IApiRequestFactory apiRequestFactory, IDiscoveryService discoveryService, IGitMetadataTagsProvider gitMetadataTagsProvider)
21+
{
22+
return LogUploadApi.Create(apiRequestFactory, discoveryService, gitMetadataTagsProvider);
23+
}
24+
2025
internal static IBatchUploadApi CreateDiagnosticsUploadApi(IApiRequestFactory apiRequestFactory, IDiscoveryService discoveryService, IGitMetadataTagsProvider gitMetadataTagsProvider)
2126
{
2227
return DiagnosticsUploadApi.Create(apiRequestFactory, discoveryService, gitMetadataTagsProvider);

tracer/src/Datadog.Trace/Debugger/Upload/DiagnosticsUploadApi.cs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,21 @@
88
using System.Threading.Tasks;
99
using Datadog.Trace.Agent;
1010
using Datadog.Trace.Agent.DiscoveryService;
11-
using Datadog.Trace.Agent.Transports;
1211
using Datadog.Trace.Configuration;
1312
using Datadog.Trace.Logging;
1413

1514
namespace Datadog.Trace.Debugger.Upload
1615
{
1716
internal class DiagnosticsUploadApi : DebuggerUploadApiBase
1817
{
19-
private const string LegacyEndpoint = "debugger/v1/input";
2018
private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor<DiagnosticsUploadApi>();
2119

22-
private readonly IApiRequestFactory _apiRequestFactory;
23-
2420
private DiagnosticsUploadApi(
2521
IApiRequestFactory apiRequestFactory,
2622
IDiscoveryService discoveryService,
2723
IGitMetadataTagsProvider gitMetadataTagsProvider)
2824
: base(apiRequestFactory, gitMetadataTagsProvider)
2925
{
30-
_apiRequestFactory = apiRequestFactory;
3126
discoveryService.SubscribeToChanges(c => Endpoint = c.DiagnosticsEndpoint);
3227
}
3328

@@ -42,13 +37,13 @@ public static DiagnosticsUploadApi Create(
4237
public override async Task<bool> SendBatchAsync(ArraySegment<byte> data)
4338
{
4439
var uri = BuildUri();
45-
if (uri == null)
40+
if (string.IsNullOrEmpty(uri))
4641
{
4742
Log.Warning("Failed to upload diagnostics: debugger endpoint not yet retrieved from discovery service");
4843
return false;
4944
}
5045

51-
using var response = await PostAsync(uri, data).ConfigureAwait(false);
46+
using var response = await PostAsync(uri!, data).ConfigureAwait(false);
5247
if (response.StatusCode is >= 200 and <= 299)
5348
{
5449
return true;
@@ -58,18 +53,5 @@ public override async Task<bool> SendBatchAsync(ArraySegment<byte> data)
5853
Log.Warning<int, string>("Failed to upload diagnostics with status code {StatusCode} and message: {ResponseContent}", response.StatusCode, content);
5954
return false;
6055
}
61-
62-
private Task<IApiResponse> PostAsync(string uri, ArraySegment<byte> data)
63-
{
64-
var request = _apiRequestFactory.Create(new Uri(uri));
65-
var isLegacy = uri.Contains(LegacyEndpoint);
66-
67-
return isLegacy ?
68-
request.PostAsync(data, MimeTypes.Json) :
69-
request.PostAsync(new MultipartFormItem[]
70-
{
71-
new("event", MimeTypes.Json, "event.json", data)
72-
});
73-
}
7456
}
7557
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// <copyright file="LogUploadApi.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+
#nullable enable
7+
using System;
8+
using System.Threading.Tasks;
9+
using Datadog.Trace.Agent;
10+
using Datadog.Trace.Agent.DiscoveryService;
11+
using Datadog.Trace.Configuration;
12+
using Datadog.Trace.Logging;
13+
14+
namespace Datadog.Trace.Debugger.Upload
15+
{
16+
internal class LogUploadApi : DebuggerUploadApiBase
17+
{
18+
private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor<LogUploadApi>();
19+
20+
private LogUploadApi(
21+
IApiRequestFactory apiRequestFactory,
22+
IDiscoveryService discoveryService,
23+
IGitMetadataTagsProvider gitMetadataTagsProvider)
24+
: base(apiRequestFactory, gitMetadataTagsProvider)
25+
{
26+
discoveryService.SubscribeToChanges(c => Endpoint = c.DebuggerEndpoint);
27+
}
28+
29+
public static LogUploadApi Create(
30+
IApiRequestFactory apiRequestFactory,
31+
IDiscoveryService discoveryService,
32+
IGitMetadataTagsProvider gitMetadataTagsProvider)
33+
{
34+
return new LogUploadApi(apiRequestFactory, discoveryService, gitMetadataTagsProvider);
35+
}
36+
37+
public override async Task<bool> SendBatchAsync(ArraySegment<byte> data)
38+
{
39+
var uri = BuildUri();
40+
if (string.IsNullOrEmpty(uri))
41+
{
42+
Log.Warning("Failed to upload log: debugger endpoint not yet retrieved from discovery service");
43+
return false;
44+
}
45+
46+
using var response = await PostAsync(uri!, data).ConfigureAwait(false);
47+
48+
if (response.StatusCode is >= 200 and <= 299)
49+
{
50+
return true;
51+
}
52+
53+
var content = await response.ReadAsStringAsync().ConfigureAwait(false);
54+
Log.Warning<int, string>("Failed to upload log with status code {StatusCode} and message: {ResponseContent}", response.StatusCode, content);
55+
return false;
56+
}
57+
}
58+
}

tracer/src/Datadog.Trace/Debugger/Upload/SnapshotUploadApi.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using System.Threading.Tasks;
99
using Datadog.Trace.Agent;
1010
using Datadog.Trace.Agent.DiscoveryService;
11-
using Datadog.Trace.Agent.Transports;
1211
using Datadog.Trace.Configuration;
1312
using Datadog.Trace.Logging;
1413

@@ -18,16 +17,13 @@ internal class SnapshotUploadApi : DebuggerUploadApiBase
1817
{
1918
private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor<SnapshotUploadApi>();
2019

21-
private readonly IApiRequestFactory _apiRequestFactory;
22-
2320
private SnapshotUploadApi(
2421
IApiRequestFactory apiRequestFactory,
2522
IDiscoveryService discoveryService,
2623
IGitMetadataTagsProvider gitMetadataTagsProvider)
2724
: base(apiRequestFactory, gitMetadataTagsProvider)
2825
{
29-
_apiRequestFactory = apiRequestFactory;
30-
discoveryService.SubscribeToChanges(c => Endpoint = c.DiagnosticsEndpoint);
26+
discoveryService.SubscribeToChanges(c => Endpoint = c.DebuggerV2Endpoint);
3127
}
3228

3329
public static SnapshotUploadApi Create(
@@ -47,9 +43,7 @@ public override async Task<bool> SendBatchAsync(ArraySegment<byte> data)
4743
return false;
4844
}
4945

50-
var request = _apiRequestFactory.Create(new Uri(uri));
51-
52-
using var response = await request.PostAsync(data, MimeTypes.Json).ConfigureAwait(false);
46+
using var response = await PostAsync(uri!, data).ConfigureAwait(false);
5347

5448
if (response.StatusCode is >= 200 and <= 299)
5549
{

0 commit comments

Comments
 (0)