This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Batch Documentation 6.0.6!

Micrometer support

Monitoring and metrics

Since version 4.2, Spring Batch provides support for batch monitoring and metrics based on Micrometer. This section describes which metrics are provided out-of-the-box and how to contribute custom metrics.

Built-in metrics

Metrics collection is disabled by default. To enable it, you need to define a Micrometer ObservationRegistry bean in your application context. Typically, you would need to define which ObservationHandler to use. The following example shows how to register a DefaultMeterObservationHandler that will store metrics in a MeterRegistry (for example, a Prometheus registry):

@Bean
public ObservationRegistry observationRegistry(MeterRegistry meterRegistry) {
    ObservationRegistry observationRegistry = ObservationRegistry.create();
    observationRegistry.observationConfig()
        .observationHandler(new DefaultMeterObservationHandler(meterRegistry));
    return observationRegistry;
}

Spring Batch specific metrics are registered under the spring.batch prefix. The following table explains all the metrics in details:

Metric Name

Type

Description

Tags

spring.batch.job

TIMER

Duration of job execution

name, status

spring.batch.job.active

LONG_TASK_TIMER

Currently active job

name

spring.batch.step

TIMER

Duration of step execution

name, job.name, status

spring.batch.step.active

LONG_TASK_TIMER

Currently active step

name

spring.batch.item.read

TIMER

Duration of item reading

job.name, step.name, status

spring.batch.item.process

TIMER

Duration of item processing

job.name, step.name, status

spring.batch.chunk.write

TIMER

Duration of chunk writing

job.name, step.name, status

spring.batch.job.launch.count

COUNTER

Job launch count

N/A

The status tag for jobs and steps is equal to the exit status. For item reading, processing and writing, this status tag can be either SUCCESS or FAILURE.

Choosing the observation registry

By default, Spring Batch uses the ObservationRegistry bean of the application context for the job operator and for all jobs and steps. You can use a different registry for a specific job or step by setting it on its builder:

@Bean
public Job job(JobRepository jobRepository, Step step) {
    return new JobBuilder("job", jobRepository)
            .observationRegistry(myJobObservationRegistry)
            .start(step)
            .build();
}

@Bean
public Step step(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    return new StepBuilder("step", jobRepository)
            .tasklet(new MyTasklet(), transactionManager)
            .observationRegistry(myStepObservationRegistry)
            .build();
}

The following rules apply:

  • An observation registry that is set explicitly on a job, a step, or the job operator is never replaced by the one of the application context.

  • To disable observations for a specific job or step, set ObservationRegistry.NOOP on it. This is treated as an explicit choice, like any other registry.

  • Jobs, steps, and job operators without an explicit observation registry use the ObservationRegistry bean of the application context, if there is one. Otherwise, no observations are created.

  • If the application context contains several ObservationRegistry beans, mark one of them as @Primary to use it by default. Without a primary bean, no registry is applied by default (and a warning is logged), so only the artifacts with an explicit registry are observed.

  • For the job operator, you can also use the observationRegistryRef attribute of @EnableBatchProcessing, or override the getObservationRegistry() method of DefaultBatchConfiguration, to select a specific registry.

Custom metrics

If you want to use your own metrics in your custom components, we recommend using Micrometer APIs directly. The following is an example of how to time a Tasklet:

import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

public class MyTimedTasklet implements Tasklet {

    private ObservationRegistry observationRegistry;

    public MyTimedTasklet(ObservationRegistry observationRegistry) {
        this.observationRegistry = observationRegistry;
    }

	@Override
	public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
		Observation observation = Observation.start("my.tasklet.step", this.observationRegistry);
		try (Observation.Scope scope = observation.openScope()) {
			// do some work
		    return RepeatStatus.FINISHED;
		} catch (Exception e) {
			// handle exception
            observation.error(exception);
		} finally {
			observation.stop();
		}
	}
}

Tracing

As of version 5, Spring Batch provides tracing through Micrometer’s Observation API. By default, tracing is disabled. To enable it, you need to define an ObservationRegistry bean configured with a TracingObservationHandler, such as DefaultTracingObservationHandler. The following example registers it next to the metrics handler shown above, so that the same registry collects both metrics and traces:

@Bean
public ObservationRegistry observationRegistry(MeterRegistry meterRegistry, Tracer tracer) {
    DefaultMeterObservationHandler observationHandler = new DefaultMeterObservationHandler(meterRegistry);
    ObservationRegistry observationRegistry = ObservationRegistry.create();
    observationRegistry.observationConfig()
            .observationHandler(new DefaultTracingObservationHandler(tracer))
            .observationHandler(new TracingAwareMeterObservationHandler<>(observationHandler, tracer));
    return observationRegistry;
}
TracingAwareMeterObservationHandler does not create spans. It wraps a MeterObservationHandler to make tracing data available to it (for exemplars, for example), so it requires a TracingObservationHandler to be registered as well.

With that in place, Spring Batch will create a trace for each job execution and a span for each step execution.

If you do not use EnableBatchProcessing or DefaultBatchConfiguration, you need to register a BatchObservabilityBeanPostProcessor in your application context, which will automatically set Micrometer’s observation registry in observable batch artefacts that do not have one configured explicitly (see Choosing the observation registry).