Skip to content

Commit 248efa2

Browse files
committed
Add long_running_traces.json to flare report
Synchronized accesses to traceArray in LongRunningTracesTracker since the flare reporter can now access the array. This shouldn't be a concern for blocking because addTrace and flushAndCompact are the existing calls from PendingTraceBuffer's run() loop and getTracesAsJson is called by the reporter thread and will complete fairly quickly.
1 parent c0c4ef7 commit 248efa2

File tree

4 files changed

+83
-4
lines changed

4 files changed

+83
-4
lines changed

dd-trace-core/src/main/java/datadog/trace/core/LongRunningTracesTracker.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
44
import datadog.communication.ddagent.SharedCommunicationObjects;
55
import datadog.trace.api.Config;
6+
import datadog.trace.api.flare.TracerFlare;
7+
import datadog.trace.common.writer.TraceDumpJsonExporter;
68
import datadog.trace.core.monitor.HealthMetrics;
9+
import java.io.IOException;
710
import java.util.ArrayList;
811
import java.util.List;
912
import java.util.concurrent.TimeUnit;
13+
import java.util.zip.ZipOutputStream;
1014

11-
public class LongRunningTracesTracker {
15+
public class LongRunningTracesTracker implements TracerFlare.Reporter {
1216
private final DDAgentFeaturesDiscovery features;
1317
private final HealthMetrics healthMetrics;
1418
private long lastFlushMilli = 0;
@@ -41,6 +45,8 @@ public LongRunningTracesTracker(
4145
(int) TimeUnit.SECONDS.toMillis(config.getLongRunningTraceFlushInterval());
4246
this.features = sharedCommunicationObjects.featuresDiscovery(config);
4347
this.healthMetrics = healthMetrics;
48+
49+
TracerFlare.addReporter(this);
4450
}
4551

4652
public boolean add(PendingTraceBuffer.Element element) {
@@ -56,7 +62,7 @@ public boolean add(PendingTraceBuffer.Element element) {
5662
return true;
5763
}
5864

59-
private void addTrace(PendingTrace trace) {
65+
private synchronized void addTrace(PendingTrace trace) {
6066
if (trace.empty()) {
6167
return;
6268
}
@@ -67,7 +73,7 @@ private void addTrace(PendingTrace trace) {
6773
traceArray.add(trace);
6874
}
6975

70-
public void flushAndCompact(long nowMilli) {
76+
public synchronized void flushAndCompact(long nowMilli) {
7177
if (nowMilli < lastFlushMilli + TimeUnit.SECONDS.toMillis(1)) {
7278
return;
7379
}
@@ -139,4 +145,18 @@ private void flushStats() {
139145
write = 0;
140146
expired = 0;
141147
}
148+
149+
public synchronized String getTracesAsJson() {
150+
try (TraceDumpJsonExporter writer = new TraceDumpJsonExporter()) {
151+
for (PendingTrace trace : traceArray) {
152+
writer.write(trace.getSpans());
153+
}
154+
return writer.getDumpJson();
155+
}
156+
}
157+
158+
@Override
159+
public void addReportToFlare(ZipOutputStream zip) throws IOException {
160+
TracerFlare.addText(zip, "long_running_traces.txt", getTracesAsJson());
161+
}
142162
}

dd-trace-core/src/main/java/datadog/trace/core/PendingTraceBuffer.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public interface Element {
5454
}
5555

5656
private static class DelayingPendingTraceBuffer extends PendingTraceBuffer {
57+
private static final Logger LOGGER = LoggerFactory.getLogger(DelayingPendingTraceBuffer.class);
5758
private static final long FORCE_SEND_DELAY_MS = TimeUnit.SECONDS.toMillis(5);
5859
private static final long SEND_DELAY_NS = TimeUnit.MILLISECONDS.toNanos(500);
5960
private static final long SLEEP_TIME_MS = 100;
@@ -315,6 +316,17 @@ public void run() {
315316
}
316317
}
317318

319+
@Override
320+
public String getTracesAsJson() throws IOException {
321+
dumpTraces();
322+
String json = getDumpJson();
323+
if (json.isEmpty()) {
324+
return "[]";
325+
} else {
326+
return json;
327+
}
328+
}
329+
318330
public DelayingPendingTraceBuffer(
319331
int bufferSize,
320332
TimeSource timeSource,
@@ -350,6 +362,11 @@ public void enqueue(Element pendingTrace) {
350362
log.debug(
351363
"PendingTrace enqueued but won't be reported. Root span: {}", pendingTrace.getRootSpan());
352364
}
365+
366+
@Override
367+
public String getTracesAsJson() {
368+
return "[]";
369+
}
353370
}
354371

355372
public static PendingTraceBuffer delaying(
@@ -374,6 +391,8 @@ public static PendingTraceBuffer discarding() {
374391

375392
public abstract void enqueue(Element pendingTrace);
376393

394+
public abstract String getTracesAsJson() throws IOException;
395+
377396
private static class TracerDump implements TracerFlare.Reporter {
378397
private final DelayingPendingTraceBuffer buffer;
379398

dd-trace-core/src/test/groovy/datadog/trace/core/LongRunningTracesTrackerTest.groovy

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,44 @@ class LongRunningTracesTrackerTest extends DDSpecification {
192192
PrioritySampling.USER_KEEP | 1 | LongRunningTracesTracker.WRITE_RUNNING_SPANS
193193
PrioritySampling.SAMPLER_KEEP | 1 | LongRunningTracesTracker.WRITE_RUNNING_SPANS
194194
}
195+
196+
def "getTracesAsJson with no traces"() {
197+
when:
198+
def json = tracker.getTracesAsJson()
199+
200+
then:
201+
json == ""
202+
}
203+
204+
def "getTracesAsJson with traces"() {
205+
given:
206+
def trace = newTraceToTrack()
207+
tracker.add(trace)
208+
209+
when:
210+
def json = tracker.getTracesAsJson()
211+
212+
then:
213+
json != null
214+
!json.isEmpty()
215+
json.contains('"service"')
216+
json.contains('"name"')
217+
}
218+
219+
def "testing tracer flare dump with trace"() {
220+
given:
221+
def trace = newTraceToTrack()
222+
tracker.add(trace)
223+
224+
when:
225+
def entries = PendingTraceBufferTest.buildAndExtractZip()
226+
227+
then:
228+
entries.size() == 1
229+
entries.containsKey("long_running_traces.txt")
230+
231+
def jsonContent = entries["long_running_traces.txt"] as String
232+
jsonContent.contains('"service"')
233+
jsonContent.contains('"name"')
234+
}
195235
}

dd-trace-core/src/test/groovy/datadog/trace/core/PendingTraceBufferTest.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ class PendingTraceBufferTest extends DDSpecification {
582582
return DDSpan.create("test", 0, context, null)
583583
}
584584

585-
def buildAndExtractZip() {
585+
def static buildAndExtractZip() {
586586
TracerFlare.prepareForFlare()
587587
def out = new ByteArrayOutputStream()
588588
try (ZipOutputStream zip = new ZipOutputStream(out)) {

0 commit comments

Comments
 (0)