Skip to content

Commit 4fb6c2f

Browse files
committed
Make the MeterRegistry used by Micrometer configurable
Issue spring-projects#4224
1 parent cff8758 commit 4fb6c2f

File tree

9 files changed

+112
-18
lines changed

9 files changed

+112
-18
lines changed

spring-batch-core/src/main/java/org/springframework/batch/core/job/AbstractJob.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.stream.Collectors;
2323

2424
import io.micrometer.core.instrument.LongTaskTimer;
25+
import io.micrometer.core.instrument.MeterRegistry;
26+
import io.micrometer.core.instrument.Metrics;
2527
import io.micrometer.core.instrument.Tag;
2628
import io.micrometer.observation.Observation;
2729
import io.micrometer.observation.ObservationRegistry;
@@ -90,6 +92,8 @@ public abstract class AbstractJob implements Job, StepLocator, BeanNameAware, In
9092

9193
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
9294

95+
private MeterRegistry meterRegistry = Metrics.globalRegistry;
96+
9397
private BatchJobObservationConvention observationConvention = new DefaultBatchJobObservationConvention();
9498

9599
/**
@@ -288,8 +292,9 @@ public final void execute(JobExecution execution) {
288292

289293
JobSynchronizationManager.register(execution);
290294
String activeJobMeterName = "job.active";
291-
LongTaskTimer longTaskTimer = BatchMetrics.createLongTaskTimer(activeJobMeterName, "Active jobs", Tag.of(
292-
BatchMetrics.METRICS_PREFIX + activeJobMeterName + ".name", execution.getJobInstance().getJobName()));
295+
LongTaskTimer longTaskTimer = BatchMetrics.createLongTaskTimer(this.meterRegistry, activeJobMeterName,
296+
"Active jobs", Tag.of(BatchMetrics.METRICS_PREFIX + activeJobMeterName + ".name",
297+
execution.getJobInstance().getJobName()));
293298
LongTaskTimer.Sample longTaskTimerSample = longTaskTimer.start();
294299
Observation observation = BatchMetrics
295300
.createObservation(BatchJobObservation.BATCH_JOB_OBSERVATION.getName(), new BatchJobContext(execution),
@@ -447,6 +452,10 @@ public void setObservationRegistry(ObservationRegistry observationRegistry) {
447452
this.observationRegistry = observationRegistry;
448453
}
449454

455+
public void setMeterRegistry(MeterRegistry meterRegistry) {
456+
this.meterRegistry = meterRegistry;
457+
}
458+
450459
@Override
451460
public String toString() {
452461
return ClassUtils.getShortName(getClass()) + ": [name=" + name + "]";

spring-batch-core/src/main/java/org/springframework/batch/core/job/builder/JobBuilderHelper.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.List;
2323
import java.util.Set;
2424

25+
import io.micrometer.core.instrument.MeterRegistry;
2526
import io.micrometer.observation.ObservationRegistry;
2627
import org.apache.commons.logging.Log;
2728
import org.apache.commons.logging.LogFactory;
@@ -113,6 +114,18 @@ public B observationRegistry(ObservationRegistry observationRegistry) {
113114
return result;
114115
}
115116

117+
/**
118+
* Sets the meter registry for the job.
119+
* @param meterRegistry the meter registry (optional)
120+
* @return this to enable fluent chaining
121+
*/
122+
public B meterRegistry(MeterRegistry meterRegistry) {
123+
properties.meterRegistry = meterRegistry;
124+
@SuppressWarnings("unchecked")
125+
B result = (B) this;
126+
return result;
127+
}
128+
116129
/**
117130
* Registers objects using the annotation based listener configuration.
118131
* @param listener the object that has a method configured with listener annotation
@@ -188,6 +201,10 @@ protected void enhance(Job target) {
188201
if (observationRegistry != null) {
189202
job.setObservationRegistry(observationRegistry);
190203
}
204+
MeterRegistry meterRegistry = properties.getMeterRegistry();
205+
if (meterRegistry != null) {
206+
job.setMeterRegistry(meterRegistry);
207+
}
191208

192209
Boolean restartable = properties.getRestartable();
193210
if (restartable != null) {
@@ -213,6 +230,8 @@ public static class CommonJobProperties {
213230

214231
private ObservationRegistry observationRegistry;
215232

233+
private MeterRegistry meterRegistry;
234+
216235
private JobParametersIncrementer jobParametersIncrementer;
217236

218237
private JobParametersValidator jobParametersValidator;
@@ -225,6 +244,7 @@ public CommonJobProperties(CommonJobProperties properties) {
225244
this.restartable = properties.restartable;
226245
this.jobRepository = properties.jobRepository;
227246
this.observationRegistry = properties.observationRegistry;
247+
this.meterRegistry = properties.meterRegistry;
228248
this.jobExecutionListeners = new LinkedHashSet<>(properties.jobExecutionListeners);
229249
this.jobParametersIncrementer = properties.jobParametersIncrementer;
230250
this.jobParametersValidator = properties.jobParametersValidator;
@@ -262,6 +282,14 @@ public void setObservationRegistry(ObservationRegistry observationRegistry) {
262282
this.observationRegistry = observationRegistry;
263283
}
264284

285+
public MeterRegistry getMeterRegistry() {
286+
return meterRegistry;
287+
}
288+
289+
public void setMeterRegistry(MeterRegistry meterRegistry) {
290+
this.meterRegistry = meterRegistry;
291+
}
292+
265293
public String getName() {
266294
return name;
267295
}

spring-batch-core/src/main/java/org/springframework/batch/core/observability/BatchMetrics.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import java.util.concurrent.TimeUnit;
2222

2323
import io.micrometer.core.instrument.LongTaskTimer;
24-
import io.micrometer.core.instrument.Metrics;
24+
import io.micrometer.core.instrument.MeterRegistry;
2525
import io.micrometer.core.instrument.Tag;
2626
import io.micrometer.core.instrument.Timer;
2727
import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler;
@@ -34,8 +34,8 @@
3434
* Central class for batch metrics. It provides:
3535
*
3636
* <ul>
37-
* <li>the main entry point to interact with Micrometer's {@link Metrics#globalRegistry}
38-
* with common metrics such as {@link Timer} and {@link LongTaskTimer}.</li>
37+
* <li>the main entry point to interact with Micrometer's API to create common metrics
38+
* such as {@link Timer} and {@link LongTaskTimer}.</li>
3939
* <li>Some utility methods like calculating durations and formatting them in a human
4040
* readable format.</li>
4141
* </ul>
@@ -59,15 +59,16 @@ private BatchMetrics() {
5959

6060
/**
6161
* Create a {@link Timer}.
62+
* @param meterRegistry the meter registry to use
6263
* @param name of the timer. Will be prefixed with
6364
* {@link BatchMetrics#METRICS_PREFIX}.
6465
* @param description of the timer
6566
* @param tags of the timer
6667
* @return a new timer instance
6768
*/
68-
public static Timer createTimer(String name, String description, Tag... tags) {
69+
public static Timer createTimer(MeterRegistry meterRegistry, String name, String description, Tag... tags) {
6970
return Timer.builder(METRICS_PREFIX + name).description(description).tags(Arrays.asList(tags))
70-
.register(Metrics.globalRegistry);
71+
.register(meterRegistry);
7172
}
7273

7374
/**
@@ -106,23 +107,26 @@ public static Observation createObservation(String name, BatchStepContext contex
106107

107108
/**
108109
* Create a new {@link Timer.Sample}.
110+
* @param meterRegistry the meter registry to use
109111
* @return a new timer sample instance
110112
*/
111-
public static Timer.Sample createTimerSample() {
112-
return Timer.start(Metrics.globalRegistry);
113+
public static Timer.Sample createTimerSample(MeterRegistry meterRegistry) {
114+
return Timer.start(meterRegistry);
113115
}
114116

115117
/**
116118
* Create a new {@link LongTaskTimer}.
119+
* @param meterRegistry the meter registry to use
117120
* @param name of the long task timer. Will be prefixed with
118121
* {@link BatchMetrics#METRICS_PREFIX}.
119122
* @param description of the long task timer.
120123
* @param tags of the timer
121124
* @return a new long task timer instance
122125
*/
123-
public static LongTaskTimer createLongTaskTimer(String name, String description, Tag... tags) {
126+
public static LongTaskTimer createLongTaskTimer(MeterRegistry meterRegistry, String name, String description,
127+
Tag... tags) {
124128
return LongTaskTimer.builder(METRICS_PREFIX + name).description(description).tags(Arrays.asList(tags))
125-
.register(Metrics.globalRegistry);
129+
.register(meterRegistry);
126130
}
127131

128132
/**

spring-batch-core/src/main/java/org/springframework/batch/core/step/AbstractStep.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.util.List;
2121
import java.util.stream.Collectors;
2222

23+
import io.micrometer.core.instrument.MeterRegistry;
24+
import io.micrometer.core.instrument.Metrics;
2325
import io.micrometer.observation.Observation;
2426
import io.micrometer.observation.ObservationRegistry;
2527
import org.apache.commons.logging.Log;
@@ -78,6 +80,8 @@ public abstract class AbstractStep implements Step, InitializingBean, BeanNameAw
7880

7981
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
8082

83+
private MeterRegistry meterRegistry = Metrics.globalRegistry;
84+
8185
private BatchStepObservationConvention observationConvention = new DefaultBatchStepObservationConvention();
8286

8387
/**
@@ -431,4 +435,8 @@ public void setObservationRegistry(ObservationRegistry observationRegistry) {
431435
this.observationRegistry = observationRegistry;
432436
}
433437

438+
public void setMeterRegistry(MeterRegistry meterRegistry) {
439+
this.meterRegistry = meterRegistry;
440+
}
441+
434442
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/SimpleStepBuilder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
import java.util.LinkedHashSet;
2222
import java.util.Set;
2323

24+
import io.micrometer.core.instrument.MeterRegistry;
25+
import io.micrometer.core.instrument.Metrics;
26+
2427
import org.springframework.batch.core.ChunkListener;
2528
import org.springframework.batch.core.ItemProcessListener;
2629
import org.springframework.batch.core.ItemReadListener;
@@ -85,6 +88,8 @@ public class SimpleStepBuilder<I, O> extends AbstractTaskletStepBuilder<SimpleSt
8588

8689
private boolean readerTransactionalQueue = false;
8790

91+
private MeterRegistry meterRegistry = Metrics.globalRegistry;
92+
8893
/**
8994
* Create a new builder initialized with any properties in the parent. The parent is
9095
* copied, so it can be re-used.
@@ -109,6 +114,7 @@ protected SimpleStepBuilder(SimpleStepBuilder<I, O> parent) {
109114
this.processor = parent.processor;
110115
this.itemListeners = parent.itemListeners;
111116
this.readerTransactionalQueue = parent.readerTransactionalQueue;
117+
this.meterRegistry = parent.meterRegistry;
112118
this.transactionManager(parent.getTransactionManager());
113119
}
114120

@@ -159,7 +165,9 @@ protected Tasklet createTasklet() {
159165
SimpleChunkProvider<I> chunkProvider = new SimpleChunkProvider<>(getReader(), repeatOperations);
160166
SimpleChunkProcessor<I, O> chunkProcessor = new SimpleChunkProcessor<>(getProcessor(), getWriter());
161167
chunkProvider.setListeners(new ArrayList<>(itemListeners));
168+
chunkProvider.setMeterRegistry(this.meterRegistry);
162169
chunkProcessor.setListeners(new ArrayList<>(itemListeners));
170+
chunkProcessor.setMeterRegistry(this.meterRegistry);
163171
ChunkOrientedTasklet<I> tasklet = new ChunkOrientedTasklet<>(chunkProvider, chunkProcessor);
164172
tasklet.setBuffering(!readerTransactionalQueue);
165173
return tasklet;

spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/StepBuilderHelper.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.List;
2222
import java.util.Set;
2323

24+
import io.micrometer.core.instrument.MeterRegistry;
25+
import io.micrometer.core.instrument.Metrics;
2426
import io.micrometer.observation.ObservationRegistry;
2527
import org.apache.commons.logging.Log;
2628
import org.apache.commons.logging.LogFactory;
@@ -73,6 +75,11 @@ public B observationRegistry(ObservationRegistry observationRegistry) {
7375
return self();
7476
}
7577

78+
public B meterRegistry(MeterRegistry meterRegistry) {
79+
properties.meterRegistry = meterRegistry;
80+
return self();
81+
}
82+
7683
public B startLimit(int startLimit) {
7784
properties.startLimit = startLimit;
7885
return self();
@@ -133,6 +140,11 @@ protected void enhance(Step target) {
133140
step.setObservationRegistry(observationRegistry);
134141
}
135142

143+
MeterRegistry meterRegistry = properties.getMeterRegistry();
144+
if (meterRegistry != null) {
145+
step.setMeterRegistry(meterRegistry);
146+
}
147+
136148
Boolean allowStartIfComplete = properties.allowStartIfComplete;
137149
if (allowStartIfComplete != null) {
138150
step.setAllowStartIfComplete(allowStartIfComplete);
@@ -161,6 +173,8 @@ public static class CommonStepProperties {
161173

162174
private ObservationRegistry observationRegistry = ObservationRegistry.NOOP;
163175

176+
private MeterRegistry meterRegistry = Metrics.globalRegistry;
177+
164178
public CommonStepProperties() {
165179
}
166180

@@ -170,6 +184,7 @@ public CommonStepProperties(CommonStepProperties properties) {
170184
this.allowStartIfComplete = properties.allowStartIfComplete;
171185
this.jobRepository = properties.jobRepository;
172186
this.observationRegistry = properties.observationRegistry;
187+
this.meterRegistry = properties.meterRegistry;
173188
this.stepExecutionListeners = new ArrayList<>(properties.stepExecutionListeners);
174189
}
175190

@@ -189,6 +204,14 @@ public void setObservationRegistry(ObservationRegistry observationRegistry) {
189204
this.observationRegistry = observationRegistry;
190205
}
191206

207+
public MeterRegistry getMeterRegistry() {
208+
return meterRegistry;
209+
}
210+
211+
public void setMeterRegistry(MeterRegistry meterRegistry) {
212+
this.meterRegistry = meterRegistry;
213+
}
214+
192215
public String getName() {
193216
return name;
194217
}

spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.batch.core.step.item;
1818

1919
import java.util.ArrayList;
20-
import java.util.Collections;
2120
import java.util.Iterator;
2221
import java.util.List;
2322
import java.util.concurrent.atomic.AtomicReference;
@@ -220,7 +219,7 @@ protected Chunk<O> transform(final StepContribution contribution, Chunk<I> input
220219

221220
@Override
222221
public O doWithRetry(RetryContext context) throws Exception {
223-
Timer.Sample sample = BatchMetrics.createTimerSample();
222+
Timer.Sample sample = BatchMetrics.createTimerSample(meterRegistry);
224223
String status = BatchMetrics.STATUS_SUCCESS;
225224
O output = null;
226225
try {
@@ -336,7 +335,7 @@ public Object doWithRetry(RetryContext context) throws Exception {
336335

337336
if (!data.scanning()) {
338337
chunkMonitor.setChunkSize(inputs.size());
339-
Timer.Sample sample = BatchMetrics.createTimerSample();
338+
Timer.Sample sample = BatchMetrics.createTimerSample(meterRegistry);
340339
String status = BatchMetrics.STATUS_SUCCESS;
341340
try {
342341
doWrite(outputs);

spring-batch-core/src/main/java/org/springframework/batch/core/step/item/SimpleChunkProcessor.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import java.util.List;
2020

21+
import io.micrometer.core.instrument.MeterRegistry;
22+
import io.micrometer.core.instrument.Metrics;
2123
import io.micrometer.core.instrument.Tag;
2224
import io.micrometer.core.instrument.Timer;
2325

@@ -47,6 +49,8 @@ public class SimpleChunkProcessor<I, O> implements ChunkProcessor<I>, Initializi
4749

4850
private final MulticasterBatchListener<I, O> listener = new MulticasterBatchListener<>();
4951

52+
protected MeterRegistry meterRegistry = Metrics.globalRegistry;
53+
5054
/**
5155
* Default constructor for ease of configuration.
5256
*/
@@ -79,6 +83,10 @@ public void setItemWriter(ItemWriter<? super O> itemWriter) {
7983
this.itemWriter = itemWriter;
8084
}
8185

86+
public void setMeterRegistry(MeterRegistry meterRegistry) {
87+
this.meterRegistry = meterRegistry;
88+
}
89+
8290
/**
8391
* Check mandatory properties.
8492
*
@@ -278,7 +286,7 @@ protected Chunk<O> getAdjustedOutputs(Chunk<I> inputs, Chunk<O> outputs) {
278286
* @throws Exception if there is a problem
279287
*/
280288
protected void write(StepContribution contribution, Chunk<I> inputs, Chunk<O> outputs) throws Exception {
281-
Timer.Sample sample = BatchMetrics.createTimerSample();
289+
Timer.Sample sample = BatchMetrics.createTimerSample(this.meterRegistry);
282290
String status = BatchMetrics.STATUS_SUCCESS;
283291
try {
284292
doWrite(outputs);
@@ -303,7 +311,7 @@ protected Chunk<O> transform(StepContribution contribution, Chunk<I> inputs) thr
303311
for (Chunk<I>.ChunkIterator iterator = inputs.iterator(); iterator.hasNext();) {
304312
final I item = iterator.next();
305313
O output;
306-
Timer.Sample sample = BatchMetrics.createTimerSample();
314+
Timer.Sample sample = BatchMetrics.createTimerSample(this.meterRegistry);
307315
String status = BatchMetrics.STATUS_SUCCESS;
308316
try {
309317
output = doProcess(item);
@@ -333,7 +341,7 @@ protected Chunk<O> transform(StepContribution contribution, Chunk<I> inputs) thr
333341
protected void stopTimer(Timer.Sample sample, StepExecution stepExecution, String metricName, String status,
334342
String description) {
335343
String fullyQualifiedMetricName = BatchMetrics.METRICS_PREFIX + metricName;
336-
sample.stop(BatchMetrics.createTimer(metricName, description + " duration",
344+
sample.stop(BatchMetrics.createTimer(this.meterRegistry, metricName, description + " duration",
337345
Tag.of(fullyQualifiedMetricName + ".job.name",
338346
stepExecution.getJobExecution().getJobInstance().getJobName()),
339347
Tag.of(fullyQualifiedMetricName + ".step.name", stepExecution.getStepName()),

0 commit comments

Comments
 (0)