From d8c29caaa77b5ef8d91ef4ea987456d30d002402 Mon Sep 17 00:00:00 2001 From: Michal Pawlik Date: Thu, 17 Jul 2025 12:24:28 +0200 Subject: [PATCH 1/3] Switch to typelevel weaver --- dd-java-agent/instrumentation/weaver/build.gradle | 10 +++++----- dd-java-agent/instrumentation/weaver/gradle.lockfile | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dd-java-agent/instrumentation/weaver/build.gradle b/dd-java-agent/instrumentation/weaver/build.gradle index 7957aedbeda..1c36b4fba45 100644 --- a/dd-java-agent/instrumentation/weaver/build.gradle +++ b/dd-java-agent/instrumentation/weaver/build.gradle @@ -3,23 +3,23 @@ apply plugin: 'scala' muzzle { pass { - group = 'com.disneystreaming' + group = 'org.typelevel' module = 'weaver-cats_3' - versions = '[0.8.4,)' + versions = '[0.9.2,)' } } addTestSuiteForDir('latestDepTest', 'test') dependencies { - compileOnly group: 'com.disneystreaming', name: 'weaver-cats_3', version: '0.8.4' + compileOnly group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.2' testImplementation testFixtures(project(':dd-java-agent:agent-ci-visibility')) testImplementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.20' - testImplementation group: 'com.disneystreaming', name: 'weaver-cats_3', version: '0.8.4' + testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.2' - testImplementation group: 'com.disneystreaming', name: 'weaver-cats_3', version: '+' + testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '+' } compileTestGroovy { diff --git a/dd-java-agent/instrumentation/weaver/gradle.lockfile b/dd-java-agent/instrumentation/weaver/gradle.lockfile index 980e28f9f5f..6f8df0070d6 100644 --- a/dd-java-agent/instrumentation/weaver/gradle.lockfile +++ b/dd-java-agent/instrumentation/weaver/gradle.lockfile @@ -13,10 +13,10 @@ com.datadoghq.okio:okio:1.17.6=compileClasspath,instrumentPluginClasspath,latest com.datadoghq:dd-javac-plugin-client:0.2.2=compileClasspath,instrumentPluginClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,muzzleBootstrap,muzzleTooling,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.datadoghq:java-dogstatsd-client:4.4.3=instrumentPluginClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath com.datadoghq:sketches-java:0.8.3=instrumentPluginClasspath,latestDepTestRuntimeClasspath,muzzleTooling,runtimeClasspath,testRuntimeClasspath -com.disneystreaming:weaver-cats-core_3:0.8.4=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.disneystreaming:weaver-cats_3:0.8.4=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.disneystreaming:weaver-core_3:0.8.4=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath -com.disneystreaming:weaver-framework_3:0.8.4=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.typelevel:weaver-cats-core_3:0.9.2=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.typelevel:weaver-cats_3:0.9.2=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.typelevel:weaver-core_3:0.9.2=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath +org.typelevel:weaver-framework_3:0.9.2=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath com.eed3si9n.expecty:expecty_3:0.16.0=compileClasspath,latestDepTestCompileClasspath,latestDepTestRuntimeClasspath,testCompileClasspath,testRuntimeClasspath com.eed3si9n:shaded-jawn-parser_2.13:1.3.2=zinc com.eed3si9n:shaded-scalajson_2.13:1.0.0-M4=zinc From 82adfc4ac307cce45560b43d27e56aea2b97a5df Mon Sep 17 00:00:00 2001 From: Daniel Mohedano Date: Thu, 24 Jul 2025 11:45:44 +0200 Subject: [PATCH 2/3] fix: update weaver instrumentation to handle both queue implementations --- .../instrumentation/weaver/build.gradle | 23 +++++++++--- .../weaver/DatadogWeaverReporter.java | 14 +++++++ ...askDefAwareConcurrentLinkedQueueProxy.java | 24 ++++++++++++ .../TaskDefAwareLinkedBlockingQueueProxy.java | 34 +++++++++++++++++ .../weaver/TaskDefAwareQueueProxy.java | 37 ------------------- .../weaver/WeaverInstrumentation.java | 29 ++++++++++++--- 6 files changed, 114 insertions(+), 47 deletions(-) create mode 100644 dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java create mode 100644 dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareLinkedBlockingQueueProxy.java delete mode 100644 dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareQueueProxy.java diff --git a/dd-java-agent/instrumentation/weaver/build.gradle b/dd-java-agent/instrumentation/weaver/build.gradle index 1c36b4fba45..7ce9ef1075a 100644 --- a/dd-java-agent/instrumentation/weaver/build.gradle +++ b/dd-java-agent/instrumentation/weaver/build.gradle @@ -2,24 +2,32 @@ apply from: "$rootDir/gradle/java.gradle" apply plugin: 'scala' muzzle { + pass { + group = 'com.disneystreaming' + module = 'weaver-cats_3' + versions = '[0.8.4,)' + } + pass { group = 'org.typelevel' module = 'weaver-cats_3' - versions = '[0.9.2,)' + versions = '[0.9.0,)' } } addTestSuiteForDir('latestDepTest', 'test') +// weaver 0.8.4 is the earliest supported version before the org migration +addTestSuiteForDir('weaver084Test', 'test') dependencies { - compileOnly group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.2' + compileOnly group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.0' testImplementation testFixtures(project(':dd-java-agent:agent-ci-visibility')) testImplementation group: 'org.scala-lang', name: 'scala-library', version: '2.12.20' - testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.2' - - testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '+' + testImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '0.9.0' + latestDepTestImplementation group: 'org.typelevel', name: 'weaver-cats_3', version: '+' + weaver084TestImplementation group: 'com.disneystreaming', name: 'weaver-cats_3', version: '0.8.4' } compileTestGroovy { @@ -31,3 +39,8 @@ compileLatestDepTestGroovy { dependsOn compileLatestDepTestScala classpath += files(sourceSets.latestDepTest.scala.destinationDirectory) } + +compileWeaver084TestGroovy { + dependsOn compileWeaver084TestScala + classpath += files(sourceSets.weaver084Test.scala.destinationDirectory) +} diff --git a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/DatadogWeaverReporter.java b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/DatadogWeaverReporter.java index 4c5c0f7be63..2873c97a84a 100644 --- a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/DatadogWeaverReporter.java +++ b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/DatadogWeaverReporter.java @@ -14,6 +14,7 @@ import sbt.testing.TaskDef; import weaver.Result; import weaver.TestOutcome; +import weaver.framework.RunEvent; import weaver.framework.SuiteFinished; import weaver.framework.SuiteStarted; import weaver.framework.TestFinished; @@ -42,6 +43,19 @@ public static synchronized void stop() { } } + public static void processEvent(Object event, TaskDef taskDef) { + if (event instanceof RunEvent) { + // handle event here, using taskDef reference to get suite details + if (event instanceof SuiteStarted) { + onSuiteStart((SuiteStarted) event); + } else if (event instanceof SuiteFinished) { + onSuiteFinish((SuiteFinished) event); + } else if (event instanceof TestFinished) { + onTestFinished((TestFinished) event, taskDef); + } + } + } + public static void onSuiteStart(SuiteStarted event) { String testSuiteName = event.name(); Class testClass = WeaverUtils.getClass(testSuiteName); diff --git a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java new file mode 100644 index 00000000000..86fcfb7bbea --- /dev/null +++ b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java @@ -0,0 +1,24 @@ +package datadog.trace.instrumentation.weaver; + +import java.util.concurrent.ConcurrentLinkedQueue; +import sbt.testing.TaskDef; + +public final class TaskDefAwareConcurrentLinkedQueueProxy extends ConcurrentLinkedQueue { + + private final TaskDef taskDef; + private final ConcurrentLinkedQueue delegate; + + public TaskDefAwareConcurrentLinkedQueueProxy(TaskDef taskDef, ConcurrentLinkedQueue delegate) { + super(); + this.taskDef = taskDef; + this.delegate = delegate; + DatadogWeaverReporter.start(); + } + + @Override + public T poll() { + T event = delegate.poll(); + DatadogWeaverReporter.processEvent(event, taskDef); + return event; + } +} diff --git a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareLinkedBlockingQueueProxy.java b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareLinkedBlockingQueueProxy.java new file mode 100644 index 00000000000..e9c267f2864 --- /dev/null +++ b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareLinkedBlockingQueueProxy.java @@ -0,0 +1,34 @@ +package datadog.trace.instrumentation.weaver; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; +import sbt.testing.TaskDef; + +public final class TaskDefAwareLinkedBlockingQueueProxy extends LinkedBlockingQueue { + + private final TaskDef taskDef; + private final LinkedBlockingQueue delegate; + + public TaskDefAwareLinkedBlockingQueueProxy(TaskDef taskDef, LinkedBlockingQueue delegate) { + super(); + this.taskDef = taskDef; + this.delegate = delegate; + DatadogWeaverReporter.start(); + } + + @Override + public T poll() { + T event = delegate.poll(); + DatadogWeaverReporter.processEvent(event, taskDef); + return event; + } + + @Override + public T poll(long timeout, TimeUnit unit) throws InterruptedException { + T event = delegate.poll(timeout, unit); + if (event != null) { + DatadogWeaverReporter.processEvent(event, taskDef); + } + return event; + } +} diff --git a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareQueueProxy.java b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareQueueProxy.java deleted file mode 100644 index e7b79ad2d72..00000000000 --- a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareQueueProxy.java +++ /dev/null @@ -1,37 +0,0 @@ -package datadog.trace.instrumentation.weaver; - -import java.util.concurrent.ConcurrentLinkedQueue; -import sbt.testing.TaskDef; -import weaver.framework.RunEvent; -import weaver.framework.SuiteFinished; -import weaver.framework.SuiteStarted; -import weaver.framework.TestFinished; - -public final class TaskDefAwareQueueProxy extends ConcurrentLinkedQueue { - - private final TaskDef taskDef; - private final ConcurrentLinkedQueue delegate; - - public TaskDefAwareQueueProxy(TaskDef taskDef, ConcurrentLinkedQueue delegate) { - super(); - this.taskDef = taskDef; - this.delegate = delegate; - DatadogWeaverReporter.start(); - } - - @Override - public T poll() { - T event = delegate.poll(); - if (event instanceof RunEvent) { - // handle event here, using taskDef reference to get suite details - if (event instanceof SuiteStarted) { - DatadogWeaverReporter.onSuiteStart((SuiteStarted) event); - } else if (event instanceof SuiteFinished) { - DatadogWeaverReporter.onSuiteFinish((SuiteFinished) event); - } else if (event instanceof TestFinished) { - DatadogWeaverReporter.onTestFinished((TestFinished) event, taskDef); - } - } - return event; - } -} diff --git a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java index 013aa56cc63..f28a45f03c5 100644 --- a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java +++ b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java @@ -5,7 +5,9 @@ import com.google.auto.service.AutoService; import datadog.trace.agent.tooling.Instrumenter; import datadog.trace.agent.tooling.InstrumenterModule; +import java.lang.reflect.Field; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingQueue; import net.bytebuddy.asm.Advice; import sbt.testing.TaskDef; import weaver.framework.SuiteEvent; @@ -28,7 +30,8 @@ public String[] helperClassNames() { return new String[] { packageName + ".WeaverUtils", packageName + ".DatadogWeaverReporter", - packageName + ".TaskDefAwareQueueProxy", + packageName + ".TaskDefAwareLinkedBlockingQueueProxy", + packageName + ".TaskDefAwareConcurrentLinkedQueueProxy", }; } @@ -41,10 +44,26 @@ public void methodAdvice(MethodTransformer transformer) { public static class SbtTaskCreationAdvice { @Advice.OnMethodExit(suppress = Throwable.class) public static void onTaskCreation( - @Advice.FieldValue(value = "queue", readOnly = false) - ConcurrentLinkedQueue queue, - @Advice.FieldValue("taskDef") TaskDef taskDef) { - queue = new TaskDefAwareQueueProxy(taskDef, queue); + @Advice.This Object sbtTask, @Advice.FieldValue("taskDef") TaskDef taskDef) { + try { + Field queueField = sbtTask.getClass().getDeclaredField("queue"); + queueField.setAccessible(true); + Object queue = queueField.get(sbtTask); + if (queue instanceof ConcurrentLinkedQueue) { + // disney's implementation (0.8.4+) uses a ConcurrentLinkedQueue for the field + queueField.set( + sbtTask, + new TaskDefAwareConcurrentLinkedQueueProxy( + taskDef, (ConcurrentLinkedQueue) queue)); + } else if (queue instanceof LinkedBlockingQueue) { + // typelevel's implementation (0.9+) uses a LinkedBlockingQueue for the field + queueField.set( + sbtTask, + new TaskDefAwareLinkedBlockingQueueProxy( + taskDef, (LinkedBlockingQueue) queue)); + } + } catch (Exception ignored) { + } } } } From 45f4161c830a86cc2562162da0643a211f9ee3a7 Mon Sep 17 00:00:00 2001 From: Daniel Mohedano Date: Thu, 24 Jul 2025 12:43:47 +0200 Subject: [PATCH 3/3] style: spotless --- .../weaver/TaskDefAwareConcurrentLinkedQueueProxy.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java index 86fcfb7bbea..eda5327434d 100644 --- a/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java +++ b/dd-java-agent/instrumentation/weaver/src/main/java/datadog/trace/instrumentation/weaver/TaskDefAwareConcurrentLinkedQueueProxy.java @@ -8,7 +8,8 @@ public final class TaskDefAwareConcurrentLinkedQueueProxy extends ConcurrentL private final TaskDef taskDef; private final ConcurrentLinkedQueue delegate; - public TaskDefAwareConcurrentLinkedQueueProxy(TaskDef taskDef, ConcurrentLinkedQueue delegate) { + public TaskDefAwareConcurrentLinkedQueueProxy( + TaskDef taskDef, ConcurrentLinkedQueue delegate) { super(); this.taskDef = taskDef; this.delegate = delegate;