## 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 does not require any specific configuration. All metrics provided by the framework are registered in Micrometer’s global registry under the `spring.batch` prefix. The following table explains all the metrics in details:

Metric Name | Type | Description
`spring.batch.job` | `TIMER` | Duration of job execution
`spring.batch.job.active` | `LONG_TASK_TIMER` | Currently active jobs
`spring.batch.step` | `TIMER` | Duration of step execution
`spring.batch.item.read` | `TIMER` | Duration of item reading
`spring.batch.item.process` | `TIMER` | Duration of item processing
`spring.batch.chunk.write` | `TIMER` | Duration of chunk writing

### 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.core.instrument.Metrics;
    import io.micrometer.core.instrument.Timer;

    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 {

    	@Override
    	public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
    		Timer.Sample sample = Timer.start(Metrics.globalRegistry);
    		String status = "success";
    		try {
    			// do some work
    		} catch (Exception e) {
    			// handle exception
    			status = "failure";
    		} finally {
    			sample.stop(Timer.builder("my.tasklet.timer")
    					.description("Duration of MyTimedTasklet")
    					.tag("status", status)
    					.register(Metrics.globalRegistry));
    		}
    		return RepeatStatus.FINISHED;
    	}
    }