Skip to content

Error in the metrics registration with a meter registry customization #4759

Open
@jorgerod

Description

@jorgerod

Bug description
When a meter registry customization is registered and the management.metrics.use-global-registry property is disabled, some spring-batch metrics are being registered in the meter registry customization and others in the meter registry global.

  • Metrics registered in meter registry customization

    • spring.batch.job
    • spring.batch.job.active
    • spring.batch.step
    • spring.batch.step.active
  • Metrics registered in the global meter registry

    • spring.batch.item.read
    • spring.batch.item.process
    • spring.batch.chunk.write

Environment
Please provide as many details as possible: Spring Batch version, Java version, which database you use if any, etc

  • Spring Batch version: 5.2.1
  • java version:
openjdk 21.0.3 2024-04-16 LTS
OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9-LTS, mixed mode, sharing)

Steps to reproduce

  1. Create a SimpleMeterRegistry
  2. management.metrics.use-global-registry=false
  3. Define job with step and reader, processor and writer
  4. Check metrics in the custom SimpleMeterRegistry

Expected behavior
Metrics spring.batch.item.read, spring.batch.item.process and spring.batch.chunk.write are registered the custom registry meter

Minimal Complete Reproducible example

package org.springframework.batch;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

import java.util.Arrays;
import java.util.List;

@Configuration
public class MyBatchJobConfiguration {

    @Bean
    public MeterRegistry myMeterRegistry() {
        return new SimpleMeterRegistry();
    }


    @Bean
    public ItemReader<String> reader() {
        return new ListItemReader<>(Arrays.asList("item1", "item2", "item3"));
    }

    @Bean
    public ItemProcessor<String, String> processor() {
        return item -> "processed " + item;
    }

    @Bean
    public ItemWriter<String> writer() {
        return items -> items.forEach(System.out::println);
    }

    @Bean
    public Job importUserJob(JobRepository jobRepository, Step step1) {
        return new JobBuilder("importUserJob", jobRepository)
            .incrementer(new RunIdIncrementer())
            .flow(step1)
            .end()
            .build();
    }

    @Bean
    public Step step(JobRepository jobRepository, PlatformTransactionManager transactionManager, ItemReader<String> reader, ItemProcessor<String, String> processor, ItemWriter<String> writer) {
        return new StepBuilder("step1", jobRepository)
            .<String, String> chunk(10, transactionManager)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
    }

    /*
     * Main method to run the application and exhibit the issue
     */
    public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyBatchJobConfiguration.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        JobParameters jobParameters = new JobParameters();
        JobExecution jobExecution = jobLauncher.run(job, jobParameters);
        System.out.println(jobExecution.getExitStatus().getExitCode());
    }
}
@SpringBatchTest
@DirtiesContext
@SpringJUnitConfig(MyBatchJobConfiguration.class)
@PropertySource("classpath:application.properties")
@EnableAutoConfiguration
public class MyBatchJobTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Autowired
    private JobRepositoryTestUtils jobRepositoryTestUtils;

    @Autowired
    private MeterRegistry myMeterRegistry;


    @Test
    public void givenCoffeeList_whenJobExecuted_thenSuccess() throws Exception {
        //when
        jobLauncherTestUtils.launchJob();

        //then
        assertThat(myMeterRegistry.getMeters()).anyMatch(meter -> meter.getId().getName().equals("spring.batch.item.read"));
        assertThat(myMeterRegistry.getMeters()).anyMatch(meter -> meter.getId().getName().equals("spring.batch.item.process"));
        assertThat(myMeterRegistry.getMeters()).anyMatch(meter -> meter.getId().getName().equals("spring.batch.chunk.write"));
    }
}

Complete sample: sb-batch.zip

Related issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: waiting-for-reporterIssues for which we are waiting for feedback from the reporter

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions