From 5885d740cf9eb90ad741e4226ee456e8588f9837 Mon Sep 17 00:00:00 2001 From: Andrew Kent Date: Mon, 20 Apr 2026 22:18:21 -0600 Subject: [PATCH] add fallback logic to other jaavagent detector --- .../dev/braintrust/system/AgentBootstrap.java | 53 +++++++++++++++---- .../braintrust/system/AgentBootstrapTest.java | 20 +++++++ 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/braintrust-java-agent/bootstrap/src/main/java/dev/braintrust/system/AgentBootstrap.java b/braintrust-java-agent/bootstrap/src/main/java/dev/braintrust/system/AgentBootstrap.java index 048d2685..bdca80a0 100644 --- a/braintrust-java-agent/bootstrap/src/main/java/dev/braintrust/system/AgentBootstrap.java +++ b/braintrust-java-agent/bootstrap/src/main/java/dev/braintrust/system/AgentBootstrap.java @@ -117,21 +117,54 @@ static List detectAgents() { try { var info = ProcessHandle.current().info(); var arguments = info.arguments(); - if (arguments.isEmpty()) return agents; - for (var arg : arguments.get()) { - if (!arg.startsWith("-javaagent:")) continue; - // Strip optional =agentargs suffix: -javaagent:/path/to.jar=args - var jarPath = arg.substring("-javaagent:".length()); - var eqIdx = jarPath.indexOf('='); - if (eqIdx >= 0) jarPath = jarPath.substring(0, eqIdx); - agents.add(classifyAgentJar(jarPath)); + if (arguments.isPresent()) { + for (var arg : arguments.get()) { + if (!arg.startsWith("-javaagent:")) continue; + agents.add(classifyAgentJar(stripAgentPath(arg))); + } + } else { + // arguments() is often empty on Linux; fall back to commandLine() + var cmdLine = info.commandLine(); + if (cmdLine.isPresent()) { + agents.addAll(detectAgentsFromCommandLine(cmdLine.get())); + } } - } catch (Throwable ignored) { - // ProcessHandle unavailable — return empty, callers fall back gracefully. + } catch (Throwable t) { + log("error detecting agents: " + t.getMessage()); + log(t); + } + return agents; + } + + /** Extracts {@code -javaagent:} entries from a raw command line string. */ + static List detectAgentsFromCommandLine(String cmdLine) { + var agents = new ArrayList(); + var prefix = "-javaagent:"; + int idx = 0; + while ((idx = cmdLine.indexOf(prefix, idx)) >= 0) { + int start = idx + prefix.length(); + // The jar path ends at the next whitespace (or end of string). + // An '=' before whitespace separates jar path from agent args. + int end = start; + while (end < cmdLine.length() && cmdLine.charAt(end) != ' ') { + end++; + } + var token = cmdLine.substring(start, end); + var eqIdx = token.indexOf('='); + var jarPath = eqIdx >= 0 ? token.substring(0, eqIdx) : token; + agents.add(classifyAgentJar(jarPath)); + idx = end; } return agents; } + private static String stripAgentPath(String arg) { + var jarPath = arg.substring("-javaagent:".length()); + var eqIdx = jarPath.indexOf('='); + if (eqIdx >= 0) jarPath = jarPath.substring(0, eqIdx); + return jarPath; + } + private static AgentKind classifyAgentJar(String jarPath) { try (var jar = new JarFile(jarPath, false)) { Manifest manifest = jar.getManifest(); diff --git a/braintrust-java-agent/src/test/java/dev/braintrust/system/AgentBootstrapTest.java b/braintrust-java-agent/src/test/java/dev/braintrust/system/AgentBootstrapTest.java index 477f195e..a508c3a5 100644 --- a/braintrust-java-agent/src/test/java/dev/braintrust/system/AgentBootstrapTest.java +++ b/braintrust-java-agent/src/test/java/dev/braintrust/system/AgentBootstrapTest.java @@ -168,6 +168,26 @@ void detectAgentsIncludesBraintrust() { "did not expect DATADOG in plain test JVM, got: " + agents); } + @Test + void detectAgentsFromCommandLine() { + var cmdLine = + "/usr/bin/java -Dfoo=bar" + + " -javaagent:/path/to/dd-java-agent-1.61.1.jar" + + " -javaagent:/tmp/braintrust-java-agent.jar" + + " -XX:TieredStopAtLevel=1 -cp foo.jar Main"; + var agents = AgentBootstrap.detectAgentsFromCommandLine(cmdLine); + assertEquals(2, agents.size(), "expected 2 agents, got: " + agents); + // classifyAgentJar won't find real JARs at these paths, so both will be UNKNOWN; + // the important thing is that parsing found 2 -javaagent entries. + } + + @Test + void detectAgentsFromCommandLineWithAgentArgs() { + var cmdLine = "/usr/bin/java -javaagent:/path/agent.jar=someArgs -cp foo.jar Main"; + var agents = AgentBootstrap.detectAgentsFromCommandLine(cmdLine); + assertEquals(1, agents.size(), "expected 1 agent, got: " + agents); + } + @Test void otelAutoconfigureProducesRealTracer() { assertEquals(