Skip to content

feat: add injection metadata fields to telemetry forwarder #9094

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
67f321b
added result, result_class, and result_reason to injection metadata
sydney-tung Jul 3, 2025
8a1b47d
remove binaries
sydney-tung Jul 3, 2025
dfbdeb4
Merge branch 'master' into INPLAT-614
sydney-tung Jul 3, 2025
5fe42f8
undo again
sydney-tung Jul 7, 2025
f39625a
update
sydney-tung Jul 7, 2025
9765824
update
sydney-tung Jul 7, 2025
ddb245a
Merge branch 'master' into INPLAT-614
sydney-tung Jul 7, 2025
13cf611
added tests
sydney-tung Jul 7, 2025
e1b9b30
fixing error reasons
sydney-tung Jul 7, 2025
1e2dbd2
update
sydney-tung Jul 8, 2025
53e6b52
fixed success case
sydney-tung Jul 8, 2025
8c2ee53
added more tests
sydney-tung Jul 8, 2025
96f08bb
Merge branch 'master' into INPLAT-614
sydney-tung Jul 8, 2025
e9f57fe
fixed formatting
sydney-tung Jul 8, 2025
38dbfef
more concise
sydney-tung Jul 9, 2025
7868c63
update
sydney-tung Jul 9, 2025
2444bf3
Merge branch 'master' into INPLAT-614
sydney-tung Jul 9, 2025
93a74f7
update ordering
sydney-tung Jul 9, 2025
20fafe3
Merge branch 'master' into INPLAT-614
sydney-tung Jul 9, 2025
d8fe228
changed tests
sydney-tung Jul 9, 2025
0b9a9c7
fix formatting
sydney-tung Jul 9, 2025
9080656
changed tests
sydney-tung Jul 9, 2025
a601a06
fixed format
sydney-tung Jul 9, 2025
07eb21e
Merge branch 'master' into INPLAT-614
sydney-tung Jul 9, 2025
ed1c6a2
Merge branch 'master' into INPLAT-614
sydney-tung Jul 10, 2025
2e9b812
Merge branch 'master' into INPLAT-614
sydney-tung Jul 10, 2025
fa08696
fix
sydney-tung Jul 10, 2025
4fe3d47
Merge branch 'master' into INPLAT-614
sydney-tung Jul 10, 2025
b5afa83
Merge branch 'master' into INPLAT-614
sydney-tung Jul 11, 2025
032fbff
add incompatible_library
sydney-tung Jul 11, 2025
ba2423d
Merge branch 'master' into INPLAT-614
sydney-tung Jul 11, 2025
6232eb0
Merge branch 'master' into INPLAT-614
betterengineering Jul 14, 2025
b59dd8a
Merge branch 'master' into INPLAT-614
AlexeyKuznetsov-DD Jul 14, 2025
1b14908
Merge branch 'master' into INPLAT-614
sydney-tung Jul 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ replay_pid*
.bsp/
**/src/*/generated/*
!dd-java-agent/benchmark/releases/*.jar
*.jar
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do want jar, like maven and gradle wrappers. Can you revert this part please?


# Magic for local JMC built
/vendor/jmc-libs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Thread safe wrapper around BootstrapInitializationTelemetry used inside the Datadog ClassLoader.
*
* <p>Right now, this is needed because of the build separation between the two portions of the
* bootstrap. We should consider adjusting the build to allow Agent et al to reference
* bootstrap. We should consider adjusting the build to allow Agent et al. to reference
* BootstrapInitializationTelemetry, then we could remove this proxy.
*/
public abstract class InitializationTelemetry {
Expand Down Expand Up @@ -48,7 +48,7 @@ public static final InitializationTelemetry noOpInstance() {
public abstract void onFatalError(Throwable t);

/**
* Indicates that an exception conditional occurred during the bootstrapping process. By default
* Indicates that an exception conditional occurred during the bootstrapping process. By default,
* the exceptional condition is assumed to NOT have fully stopped the initialization of the
* tracer.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ public static BootstrapInitializationTelemetry createFromForwarderPath(String fo

public abstract void onError(String reasonCode);

public abstract void setInjectResult(String result);

public abstract void setInjectResultReason(String reason);

public abstract void setInjectResultClass(String resultClass);

public abstract void markIncomplete();

public abstract void finish();
Expand All @@ -77,6 +83,15 @@ public void onFatalError(Throwable t) {}
@Override
public void onError(Throwable t) {}

@Override
public void setInjectResult(String result) {}

@Override
public void setInjectResultReason(String reason) {}

@Override
public void setInjectResultClass(String resultClass) {}

@Override
public void markIncomplete() {}

Expand All @@ -92,6 +107,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;
Expand All @@ -107,15 +123,37 @@ public void initMetaInfo(String attr, String value) {
}
}

@Override
public void setInjectResult(String result) {
initMetaInfo("result", result);
}

@Override
public void setInjectResultReason(String resultReason) {
initMetaInfo("resultReason", resultReason);
}

@Override
public void setInjectResultClass(String resultClass) {
initMetaInfo("resultClass", resultClass);
}

@Override
public void onAbort(String reasonCode) {
onPoint("library_entrypoint.abort", "reason:" + reasonCode);
markIncomplete();
setInjectResult("abort");
setInjectResultReason(reasonCode);
setInjectResultClass(mapResultClass(reasonCode));
}

@Override
public void onError(Throwable t) {
error = true;
onPoint("library_entrypoint.error", "error_type:" + t.getClass().getName());
setInjectResult("error");
setInjectResultReason(t.getMessage());
setInjectResultClass("internal_error");
}

@Override
Expand All @@ -126,7 +164,27 @@ public void onFatalError(Throwable t) {

@Override
public void onError(String reasonCode) {
error = true;
onPoint("library_entrypoint.error", "error_type:" + reasonCode);
setInjectResult("error");
setInjectResultReason(reasonCode);
setInjectResultClass(mapResultClass(reasonCode));
}

private String mapResultClass(String reasonCode) {
if (reasonCode == null) {
return "success";
}
switch (reasonCode) {
case "already_initialized":
return "already_initialized";
case "other-java-agents":
return "already_instrumented";
case "jdk_tool":
return "incorrect_installation";
default:
return "unknown";
}
}

private void onPoint(String name, String tag) {
Expand All @@ -143,6 +201,11 @@ public void markIncomplete() {

@Override
public void finish() {
if (!this.incomplete && !this.error) {
setInjectResult("success");
setInjectResultReason("Successfully configured ddtrace package");
setInjectResultClass("success");
}
try (JsonWriter writer = new JsonWriter()) {
writer.beginObject();
writer.name("metadata").beginObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

/** Special lightweight pre-main class that skips installation on incompatible JVMs. */
public class AgentPreCheck {
public static final int minJavaVersion = 8;
public static void premain(final String agentArgs, final Instrumentation inst) {
agentmain(agentArgs, inst);
}
Expand Down Expand Up @@ -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:need to install a java version later than " + minJavaVersion + "\""
+ "]"
+ "}]"
+ "}";

Expand Down Expand Up @@ -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 >= minJavaVersion) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,78 @@ class BootstrapInitializationTelemetryTest extends Specification {
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() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"error","resultReason":"foo","resultClass":"internal_error"},"points":[{"name":"library_entrypoint.error","tags":["error_type:java.lang.Exception"]},{"name":"library_entrypoint.complete"}]}'
}

def "test fatal error"() {
when:
initTelemetry.initMetaInfo("runtime_name", "java")
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")

initTelemetry.onFatalError(new Exception("foo"))
initTelemetry.finish()

then:
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"error","resultReason":"foo","resultClass":"internal_error"},"points":[{"name":"library_entrypoint.error","tags":["error_type:java.lang.Exception"]}]}'
}

def "test abort"() {
when:
initTelemetry.initMetaInfo("runtime_name", "java")
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")

initTelemetry.onAbort("jdk_tool")
initTelemetry.finish()

then:
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"abort","resultReason":"jdk_tool","resultClass":"incorrect_installation"},"points":[{"name":"library_entrypoint.abort","tags":["reason:jdk_tool"]}]}'
}

def "test success"() {
when:
initTelemetry.initMetaInfo("runtime_name", "java")
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")

initTelemetry.finish()

then:
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"success","resultReason":"Successfully configured ddtrace package","resultClass":"success"},"points":[{"name":"library_entrypoint.complete"}]}'
}

def "test abort jdk_tool"() {
when:
initTelemetry.initMetaInfo("runtime_name", "java")
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")

initTelemetry.onAbort("jdk_tool")
initTelemetry.finish()

then:
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"abort","resultReason":"jdk_tool","resultClass":"incorrect_installation"},"points":[{"name":"library_entrypoint.abort","tags":["reason:jdk_tool"]}]}'
}

def "test abort other-java-agents"() {
when:
initTelemetry.initMetaInfo("runtime_name", "java")
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")

initTelemetry.onAbort("other-java-agents")
initTelemetry.finish()

then:
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"abort","resultReason":"other-java-agents","resultClass":"already_instrumented"},"points":[{"name":"library_entrypoint.abort","tags":["reason:other-java-agents"]}]}'
}

def "test abort unknown"() {
when:
initTelemetry.initMetaInfo("runtime_name", "java")
initTelemetry.initMetaInfo("runtime_version", "1.8.0_382")

initTelemetry.onAbort("foo")
initTelemetry.finish()

then:
capture.json() == '{"metadata":{"runtime_name":"java","runtime_version":"1.8.0_382","result":"abort","resultReason":"foo","resultClass":"unknown"},"points":[{"name":"library_entrypoint.abort","tags":["reason:foo"]}]}'
}

def "trivial completion check"() {
Expand Down
Loading