From d4ee86c6ea3422b2b5426481579503c5843d6d36 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 14:40:41 +0200 Subject: [PATCH 1/7] feat: add mock and Ollama demo for LC4j phase attribution Co-Authored-By: Claude Sonnet 4.6 --- .../langchain4j/langchain4j-1.0/build.gradle | 2 + .../langchain4j/demo/MockLlmPipelineTest.java | 62 +++++++++++++++++++ .../demo/OllamaLlmPipelineDemo.java | 43 +++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/MockLlmPipelineTest.java create mode 100644 dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index a5a2793836c..edd246067fd 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -15,5 +15,7 @@ addTestSuiteForDir('latestDepTest', 'test') dependencies { compileOnly group: 'dev.langchain4j', name: 'langchain4j-core', version: minVer testImplementation group: 'dev.langchain4j', name: 'langchain4j', version: minVer + testCompileOnly group: 'dev.langchain4j', name: 'langchain4j-ollama', version: '1.2.0' latestDepTestImplementation group: 'dev.langchain4j', name: 'langchain4j', version: '+' + latestDepTestCompileOnly group: 'dev.langchain4j', name: 'langchain4j-ollama', version: '+' } diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/MockLlmPipelineTest.java b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/MockLlmPipelineTest.java new file mode 100644 index 00000000000..5ec16c0bff9 --- /dev/null +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/MockLlmPipelineTest.java @@ -0,0 +1,62 @@ +package datadog.trace.instrumentation.langchain4j.demo; + +import dev.langchain4j.agent.tool.Tool; +import dev.langchain4j.agent.tool.ToolExecutionRequest; +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.chat.ChatModel; +import dev.langchain4j.model.chat.request.ChatRequest; +import dev.langchain4j.model.chat.response.ChatResponse; +import dev.langchain4j.service.AiServices; +import org.junit.jupiter.api.Test; + +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class MockLlmPipelineTest { + + interface WeatherAssistant { + String chat(String message); + } + + static class MockWeatherTool { + @Tool("Get current weather for a location") + public String getWeather(String location) { + return "Sunny, 22°C in " + location; + } + } + + static class TwoTurnMockModel implements ChatModel { + private final AtomicInteger calls = new AtomicInteger(); + + @Override + public ChatResponse chat(ChatRequest request) { + try { Thread.sleep(30); } catch (InterruptedException ignored) {} + if (calls.getAndIncrement() == 0) { + return ChatResponse.builder() + .aiMessage(AiMessage.from( + ToolExecutionRequest.builder() + .name("getWeather") + .arguments("{\"location\": \"Amsterdam\"}") + .build())) + .build(); + } + return ChatResponse.builder() + .aiMessage(AiMessage.from("The weather in Amsterdam is Sunny, 22°C.")) + .build(); + } + } + + @Test + public void pipelineExercisesAllThreeInstrumentationPoints() { + WeatherAssistant assistant = AiServices.builder(WeatherAssistant.class) + .chatModel(new TwoTurnMockModel()) + .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) + .tools(new MockWeatherTool()) + .build(); + + String response = assistant.chat("What is the weather in Amsterdam?"); + assertNotNull(response, "Expected a non-null response from the mock pipeline"); + } +} diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java new file mode 100644 index 00000000000..6ddfb4a3f18 --- /dev/null +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java @@ -0,0 +1,43 @@ +package datadog.trace.instrumentation.langchain4j.demo; + +import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.ollama.OllamaChatModel; +import dev.langchain4j.service.AiServices; + +import java.time.Duration; + +/** + * Generates a JFR recording with llm.agent.phase tags against a local Ollama server. + * + * Run: + * java -javaagent:dd-java-agent.jar + * -Ddd.profiling.enabled=true + * -Ddd.profiling.context.attributes.llm.phase.enabled=true + * -cp + * datadog.trace.instrumentation.langchain4j.demo.OllamaLlmPipelineDemo + * + * Prerequisites: ollama serve && ollama pull llama3 + */ +public class OllamaLlmPipelineDemo { + + interface Assistant { + String chat(String message); + } + + public static void main(String[] args) { + OllamaChatModel model = OllamaChatModel.builder() + .baseUrl("http://localhost:11434") + .modelName("llama3") + .timeout(Duration.ofMinutes(2)) + .build(); + + Assistant assistant = AiServices.builder(Assistant.class) + .chatModel(model) + .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) + .build(); + + System.out.println("Sending request..."); + String answer = assistant.chat("Explain Java garbage collection in one sentence."); + System.out.println("Response: " + answer); + } +} From 5d2581aac87a175521550b7d7118029316c84cd3 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 15:50:33 +0200 Subject: [PATCH 2/7] build: add runOllamaDemo task and fix ollama runtime dep --- .../langchain4j/langchain4j-1.0/build.gradle | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index edd246067fd..d226dc1758e 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -15,7 +15,19 @@ addTestSuiteForDir('latestDepTest', 'test') dependencies { compileOnly group: 'dev.langchain4j', name: 'langchain4j-core', version: minVer testImplementation group: 'dev.langchain4j', name: 'langchain4j', version: minVer - testCompileOnly group: 'dev.langchain4j', name: 'langchain4j-ollama', version: '1.2.0' + testImplementation group: 'dev.langchain4j', name: 'langchain4j-ollama', version: '1.2.0' latestDepTestImplementation group: 'dev.langchain4j', name: 'langchain4j', version: '+' latestDepTestCompileOnly group: 'dev.langchain4j', name: 'langchain4j-ollama', version: '+' } + +tasks.register('runOllamaDemo', JavaExec) { + dependsOn testClasses + classpath = sourceSets.test.runtimeClasspath + mainClass = 'datadog.trace.instrumentation.langchain4j.demo.OllamaLlmPipelineDemo' + def agentJar = fileTree("$rootDir/dd-java-agent/build/libs").include("dd-java-agent-*.jar") + .exclude("*-sources.jar").singleFile + jvmArgs "-javaagent:${agentJar}", + "-Ddd.profiling.enabled=true", + "-Ddd.profiling.context.attributes.llm.phase.enabled=true", + "-Ddd.trace.enabled=false" +} From 53f0addf7eefebb7d1ada32b2ae258779420d1fe Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 16:11:30 +0200 Subject: [PATCH 3/7] fix(demo): semver jar pick, 3-question loop, 25s hold for profiler flush --- .../langchain4j/langchain4j-1.0/build.gradle | 16 +++++++++++--- .../demo/OllamaLlmPipelineDemo.java | 21 ++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index d226dc1758e..568c26f1f7e 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -24,10 +24,20 @@ tasks.register('runOllamaDemo', JavaExec) { dependsOn testClasses classpath = sourceSets.test.runtimeClasspath mainClass = 'datadog.trace.instrumentation.langchain4j.demo.OllamaLlmPipelineDemo' - def agentJar = fileTree("$rootDir/dd-java-agent/build/libs").include("dd-java-agent-*.jar") - .exclude("*-sources.jar").singleFile + // Pick the highest semver agent jar in build/libs, ignoring classifier jars. + def agentJar = fileTree("$rootDir/dd-java-agent/build/libs") + .include("dd-java-agent-*.jar") + .exclude("*-sources.jar", "*-javadoc.jar") + .files + .sort { f -> + def m = f.name =~ /dd-java-agent-(\d+)\.(\d+)\.(\d+)/ + m ? (m[0][1] as int) * 1_000_000 + (m[0][2] as int) * 1_000 + (m[0][3] as int) : 0 + }.last() jvmArgs "-javaagent:${agentJar}", "-Ddd.profiling.enabled=true", "-Ddd.profiling.context.attributes.llm.phase.enabled=true", - "-Ddd.trace.enabled=false" + "-Ddd.trace.enabled=false", + "-Ddd.profiling.start-force-first=true", + "-Ddd.profiling.upload.period=10", + "-XX:StartFlightRecording=filename=/tmp/demo-llm.jfr,dumponexit=true,settings=profile" } diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java index 6ddfb4a3f18..455e918f51c 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/test/java/datadog/trace/instrumentation/langchain4j/demo/OllamaLlmPipelineDemo.java @@ -36,8 +36,23 @@ public static void main(String[] args) { .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) .build(); - System.out.println("Sending request..."); - String answer = assistant.chat("Explain Java garbage collection in one sentence."); - System.out.println("Response: " + answer); + String[] questions = { + "Explain Java garbage collection in one sentence.", + "What is a Java virtual thread?", + "Name one advantage of the G1 garbage collector." + }; + for (String q : questions) { + System.out.println("Q: " + q); + System.out.println("A: " + assistant.chat(q)); + } + + // Hold the JVM alive so the profiler flushes at least two recording cycles + // (dd.profiling.upload.period=10 → flush at ~10 s and ~20 s). + System.out.println("Waiting 25 s for profiling data to flush..."); + try { + Thread.sleep(25_000); + } catch (InterruptedException ignored) { + } + System.out.println("Done."); } } From d300b03c382f0eb538a175a9ca983e20a875111a Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 16:31:19 +0200 Subject: [PATCH 4/7] fix(demo): use dd.profiling.debug.dump_path to persist JFR recordings --- .../instrumentation/langchain4j/langchain4j-1.0/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index 568c26f1f7e..b1834c59163 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -39,5 +39,5 @@ tasks.register('runOllamaDemo', JavaExec) { "-Ddd.trace.enabled=false", "-Ddd.profiling.start-force-first=true", "-Ddd.profiling.upload.period=10", - "-XX:StartFlightRecording=filename=/tmp/demo-llm.jfr,dumponexit=true,settings=profile" + "-Ddd.profiling.debug.dump_path=/tmp/llm-demo-profiles" } From 66ba1ea3dce33a7506a4ac716ca87b63b503a528 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 16:39:09 +0200 Subject: [PATCH 5/7] fix(demo): replace dd.trace.enabled=false with LoggingWriter so Profiling.get() works --- .../instrumentation/langchain4j/langchain4j-1.0/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index b1834c59163..3e7e1584035 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -36,7 +36,7 @@ tasks.register('runOllamaDemo', JavaExec) { jvmArgs "-javaagent:${agentJar}", "-Ddd.profiling.enabled=true", "-Ddd.profiling.context.attributes.llm.phase.enabled=true", - "-Ddd.trace.enabled=false", + "-Ddd.writer.type=LoggingWriter", "-Ddd.profiling.start-force-first=true", "-Ddd.profiling.upload.period=10", "-Ddd.profiling.debug.dump_path=/tmp/llm-demo-profiles" From 0d0661798ef8aff052aeee9f55d74ab262f7a3a3 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 17:12:06 +0200 Subject: [PATCH 6/7] fix: call DatadogProfilingIntegration directly from advice, drop Profiling.get() --- .../ddprof/DatadogProfilingIntegration.java | 8 ++++++++ .../langchain4j/langchain4j-1.0/build.gradle | 3 ++- .../langchain4j/AiServicesInstrumentation.java | 14 +++++--------- .../langchain4j/ChatModelInstrumentation.java | 14 +++++--------- .../langchain4j/ToolExecutorInstrumentation.java | 14 +++++--------- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/dd-java-agent/agent-profiling/profiling-ddprof/src/main/java/com/datadog/profiling/ddprof/DatadogProfilingIntegration.java b/dd-java-agent/agent-profiling/profiling-ddprof/src/main/java/com/datadog/profiling/ddprof/DatadogProfilingIntegration.java index 00a0358d346..3b143919bbb 100644 --- a/dd-java-agent/agent-profiling/profiling-ddprof/src/main/java/com/datadog/profiling/ddprof/DatadogProfilingIntegration.java +++ b/dd-java-agent/agent-profiling/profiling-ddprof/src/main/java/com/datadog/profiling/ddprof/DatadogProfilingIntegration.java @@ -82,6 +82,14 @@ public void clearContext() { DDPROF.clearContextValue(RESOURCE_NAME_INDEX); } + public static void setLlmPhase(String phaseToken) { + DDPROF.setAgentPhase(phaseToken); + } + + public static void clearLlmPhase() { + DDPROF.clearAgentPhase(); + } + @Override public ProfilingContextAttribute createContextAttribute(String attribute) { return new DatadogProfilerContextSetter(attribute, DDPROF); diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index 3e7e1584035..3548dc8ef66 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -13,6 +13,7 @@ muzzle { addTestSuiteForDir('latestDepTest', 'test') dependencies { + compileOnly project(':dd-java-agent:agent-profiling:profiling-ddprof') compileOnly group: 'dev.langchain4j', name: 'langchain4j-core', version: minVer testImplementation group: 'dev.langchain4j', name: 'langchain4j', version: minVer testImplementation group: 'dev.langchain4j', name: 'langchain4j-ollama', version: '1.2.0' @@ -36,7 +37,7 @@ tasks.register('runOllamaDemo', JavaExec) { jvmArgs "-javaagent:${agentJar}", "-Ddd.profiling.enabled=true", "-Ddd.profiling.context.attributes.llm.phase.enabled=true", - "-Ddd.writer.type=LoggingWriter", + "-Ddd.trace.enabled=false", "-Ddd.profiling.start-force-first=true", "-Ddd.profiling.upload.period=10", "-Ddd.profiling.debug.dump_path=/tmp/llm-demo-profiles" diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/AiServicesInstrumentation.java b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/AiServicesInstrumentation.java index 7033aa04cd6..00a8874cf21 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/AiServicesInstrumentation.java +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/AiServicesInstrumentation.java @@ -3,9 +3,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; +import com.datadog.profiling.ddprof.DatadogProfilingIntegration; import datadog.trace.agent.tooling.Instrumenter; -import datadog.trace.api.profiling.Profiling; -import datadog.trace.api.profiling.ProfilingScope; import net.bytebuddy.asm.Advice; public class AiServicesInstrumentation @@ -25,16 +24,13 @@ public void methodAdvice(MethodTransformer transformer) { public static final class InvokeAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static ProfilingScope enter() { - ProfilingScope scope = Profiling.get().newScope(); - scope.setContextValue("llm.agent.phase", "context_build"); - return scope; + public static void enter() { + DatadogProfilingIntegration.setLlmPhase("context_build"); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - public static void exit(@Advice.Enter final ProfilingScope scope) { - scope.clearContextValue("llm.agent.phase"); - scope.close(); + public static void exit() { + DatadogProfilingIntegration.clearLlmPhase(); } } } diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ChatModelInstrumentation.java b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ChatModelInstrumentation.java index 20f286d6589..bead8a76547 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ChatModelInstrumentation.java +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ChatModelInstrumentation.java @@ -5,9 +5,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import com.datadog.profiling.ddprof.DatadogProfilingIntegration; import datadog.trace.agent.tooling.Instrumenter; -import datadog.trace.api.profiling.Profiling; -import datadog.trace.api.profiling.ProfilingScope; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -36,16 +35,13 @@ public void methodAdvice(MethodTransformer transformer) { public static final class ChatAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static ProfilingScope enter() { - ProfilingScope scope = Profiling.get().newScope(); - scope.setContextValue("llm.agent.phase", "awaiting_inference"); - return scope; + public static void enter() { + DatadogProfilingIntegration.setLlmPhase("awaiting_inference"); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - public static void exit(@Advice.Enter final ProfilingScope scope) { - scope.clearContextValue("llm.agent.phase"); - scope.close(); + public static void exit() { + DatadogProfilingIntegration.clearLlmPhase(); } } } diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ToolExecutorInstrumentation.java b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ToolExecutorInstrumentation.java index 2ac69441885..0090b27ed4e 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ToolExecutorInstrumentation.java +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/src/main/java/datadog/trace/instrumentation/langchain4j/ToolExecutorInstrumentation.java @@ -5,9 +5,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import com.datadog.profiling.ddprof.DatadogProfilingIntegration; import datadog.trace.agent.tooling.Instrumenter; -import datadog.trace.api.profiling.Profiling; -import datadog.trace.api.profiling.ProfilingScope; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -36,16 +35,13 @@ public void methodAdvice(MethodTransformer transformer) { public static final class ExecuteAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static ProfilingScope enter() { - ProfilingScope scope = Profiling.get().newScope(); - scope.setContextValue("llm.agent.phase", "tool_execution"); - return scope; + public static void enter() { + DatadogProfilingIntegration.setLlmPhase("tool_execution"); } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - public static void exit(@Advice.Enter final ProfilingScope scope) { - scope.clearContextValue("llm.agent.phase"); - scope.close(); + public static void exit() { + DatadogProfilingIntegration.clearLlmPhase(); } } } From 64a9b3e0eff0005ef4664ad2f630885a8176c07c Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Tue, 2 Jun 2026 17:34:11 +0200 Subject: [PATCH 7/7] fix(demo): depend on shadowJar so agent is always rebuilt before running --- .../instrumentation/langchain4j/langchain4j-1.0/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle index 3548dc8ef66..1fe2fbe48d6 100644 --- a/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle +++ b/dd-java-agent/instrumentation/langchain4j/langchain4j-1.0/build.gradle @@ -22,7 +22,7 @@ dependencies { } tasks.register('runOllamaDemo', JavaExec) { - dependsOn testClasses + dependsOn testClasses, ':dd-java-agent:shadowJar' classpath = sourceSets.test.runtimeClasspath mainClass = 'datadog.trace.instrumentation.langchain4j.demo.OllamaLlmPipelineDemo' // Pick the highest semver agent jar in build/libs, ignoring classifier jars.