Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1792 from newrelic/spring-batch-instr-module
Instrumentation for Spring Batch v4 and v5
- Loading branch information
Showing
11 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# spring-batch-4.0.0 Instrumentation Module | ||
|
||
This module provides instrumentation for the Spring Batch 4 framework (up to, but not including version 5). | ||
|
||
Only single process, single threaded jobs are supported. Single process, multi-threaded and | ||
multi-process jobs are not supported. | ||
|
||
### Details | ||
The instrumentation will weave the following classes: | ||
|
||
- `org.springframework.batch.core.Job`: In Spring Batch, the Job class wraps the steps and processors that make a up a complete batch job implementation. | ||
The execute() method will be the transaction dispatcher. The transaction name will be `OtherTransaction/SpringBatch/Job/{jobName}` | ||
|
||
- `org.springframework.batch.core.Step`: The Step class represents a single step of the target batch job. The execute() method will be instrumented in order | ||
to track the total execution time of a job step. The timing of a Step task will include the time to read the data | ||
from the defined data source, the processing of the data and the time to write the data to the target data source. | ||
|
||
- `org.springframework.batch.item.ItemWriter`: The ItemWriter class is used to write the processed/transformed items to a data store. There will be the same number | ||
of ItemWriter segments as Step segments, since there is one write operation per Step. | ||
|
||
The ItemReader and ItemProcessor classes will not be instrumented since these are each called once per data item, | ||
which would cause the Transaction traces to be inflated unnecessarily. The timings for these calls are included | ||
in the Step instrumentation timing. | ||
|
||
### Metrics | ||
The following metrics will be reported: | ||
|
||
- `SpringBatch/Job/{jobName}/Step/{stepName}/read` | ||
- `SpringBatch/Job/{jobName}/Step/{stepName}/write` | ||
- `SpringBatch/Job/{jobName}/Step/{stepName}/skipped` | ||
|
||
These metrics represent the total number of items read, written and skipped for a particular step for a completed job. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
plugins { | ||
id "org.jetbrains.kotlin.jvm" | ||
} | ||
|
||
dependencies { | ||
implementation(project(":agent-bridge")) | ||
implementation("org.springframework.batch:spring-batch-core:4.0.0.RELEASE") | ||
implementation("org.springframework.batch:spring-batch-infrastructure:4.0.0.RELEASE") | ||
testImplementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.21") | ||
} | ||
|
||
jar { | ||
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.spring-batch-4.0.0', | ||
'Implementation-Title-Alias': 'spring_batch' } | ||
} | ||
|
||
verifyInstrumentation { | ||
passesOnly 'org.springframework.batch:spring-batch-core:[4.0.0.RELEASE,5.0.0.RELEASE)' | ||
|
||
excludeRegex 'org.springframework.batch:spring-batch-core:.*(RC|SEC|M)[0-9]*$' | ||
exclude 'org.springframework.batch:spring-batch-core:[1.0.0.FINAL,4.0.0.RELEASE)' | ||
} | ||
|
||
site { | ||
title 'Spring' | ||
type 'Framework' | ||
} |
42 changes: 42 additions & 0 deletions
42
.../spring-batch-4.0.0/src/main/java/org/springframework/batch/core/Job_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package org.springframework.batch.core; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.bridge.Transaction; | ||
import com.newrelic.agent.bridge.TransactionNamePriority; | ||
import com.newrelic.api.agent.NewRelic; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.springframework.batch.core.Job") | ||
public class Job_Instrumentation { | ||
@Trace(dispatcher = true) | ||
public void execute(JobExecution jobExecution) { | ||
Weaver.callOriginal(); | ||
|
||
Transaction transaction = AgentBridge.getAgent().getTransaction(false); | ||
if (transaction != null) { | ||
String jobName = jobExecution.getJobInstance().getJobName(); | ||
transaction.setTransactionName(TransactionNamePriority.FRAMEWORK_HIGH, false, "SpringBatch", "Job", jobName); | ||
|
||
String status = jobExecution.getExitStatus().getExitCode(); | ||
if ("COMPLETED".equals(status) || "FAILED".equals(status)) { | ||
NewRelic.incrementCounter("SpringBatch/Job/" + jobName + "/" + status); | ||
} | ||
|
||
for (StepExecution stepExecution : jobExecution.getStepExecutions()) { | ||
String metricName = "SpringBatch/Job/" + jobName + "/Step/" + stepExecution.getStepName(); | ||
NewRelic.incrementCounter(metricName + "/read", stepExecution.getReadCount()); | ||
NewRelic.incrementCounter(metricName + "/write", stepExecution.getWriteCount()); | ||
NewRelic.incrementCounter(metricName + "/skip", stepExecution.getSkipCount()); | ||
} | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...spring-batch-4.0.0/src/main/java/org/springframework/batch/core/Step_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package org.springframework.batch.core; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.bridge.Transaction; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.springframework.batch.core.Step") | ||
public class Step_Instrumentation { | ||
@Trace | ||
public void execute(StepExecution stepExecution) throws JobInterruptedException { | ||
Weaver.callOriginal(); | ||
Transaction transaction = AgentBridge.getAgent().getTransaction(false); | ||
if (transaction != null) { | ||
transaction.getTracedMethod().setMetricName("SpringBatch", "Step", "execute", stepExecution.getStepName()); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...-batch-4.0.0/src/main/java/org/springframework/batch/item/ItemWriter_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package org.springframework.batch.item; | ||
|
||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
import java.util.List; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.springframework.batch.item.ItemWriter") | ||
public class ItemWriter_Instrumentation { | ||
@Trace | ||
public void write(List items) throws Exception { | ||
Weaver.callOriginal(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# spring-batch-5.0.0 Instrumentation Module | ||
|
||
This module provides instrumentation for the Spring Batch v5 framework. | ||
|
||
Only single process, single threaded jobs are supported. Single process, multi-threaded and | ||
multi-process jobs are not supported. | ||
|
||
### Details | ||
The instrumentation will weave the following classes: | ||
|
||
- `org.springframework.batch.core.Job`: In Spring Batch, the Job class wraps the steps and processors that make a up a complete batch job implementation. | ||
The execute() method will be the transaction dispatcher. The transaction name will be `OtherTransaction/SpringBatch/Job/{jobName}` | ||
|
||
- `org.springframework.batch.core.Step`: The Step class represents a single step of the target batch job. The execute() method will be instrumented in order | ||
to track the total execution time of a job step. The timing of a Step task will include the time to read the data | ||
from the defined data source, the processing of the data and the time to write the data to the target data source. | ||
|
||
- `org.springframework.batch.item.ItemWriter`: The ItemWriter class is used to write the processed/transformed items to a data store. There will be the same number | ||
of ItemWriter segments as Step segments, since there is one write operation per Step. | ||
|
||
The ItemReader and ItemProcessor classes will not be instrumented since these are each called once per data item, | ||
which would cause the Transaction traces to be inflated unnecessarily. The timings for these calls are included | ||
in the Step instrumentation timing. | ||
|
||
### Metrics | ||
The following metrics will be reported: | ||
|
||
- `SpringBatch/Job/{jobName}/Step/{stepName}/read` | ||
- `SpringBatch/Job/{jobName}/Step/{stepName}/write` | ||
- `SpringBatch/Job/{jobName}/Step/{stepName}/skipped` | ||
|
||
These metrics represent the total number of items read, written and skipped for a particular step for a completed job. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
plugins { | ||
id "org.jetbrains.kotlin.jvm" | ||
} | ||
|
||
dependencies { | ||
implementation(project(":agent-bridge")) | ||
implementation("org.springframework.batch:spring-batch-core:5.0.0") | ||
implementation("org.springframework.batch:spring-batch-infrastructure:5.0.0") | ||
testImplementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.21") | ||
} | ||
|
||
jar { | ||
manifest { attributes 'Implementation-Title': 'com.newrelic.instrumentation.spring-batch-5.0.0', | ||
'Implementation-Title-Alias': 'spring_batch' } | ||
} | ||
|
||
verifyInstrumentation { | ||
passesOnly 'org.springframework.batch:spring-batch-core:[5.0.0,)' | ||
|
||
excludeRegex 'org.springframework.batch:spring-batch-core:.*(RC|SEC|M)[0-9]*$' | ||
exclude 'org.springframework.batch:spring-batch-core:[1.0.0.FINAL,4.0.0.RELEASE)' | ||
} | ||
|
||
site { | ||
title 'Spring' | ||
type 'Framework' | ||
} | ||
|
||
java { | ||
toolchain { | ||
languageVersion.set(JavaLanguageVersion.of(17)) | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
.../spring-batch-5.0.0/src/main/java/org/springframework/batch/core/Job_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package org.springframework.batch.core; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.bridge.Transaction; | ||
import com.newrelic.agent.bridge.TransactionNamePriority; | ||
import com.newrelic.api.agent.NewRelic; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.springframework.batch.core.Job") | ||
public class Job_Instrumentation { | ||
@Trace(dispatcher = true) | ||
public void execute(JobExecution jobExecution) { | ||
Weaver.callOriginal(); | ||
|
||
Transaction transaction = AgentBridge.getAgent().getTransaction(false); | ||
if (transaction != null) { | ||
String jobName = jobExecution.getJobInstance().getJobName(); | ||
transaction.setTransactionName(TransactionNamePriority.FRAMEWORK_HIGH, false, "SpringBatch", "Job", jobName); | ||
|
||
String status = jobExecution.getExitStatus().getExitCode(); | ||
if ("COMPLETED".equals(status) || "FAILED".equals(status)) { | ||
NewRelic.incrementCounter("SpringBatch/Job/" + jobName + "/" + status); | ||
} | ||
|
||
for (StepExecution stepExecution : jobExecution.getStepExecutions()) { | ||
String metricName = "SpringBatch/Job/" + jobName + "/Step/" + stepExecution.getStepName(); | ||
NewRelic.incrementCounter(metricName + "/read", (int)stepExecution.getReadCount()); | ||
NewRelic.incrementCounter(metricName + "/write", (int)stepExecution.getWriteCount()); | ||
NewRelic.incrementCounter(metricName + "/skip", (int)stepExecution.getSkipCount()); | ||
} | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...spring-batch-5.0.0/src/main/java/org/springframework/batch/core/Step_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package org.springframework.batch.core; | ||
|
||
import com.newrelic.agent.bridge.AgentBridge; | ||
import com.newrelic.agent.bridge.Transaction; | ||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.springframework.batch.core.Step") | ||
public class Step_Instrumentation { | ||
@Trace | ||
public void execute(StepExecution stepExecution) throws JobInterruptedException { | ||
Weaver.callOriginal(); | ||
Transaction transaction = AgentBridge.getAgent().getTransaction(false); | ||
if (transaction != null) { | ||
transaction.getTracedMethod().setMetricName("SpringBatch", "Step", "execute", stepExecution.getStepName()); | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
...-batch-5.0.0/src/main/java/org/springframework/batch/item/ItemWriter_Instrumentation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* | ||
* * Copyright 2024 New Relic Corporation. All rights reserved. | ||
* * SPDX-License-Identifier: Apache-2.0 | ||
* | ||
*/ | ||
package org.springframework.batch.item; | ||
|
||
import com.newrelic.api.agent.weaver.MatchType; | ||
import com.newrelic.api.agent.Trace; | ||
import com.newrelic.api.agent.weaver.Weave; | ||
import com.newrelic.api.agent.weaver.Weaver; | ||
import org.springframework.lang.NonNull; | ||
|
||
import java.util.List; | ||
|
||
@Weave(type = MatchType.Interface, originalName = "org.springframework.batch.item.ItemWriter") | ||
public class ItemWriter_Instrumentation { | ||
@Trace | ||
public void write(@NonNull Chunk chunk) throws Exception { | ||
Weaver.callOriginal(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters