Skip to content

Commit 64d3c2b

Browse files
Move JSON generation to sender thread to improve startup time.
1 parent 887ea39 commit 64d3c2b

File tree

2 files changed

+114
-133
lines changed

2 files changed

+114
-133
lines changed

dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java

Lines changed: 66 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.io.Closeable;
77
import java.io.OutputStream;
88
import java.util.ArrayList;
9-
import java.util.Collections;
9+
import java.util.Arrays;
1010
import java.util.LinkedHashMap;
1111
import java.util.List;
1212
import java.util.Map;
@@ -51,14 +51,14 @@ public static BootstrapInitializationTelemetry createFromForwarderPath(String fo
5151
*/
5252
public abstract void onError(Throwable t);
5353

54+
public abstract void onError(String reasonCode);
55+
5456
/**
5557
* Indicates an exception that occurred during the bootstrapping process that left initialization
5658
* incomplete. Equivalent to calling {@link #onError(Throwable)} and {@link #markIncomplete()}
5759
*/
5860
public abstract void onFatalError(Throwable t);
5961

60-
public abstract void onError(String reasonCode);
61-
6262
public abstract void markIncomplete();
6363

6464
public abstract void finish();
@@ -78,10 +78,10 @@ public void onAbort(String reasonCode) {}
7878
public void onError(String reasonCode) {}
7979

8080
@Override
81-
public void onFatalError(Throwable t) {}
81+
public void onError(Throwable t) {}
8282

8383
@Override
84-
public void onError(Throwable t) {}
84+
public void onFatalError(Throwable t) {}
8585

8686
@Override
8787
public void markIncomplete() {}
@@ -93,24 +93,24 @@ public void finish() {}
9393
public static final class JsonBased extends BootstrapInitializationTelemetry {
9494
private final JsonSender sender;
9595

96-
private final List<String> meta;
96+
private final Map<String, String> meta;
9797
private final Map<String, List<String>> points;
9898

9999
// one way false to true
100100
private volatile boolean incomplete = false;
101-
private volatile boolean error = false;
102101

103102
JsonBased(JsonSender sender) {
104103
this.sender = sender;
105-
this.meta = new ArrayList<>();
104+
this.meta = new LinkedHashMap<>();
106105
this.points = new LinkedHashMap<>();
106+
107+
setMetaInfo("success", "success", "Successfully configured ddtrace package");
107108
}
108109

109110
@Override
110111
public void initMetaInfo(String attr, String value) {
111112
synchronized (this.meta) {
112-
this.meta.add(attr);
113-
this.meta.add(value);
113+
this.meta.put(attr, value);
114114
}
115115
}
116116

@@ -123,7 +123,6 @@ public void onAbort(String reasonCode) {
123123

124124
@Override
125125
public void onError(Throwable t) {
126-
error = true;
127126
setMetaInfo("error", "internal_error", t.getMessage());
128127

129128
List<String> causes = new ArrayList<>();
@@ -142,7 +141,13 @@ public void onError(Throwable t) {
142141
causes = causes.subList(numCauses - maxTags, numCauses);
143142
}
144143

145-
onPoint("library_entrypoint.error", causes);
144+
onPoint("library_entrypoint.error", causes.toArray(new String[0]));
145+
}
146+
147+
@Override
148+
public void onError(String reasonCode) {
149+
onPoint("library_entrypoint.error", "error_type:" + reasonCode);
150+
setMetaInfo("error", mapResultClass(reasonCode), reasonCode);
146151
}
147152

148153
private int maxTags() {
@@ -165,13 +170,6 @@ public void onFatalError(Throwable t) {
165170
markIncomplete();
166171
}
167172

168-
@Override
169-
public void onError(String reasonCode) {
170-
error = true;
171-
onPoint("library_entrypoint.error", "error_type:" + reasonCode);
172-
setMetaInfo("error", mapResultClass(reasonCode), reasonCode);
173-
}
174-
175173
private void setMetaInfo(String result, String resultClass, String resultReason) {
176174
initMetaInfo("result", result);
177175
initMetaInfo("result_class", resultClass);
@@ -195,13 +193,9 @@ private String mapResultClass(String reasonCode) {
195193
}
196194
}
197195

198-
private void onPoint(String name, String tag) {
199-
onPoint(name, Collections.singletonList(tag));
200-
}
201-
202-
private void onPoint(String name, List<String> tags) {
196+
private void onPoint(String name, String... tags) {
203197
synchronized (this.points) {
204-
this.points.put(name, tags);
198+
this.points.put(name, Arrays.asList(tags));
205199
}
206200
}
207201

@@ -212,51 +206,16 @@ public void markIncomplete() {
212206

213207
@Override
214208
public void finish() {
215-
if (!this.incomplete && !this.error) {
216-
setMetaInfo("success", "success", "Successfully configured ddtrace package");
209+
if (!this.incomplete) {
210+
onPoint("library_entrypoint.complete");
217211
}
218212

219-
try (JsonWriter writer = new JsonWriter()) {
220-
writer.beginObject();
221-
writer.name("metadata").beginObject();
222-
synchronized (this.meta) {
223-
for (int i = 0; i + 1 < this.meta.size(); i = i + 2) {
224-
writer.name(this.meta.get(i));
225-
writer.value(this.meta.get(i + 1));
226-
}
227-
}
228-
writer.endObject();
229-
230-
writer.name("points").beginArray();
231-
synchronized (this.points) {
232-
for (Map.Entry<String, List<String>> entry : points.entrySet()) {
233-
writer.beginObject();
234-
writer.name("name").value(entry.getKey());
235-
writer.name("tags").beginArray();
236-
for (String tag : entry.getValue()) {
237-
writer.value(tag);
238-
}
239-
writer.endArray();
240-
writer.endObject();
241-
}
242-
this.points.clear();
243-
}
244-
if (!this.incomplete) {
245-
writer.beginObject().name("name").value("library_entrypoint.complete").endObject();
246-
}
247-
writer.endArray();
248-
writer.endObject();
249-
250-
this.sender.send(writer.toByteArray());
251-
} catch (Throwable t) {
252-
// Since this is the reporting mechanism, there's little recourse here
253-
// Decided to simply ignore - arguably might want to write to stderr
254-
}
213+
this.sender.send(meta, points);
255214
}
256215
}
257216

258217
public interface JsonSender {
259-
void send(byte[] payload);
218+
void send(Map<String, String> meta, Map<String, List<String>> points);
260219
}
261220

262221
public static final class ForwarderJsonSender implements JsonSender {
@@ -267,21 +226,24 @@ public static final class ForwarderJsonSender implements JsonSender {
267226
}
268227

269228
@Override
270-
public void send(byte[] payload) {
271-
ForwarderJsonSenderThread t = new ForwarderJsonSenderThread(forwarderPath, payload);
229+
public void send(Map<String, String> meta, Map<String, List<String>> points) {
230+
ForwarderJsonSenderThread t = new ForwarderJsonSenderThread(forwarderPath, meta, points);
272231
t.setDaemon(true);
273232
t.start();
274233
}
275234
}
276235

277236
public static final class ForwarderJsonSenderThread extends Thread {
278237
private final String forwarderPath;
279-
private final byte[] payload;
238+
private final Map<String, String> meta;
239+
private final Map<String, List<String>> points;
280240

281-
public ForwarderJsonSenderThread(String forwarderPath, byte[] payload) {
241+
public ForwarderJsonSenderThread(
242+
String forwarderPath, Map<String, String> meta, Map<String, List<String>> points) {
282243
super("dd-forwarder-json-sender");
283244
this.forwarderPath = forwarderPath;
284-
this.payload = payload;
245+
this.meta = meta;
246+
this.points = points;
285247
}
286248

287249
@SuppressForbidden
@@ -291,6 +253,8 @@ public void run() {
291253

292254
// Run forwarder and mute tracing for subprocesses executed in by dd-java-agent.
293255
try (final Closeable ignored = muteTracing()) {
256+
byte[] payload = json();
257+
294258
Process process = builder.start();
295259
try (OutputStream out = process.getOutputStream()) {
296260
out.write(payload);
@@ -301,6 +265,39 @@ public void run() {
301265
}
302266
}
303267

268+
private byte[] json() {
269+
try (JsonWriter writer = new JsonWriter()) {
270+
writer.beginObject();
271+
writer.name("metadata").beginObject();
272+
synchronized (this.meta) {
273+
for (Map.Entry<String, String> entry : meta.entrySet()) {
274+
writer.name(entry.getKey());
275+
writer.value(entry.getValue());
276+
}
277+
}
278+
writer.endObject();
279+
280+
writer.name("points").beginArray();
281+
synchronized (this.points) {
282+
for (Map.Entry<String, List<String>> entry : points.entrySet()) {
283+
writer.beginObject();
284+
writer.name("name").value(entry.getKey());
285+
writer.name("tags").beginArray();
286+
for (String tag : entry.getValue()) {
287+
writer.value(tag);
288+
}
289+
writer.endArray();
290+
writer.endObject();
291+
}
292+
this.points.clear();
293+
}
294+
writer.endArray();
295+
writer.endObject();
296+
297+
return writer.toByteArray();
298+
}
299+
}
300+
304301
@SuppressForbidden
305302
private Closeable muteTracing() {
306303
try {

0 commit comments

Comments
 (0)