diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 99fccf3880..c33b23e04c 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -38,6 +38,7 @@ This is not a breaking change, so former * Adds <> option to exclude fast executing spans. When set together with one of the more specific thresholds - `trace_methods_duration_threshold` or `profiling_inferred_spans_min_duration`, the higher threshold will determine which spans will be discarded. +* Automatically instrument quartz jobs from the quartz-jobs artifact {pull}1170[#1170] [float] ===== Bug fixes diff --git a/apm-agent-plugins/apm-quartz-job-plugin/pom.xml b/apm-agent-plugins/apm-quartz-job-plugin/pom.xml index 59e362902e..c458bfc5e7 100644 --- a/apm-agent-plugins/apm-quartz-job-plugin/pom.xml +++ b/apm-agent-plugins/apm-quartz-job-plugin/pom.xml @@ -29,6 +29,13 @@ ${version.spring} provided + + + org.quartz-scheduler + quartz-jobs + ${version.quartz} + test + diff --git a/apm-agent-plugins/apm-quartz-job-plugin/src/main/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentation.java b/apm-agent-plugins/apm-quartz-job-plugin/src/main/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentation.java index b70b0790c4..09a95a58ac 100644 --- a/apm-agent-plugins/apm-quartz-job-plugin/src/main/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentation.java +++ b/apm-agent-plugins/apm-quartz-job-plugin/src/main/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentation.java @@ -40,6 +40,7 @@ import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; import static net.bytebuddy.matcher.ElementMatchers.hasSuperType; import static net.bytebuddy.matcher.ElementMatchers.isInterface; +import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; @@ -56,6 +57,7 @@ public JobTransactionNameInstrumentation(ElasticApmTracer tracer) { @Override public ElementMatcher getTypeMatcher() { return isInAnyPackage(applicationPackages, ElementMatchers.none()) + .or(nameStartsWith("org.quartz.job")) .and(hasSuperType(named("org.quartz.Job"))) .and(declaresMethod(getMethodMatcher())); } diff --git a/apm-agent-plugins/apm-quartz-job-plugin/src/test/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentationTest.java b/apm-agent-plugins/apm-quartz-job-plugin/src/test/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentationTest.java index 67c17fbcbb..372c94e711 100644 --- a/apm-agent-plugins/apm-quartz-job-plugin/src/test/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentationTest.java +++ b/apm-agent-plugins/apm-quartz-job-plugin/src/test/java/co/elastic/apm/agent/quartz/job/JobTransactionNameInstrumentationTest.java @@ -24,14 +24,16 @@ */ package co.elastic.apm.agent.quartz.job; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + import co.elastic.apm.agent.AbstractInstrumentationTest; import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.impl.TracerInternalApiUtils; import co.elastic.apm.agent.impl.transaction.Transaction; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.quartz.Job; @@ -45,12 +47,10 @@ import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; +import org.quartz.jobs.DirectoryScanJob; +import org.quartz.jobs.DirectoryScanListener; import org.springframework.scheduling.quartz.QuartzJobBean; -import java.time.Duration; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; @@ -159,6 +159,27 @@ void testJobWithResult() throws SchedulerException { assertThat(reporter.getTransactions().get(0).getResult()).isEqualTo("this is the result"); } + @Test + void testDirectoryScan() throws SchedulerException, IOException { + Path directoryScanTest = Files.createTempDirectory("DirectoryScanTest"); + + Trigger trigger = TriggerBuilder + .newTrigger() + .withIdentity("myTrigger") + .withSchedule( + SimpleScheduleBuilder.repeatSecondlyForTotalCount(1, 1)) + .build(); + final JobDetail job = JobBuilder.newJob(DirectoryScanJob.class) + .withIdentity("dummyJobName") + .usingJobData(DirectoryScanJob.DIRECTORY_NAME, directoryScanTest.toAbsolutePath().toString()) + .usingJobData(DirectoryScanJob.DIRECTORY_SCAN_LISTENER_NAME, TestDirectoryScanListener.class.getSimpleName()) + .build(); + + scheduler.getContext().put(TestDirectoryScanListener.class.getSimpleName(), new TestDirectoryScanListener()); + scheduler.scheduleJob(job, trigger); + verifyJobDetails(job); + } + public static class TestJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { @@ -201,4 +222,11 @@ protected void executeInternal(JobExecutionContext context) throws JobExecutionE } } + + public static class TestDirectoryScanListener implements DirectoryScanListener { + + @Override + public void filesUpdatedOrAdded(File[] files) { + } + } } diff --git a/docs/supported-technologies.asciidoc b/docs/supported-technologies.asciidoc index 699021de9c..4490bb39f9 100644 --- a/docs/supported-technologies.asciidoc +++ b/docs/supported-technologies.asciidoc @@ -336,7 +336,7 @@ When using a scheduling framework a transaction for every execution will be crea |2.0+ |The agent instruments the `execute` method of any class implementing `org.quartz.Job`, as well as the `executeInternal` method of any class extending `org.springframework.scheduling.quartz.QuartzJobBean`, and creates a transaction with the type `scheduled`, representing the job execution -NOTE: only classes from packages configured in <> will be instrumented. +NOTE: only classes from the quartz-jobs dependency will be instrumented automatically. For the instrumentation of other jobs the package must be added to the <> parameter. |1.8.0 |===