Skip to content

Commit a6af97e

Browse files
authored
feat: add injection metadata fields to telemetry forwarder (#9185)
* edit * debug * fix * edit
1 parent d1794c1 commit a6af97e

File tree

4 files changed

+83
-7
lines changed

4 files changed

+83
-7
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public static final class JsonBased extends BootstrapInitializationTelemetry {
9292

9393
// one way false to true
9494
private volatile boolean incomplete = false;
95+
private volatile boolean error = false;
9596

9697
JsonBased(JsonSender sender) {
9798
this.sender = sender;
@@ -111,11 +112,14 @@ public void initMetaInfo(String attr, String value) {
111112
public void onAbort(String reasonCode) {
112113
onPoint("library_entrypoint.abort", "reason:" + reasonCode);
113114
markIncomplete();
115+
setMetaInfo("abort", mapResultClass(reasonCode), reasonCode);
114116
}
115117

116118
@Override
117119
public void onError(Throwable t) {
120+
error = true;
118121
onPoint("library_entrypoint.error", "error_type:" + t.getClass().getName());
122+
setMetaInfo("error", "internal_error", t.getMessage());
119123
}
120124

121125
@Override
@@ -126,7 +130,32 @@ public void onFatalError(Throwable t) {
126130

127131
@Override
128132
public void onError(String reasonCode) {
133+
error = true;
129134
onPoint("library_entrypoint.error", "error_type:" + reasonCode);
135+
setMetaInfo("error", mapResultClass(reasonCode), reasonCode);
136+
}
137+
138+
private void setMetaInfo(String result, String resultClass, String resultReason) {
139+
initMetaInfo("result", result);
140+
initMetaInfo("result_class", resultClass);
141+
initMetaInfo("result_reason", resultReason);
142+
}
143+
144+
private String mapResultClass(String reasonCode) {
145+
if (reasonCode == null) {
146+
return "success";
147+
}
148+
149+
switch (reasonCode) {
150+
case "already_initialized":
151+
return "already_instrumented";
152+
case "other-java-agents":
153+
return "incompatible_library";
154+
case "jdk_tool":
155+
return "unsupported_binary";
156+
default:
157+
return "unknown";
158+
}
130159
}
131160

132161
private void onPoint(String name, String tag) {
@@ -143,6 +172,10 @@ public void markIncomplete() {
143172

144173
@Override
145174
public void finish() {
175+
if (!this.incomplete && !this.error) {
176+
setMetaInfo("success", "success", "Successfully configured ddtrace package");
177+
}
178+
146179
try (JsonWriter writer = new JsonWriter()) {
147180
writer.beginObject();
148181
writer.name("metadata").beginObject();

dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
/** Special lightweight pre-main class that skips installation on incompatible JVMs. */
1313
public class AgentPreCheck {
14+
public static final int MIN_JAVA_VERSION = 8;
15+
1416
public static void premain(final String agentArgs, final Instrumentation inst) {
1517
agentmain(agentArgs, inst);
1618
}
@@ -55,7 +57,11 @@ static void sendTelemetry(String forwarderPath, String javaVersion, String agent
5557
+ "\","
5658
+ "\"tracer_version\":\""
5759
+ agentVersion
58-
+ "\"},"
60+
+ "\","
61+
+ "\"result\":\"abort\","
62+
+ "\"result_class\":\"unknown\","
63+
+ "\"result_reason\":\"incompatible_runtime\""
64+
+ "},"
5965
+ "\"points\":[{"
6066
+ "\"name\":\"library_entrypoint.abort\","
6167
+ "\"tags\":[\"reason:incompatible_runtime\"]"
@@ -87,7 +93,7 @@ private static boolean compatible() {
8793
static boolean compatible(String javaVersion, String javaHome, PrintStream output) {
8894
int majorJavaVersion = parseJavaMajorVersion(javaVersion);
8995

90-
if (majorJavaVersion >= 8) {
96+
if (majorJavaVersion >= MIN_JAVA_VERSION) {
9197
return true;
9298
}
9399

dd-java-agent/src/test/groovy/datadog/trace/bootstrap/AgentPreCheckTest.groovy

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,10 @@ class AgentPreCheckTest extends Specification {
125125
"language_name": "jvm",
126126
"runtime_version": "1.6.0_45",
127127
"language_version": "1.6.0_45",
128-
"tracer_version": "1.50"
128+
"tracer_version": "1.50",
129+
"result": "abort",
130+
"result_class": "unknown",
131+
"result_reason": "incompatible_runtime"
129132
},
130133
"points": [
131134
{

dd-java-agent/src/test/groovy/datadog/trace/bootstrap/BootstrapInitializationTelemetryTest.groovy

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,47 @@ class BootstrapInitializationTelemetryTest extends Specification {
2626
initTelemetryProxy.setAdaptee(initTelemetry)
2727

2828
this.initTelemetry = initTelemetryProxy
29+
this.initTelemetry.initMetaInfo("runtime_name", "java")
30+
this.initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")
2931
this.capture = capture
3032
}
3133

32-
def "real example"() {
34+
def "test success"() {
3335
when:
34-
initTelemetry.initMetaInfo("runtime_name", "java")
35-
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")
36+
initTelemetry.finish()
37+
38+
then:
39+
capture.json() == json("success", "success", "Successfully configured ddtrace package",
40+
[[name: "library_entrypoint.complete"]])
41+
}
3642

43+
def "real example"() {
44+
when:
3745
initTelemetry.onError(new Exception("foo"))
3846
initTelemetry.finish()
3947

4048
then:
41-
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382"},"points":[{"name":"library_entrypoint.error","tags":["error_type:java.lang.Exception"]},{"name":"library_entrypoint.complete"}]}'
49+
capture.json() == json("error", "internal_error", "foo", [
50+
[name: "library_entrypoint.error", tags: ["error_type:java.lang.Exception"]],
51+
[name: "library_entrypoint.complete"]
52+
])
53+
}
54+
55+
def "test abort"() {
56+
when:
57+
initTelemetry.onAbort(reasonCode)
58+
initTelemetry.finish()
59+
60+
then:
61+
capture.json() == json("abort", resultClass, reasonCode,
62+
[[name: "library_entrypoint.abort", tags: ["reason:${reasonCode}"]]])
63+
64+
where:
65+
reasonCode | resultClass
66+
"jdk_tool" | "unsupported_binary"
67+
"already_initialized" | "already_instrumented"
68+
"other-java-agents" | "incompatible_library"
69+
"foo" | "unknown"
4270
}
4371

4472
def "trivial completion check"() {
@@ -65,6 +93,8 @@ class BootstrapInitializationTelemetryTest extends Specification {
6593

6694
then:
6795
!capture.json().contains("library_entrypoint.complete")
96+
capture.json() == json("error", "internal_error", "foo",
97+
[[name: "library_entrypoint.error", tags: ["error_type:java.lang.Exception"]]])
6898
}
6999

70100
def "incomplete on abort"() {
@@ -76,6 +106,10 @@ class BootstrapInitializationTelemetryTest extends Specification {
76106
!capture.json().contains("library_entrypoint.complete")
77107
}
78108

109+
private String json(String result, String resultClass, String resultReason, List points) {
110+
return """{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"${result}","result_class":"${resultClass}","result_reason":"${resultReason}"},"points":${new groovy.json.JsonBuilder(points)}}"""
111+
}
112+
79113
static class Capture implements BootstrapInitializationTelemetry.JsonSender {
80114
String json
81115

0 commit comments

Comments
 (0)