From a9c496eb5b21ac11df5a559aec2152f7155a4569 Mon Sep 17 00:00:00 2001 From: Sydney Tung Date: Wed, 16 Jul 2025 09:38:11 -0400 Subject: [PATCH 1/4] edit --- .../BootstrapInitializationTelemetry.java | 33 +++++++++++++++ .../trace/bootstrap/AgentPreCheck.java | 7 +++- ...ootstrapInitializationTelemetryTest.groovy | 42 +++++++++++++++++-- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java b/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java index 6e09fa0f30a..a276ff9e8a2 100644 --- a/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java +++ b/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java @@ -92,6 +92,7 @@ public static final class JsonBased extends BootstrapInitializationTelemetry { // one way false to true private volatile boolean incomplete = false; + private volatile boolean error = false; JsonBased(JsonSender sender) { this.sender = sender; @@ -111,11 +112,14 @@ public void initMetaInfo(String attr, String value) { public void onAbort(String reasonCode) { onPoint("library_entrypoint.abort", "reason:" + reasonCode); markIncomplete(); + setMetadata("abort", mapResultClass(reasonCode), reasonCode); } @Override public void onError(Throwable t) { + error = true; onPoint("library_entrypoint.error", "error_type:" + t.getClass().getName()); + setMetadata("error", "internal_error", t.getMessage()); } @Override @@ -126,7 +130,32 @@ public void onFatalError(Throwable t) { @Override public void onError(String reasonCode) { + error = true; onPoint("library_entrypoint.error", "error_type:" + reasonCode); + setMetadata("error", mapResultClass(reasonCode), reasonCode); + } + + private void setMetadata(String result, String resultClass, String resultReason) { + initMetaInfo("result", result); + initMetaInfo("result_class", resultClass); + initMetaInfo("result_reason", resultReason); + } + + private String mapResultClass(String reasonCode) { + if (reasonCode == null) { + return "success"; + } + + switch (reasonCode) { + case "already_initialized": + return "already_instrumented"; + case "other-java-agents": + return "incompatible_library"; + case "jdk_tool": + return "unsupported_binary"; + default: + return "unknown"; + } } private void onPoint(String name, String tag) { @@ -143,6 +172,10 @@ public void markIncomplete() { @Override public void finish() { + if (!this.incomplete && !this.error) { + setMetadata("success", "success", "Successfully configured ddtrace package"); + } + try (JsonWriter writer = new JsonWriter()) { writer.beginObject(); writer.name("metadata").beginObject(); diff --git a/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java b/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java index a2919226eb5..6503ff44d10 100644 --- a/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java +++ b/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java @@ -11,6 +11,7 @@ /** Special lightweight pre-main class that skips installation on incompatible JVMs. */ public class AgentPreCheck { + public static final int MIN_JAVA_VERSION = 8; public static void premain(final String agentArgs, final Instrumentation inst) { agentmain(agentArgs, inst); } @@ -59,6 +60,10 @@ static void sendTelemetry(String forwarderPath, String javaVersion, String agent + "\"points\":[{" + "\"name\":\"library_entrypoint.abort\"," + "\"tags\":[\"reason:incompatible_runtime\"]" + + "\"result:error\"," + + "\"result_class:incompatible_runtime\"," + + "\"result_reason:java version" + MIN_JAVA_VERSION + "+ required\"" + + "]" + "}]" + "}"; @@ -87,7 +92,7 @@ private static boolean compatible() { static boolean compatible(String javaVersion, String javaHome, PrintStream output) { int majorJavaVersion = parseJavaMajorVersion(javaVersion); - if (majorJavaVersion >= 8) { + if (majorJavaVersion >= MIN_JAVA_VERSION) { return true; } diff --git a/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/BootstrapInitializationTelemetryTest.groovy b/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/BootstrapInitializationTelemetryTest.groovy index da0dafa6d4a..c5506a343d0 100644 --- a/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/BootstrapInitializationTelemetryTest.groovy +++ b/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/BootstrapInitializationTelemetryTest.groovy @@ -26,19 +26,47 @@ class BootstrapInitializationTelemetryTest extends Specification { initTelemetryProxy.setAdaptee(initTelemetry) this.initTelemetry = initTelemetryProxy + this.initTelemetry.initMetaInfo("runtime_name", "java") + this.initTelemetry.initMetaInfo("runtime_version", "1.8.0_382") this.capture = capture } - def "real example"() { + def "test success"() { when: - initTelemetry.initMetaInfo("runtime_name", "java") - initTelemetry.initMetaInfo("runtime_version", "1.8.0_382") + initTelemetry.finish() + + then: + capture.json() == json("success", "success", "Successfully configured ddtrace package", + [[name: "library_entrypoint.complete"]]) + } + def "real example"() { + when: initTelemetry.onError(new Exception("foo")) initTelemetry.finish() then: - 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"}]}' + capture.json() == json("error", "internal_error", "foo", [ + [name: "library_entrypoint.error", tags: ["error_type:java.lang.Exception"]], + [name: "library_entrypoint.complete"] + ]) + } + + def "test abort"() { + when: + initTelemetry.onAbort(reasonCode) + initTelemetry.finish() + + then: + capture.json() == json("abort", resultClass, reasonCode, + [[name: "library_entrypoint.abort", tags: ["reason:${reasonCode}"]]]) + + where: + reasonCode | resultClass + "jdk_tool" | "unsupported_binary" + "already_initialized" | "already_instrumented" + "other-java-agents" | "incompatible_library" + "foo" | "unknown" } def "trivial completion check"() { @@ -65,6 +93,8 @@ class BootstrapInitializationTelemetryTest extends Specification { then: !capture.json().contains("library_entrypoint.complete") + capture.json() == json("error", "internal_error", "foo", + [[name: "library_entrypoint.error", tags: ["error_type:java.lang.Exception"]]]) } def "incomplete on abort"() { @@ -76,6 +106,10 @@ class BootstrapInitializationTelemetryTest extends Specification { !capture.json().contains("library_entrypoint.complete") } + private String json(String result, String resultClass, String resultReason, List points) { + 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)}}""" + } + static class Capture implements BootstrapInitializationTelemetry.JsonSender { String json From cfe15d6da35bd9bb7f52c279ee04b06a9fd9177b Mon Sep 17 00:00:00 2001 From: Sydney Tung Date: Wed, 16 Jul 2025 14:22:24 -0400 Subject: [PATCH 2/4] debug --- .../main/java6/datadog/trace/bootstrap/AgentPreCheck.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java b/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java index 6503ff44d10..0326dbb7e7d 100644 --- a/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java +++ b/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java @@ -12,6 +12,7 @@ /** Special lightweight pre-main class that skips installation on incompatible JVMs. */ public class AgentPreCheck { public static final int MIN_JAVA_VERSION = 8; + public static void premain(final String agentArgs, final Instrumentation inst) { agentmain(agentArgs, inst); } @@ -62,7 +63,9 @@ static void sendTelemetry(String forwarderPath, String javaVersion, String agent + "\"tags\":[\"reason:incompatible_runtime\"]" + "\"result:error\"," + "\"result_class:incompatible_runtime\"," - + "\"result_reason:java version" + MIN_JAVA_VERSION + "+ required\"" + + "\"result_reason:java version" + + MIN_JAVA_VERSION + + "+ required\"" + "]" + "}]" + "}"; From a2ed73d317b54c1d9b8ca7963ff4034501adc3dd Mon Sep 17 00:00:00 2001 From: Sydney Tung Date: Wed, 16 Jul 2025 21:51:38 -0400 Subject: [PATCH 3/4] fix --- .../java6/datadog/trace/bootstrap/AgentPreCheck.java | 12 +++++------- .../datadog/trace/bootstrap/AgentPreCheckTest.groovy | 5 ++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java b/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java index 0326dbb7e7d..3ec4f41a4d7 100644 --- a/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java +++ b/dd-java-agent/src/main/java6/datadog/trace/bootstrap/AgentPreCheck.java @@ -57,16 +57,14 @@ static void sendTelemetry(String forwarderPath, String javaVersion, String agent + "\"," + "\"tracer_version\":\"" + agentVersion - + "\"}," + + "\"," + + "\"result\":\"abort\"," + + "\"result_class\":\"unknown\"," + + "\"result_reason\":\"incompatible_runtime\"" + + "}," + "\"points\":[{" + "\"name\":\"library_entrypoint.abort\"," + "\"tags\":[\"reason:incompatible_runtime\"]" - + "\"result:error\"," - + "\"result_class:incompatible_runtime\"," - + "\"result_reason:java version" - + MIN_JAVA_VERSION - + "+ required\"" - + "]" + "}]" + "}"; diff --git a/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/AgentPreCheckTest.groovy b/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/AgentPreCheckTest.groovy index e67614813b5..fef98032091 100644 --- a/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/AgentPreCheckTest.groovy +++ b/dd-java-agent/src/test/groovy/datadog/trace/bootstrap/AgentPreCheckTest.groovy @@ -125,7 +125,10 @@ class AgentPreCheckTest extends Specification { "language_name": "jvm", "runtime_version": "1.6.0_45", "language_version": "1.6.0_45", - "tracer_version": "1.50" + "tracer_version": "1.50", + "result": "abort", + "result_class": "unknown", + "result_reason": "incompatible_runtime" }, "points": [ { From b1832131956f2266ba29d32be7fffa14a10554ee Mon Sep 17 00:00:00 2001 From: Sydney Tung Date: Wed, 16 Jul 2025 21:59:55 -0400 Subject: [PATCH 4/4] edit --- .../bootstrap/BootstrapInitializationTelemetry.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java b/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java index a276ff9e8a2..55dd6b4ef23 100644 --- a/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java +++ b/dd-java-agent/src/main/java/datadog/trace/bootstrap/BootstrapInitializationTelemetry.java @@ -112,14 +112,14 @@ public void initMetaInfo(String attr, String value) { public void onAbort(String reasonCode) { onPoint("library_entrypoint.abort", "reason:" + reasonCode); markIncomplete(); - setMetadata("abort", mapResultClass(reasonCode), reasonCode); + setMetaInfo("abort", mapResultClass(reasonCode), reasonCode); } @Override public void onError(Throwable t) { error = true; onPoint("library_entrypoint.error", "error_type:" + t.getClass().getName()); - setMetadata("error", "internal_error", t.getMessage()); + setMetaInfo("error", "internal_error", t.getMessage()); } @Override @@ -132,10 +132,10 @@ public void onFatalError(Throwable t) { public void onError(String reasonCode) { error = true; onPoint("library_entrypoint.error", "error_type:" + reasonCode); - setMetadata("error", mapResultClass(reasonCode), reasonCode); + setMetaInfo("error", mapResultClass(reasonCode), reasonCode); } - private void setMetadata(String result, String resultClass, String resultReason) { + private void setMetaInfo(String result, String resultClass, String resultReason) { initMetaInfo("result", result); initMetaInfo("result_class", resultClass); initMetaInfo("result_reason", resultReason); @@ -173,7 +173,7 @@ public void markIncomplete() { @Override public void finish() { if (!this.incomplete && !this.error) { - setMetadata("success", "success", "Successfully configured ddtrace package"); + setMetaInfo("success", "success", "Successfully configured ddtrace package"); } try (JsonWriter writer = new JsonWriter()) {