From c662e9b6ffe1e4c833fc5477278d37dbe20767b0 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 26 Mar 2024 11:12:39 +0100 Subject: [PATCH] Add configuration property to disable long timers in Micrometer Observations Set management.observations.long-task-timer.enabled = false to disable the LongTaskTimer creation. Closes gh-39618 --- .../ObservationAutoConfiguration.java | 15 ++++--- .../observation/ObservationProperties.java | 25 ++++++++++- .../ObservationAutoConfigurationTests.java | 41 +++++++++++++++++++ 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java index b9230b45dd..b4d9760e86 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.util.List; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler.IgnoredMeters; import io.micrometer.core.instrument.observation.MeterObservationHandler; import io.micrometer.observation.GlobalObservationConvention; import io.micrometer.observation.Observation; @@ -131,8 +132,10 @@ public class ObservationAutoConfiguration { static class OnlyMetricsMeterObservationHandlerConfiguration { @Bean - DefaultMeterObservationHandler defaultMeterObservationHandler(MeterRegistry meterRegistry) { - return new DefaultMeterObservationHandler(meterRegistry); + DefaultMeterObservationHandler defaultMeterObservationHandler(MeterRegistry meterRegistry, + ObservationProperties properties) { + return properties.getLongTaskTimer().isEnabled() ? new DefaultMeterObservationHandler(meterRegistry) + : new DefaultMeterObservationHandler(meterRegistry, IgnoredMeters.LONG_TASK_TIMER); } } @@ -143,8 +146,10 @@ public class ObservationAutoConfiguration { @Bean TracingAwareMeterObservationHandler tracingAwareMeterObservationHandler( - MeterRegistry meterRegistry, Tracer tracer) { - DefaultMeterObservationHandler delegate = new DefaultMeterObservationHandler(meterRegistry); + MeterRegistry meterRegistry, Tracer tracer, ObservationProperties properties) { + DefaultMeterObservationHandler delegate = properties.getLongTaskTimer().isEnabled() + ? new DefaultMeterObservationHandler(meterRegistry) + : new DefaultMeterObservationHandler(meterRegistry, IgnoredMeters.LONG_TASK_TIMER); return new TracingAwareMeterObservationHandler<>(delegate, tracer); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java index 08de1a01c1..93d0e71524 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 the original author or authors. + * Copyright 2012-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,6 +45,8 @@ public class ObservationProperties { */ private Map enable = new LinkedHashMap<>(); + private final LongTaskTimer longTaskTimer = new LongTaskTimer(); + public Map getEnable() { return this.enable; } @@ -65,6 +67,10 @@ public class ObservationProperties { this.keyValues = keyValues; } + public LongTaskTimer getLongTaskTimer() { + return this.longTaskTimer; + } + public static class Http { private final Client client = new Client(); @@ -135,4 +141,21 @@ public class ObservationProperties { } + public static class LongTaskTimer { + + /** + * Whether to create a LongTaskTimer for every observation. + */ + private boolean enabled = true; + + public boolean isEnabled() { + return this.enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java index 655d2eb0fb..f2742c73f1 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/observation/ObservationAutoConfigurationTests.java @@ -50,6 +50,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.annotation.Order; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -334,6 +335,46 @@ class ObservationAutoConfigurationTests { }); } + @Test + void shouldEnableLongTaskTimersByDefault() { + this.contextRunner.run((context) -> { + DefaultMeterObservationHandler handler = context.getBean(DefaultMeterObservationHandler.class); + assertThat(handler).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", true); + }); + } + + @Test + void shouldDisableLongTaskTimerIfPropertyIsSet() { + this.contextRunner.withPropertyValues("management.observations.long-task-timer.enabled=false") + .run((context) -> { + DefaultMeterObservationHandler handler = context.getBean(DefaultMeterObservationHandler.class); + assertThat(handler).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", false); + }); + } + + @Test + @SuppressWarnings("unchecked") + void shouldEnableLongTaskTimersForTracingByDefault() { + this.tracingContextRunner.run((context) -> { + TracingAwareMeterObservationHandler tracingHandler = context + .getBean(TracingAwareMeterObservationHandler.class); + Object delegate = ReflectionTestUtils.getField(tracingHandler, "delegate"); + assertThat(delegate).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", true); + }); + } + + @Test + @SuppressWarnings("unchecked") + void shouldDisableLongTaskTimerForTracingIfPropertyIsSet() { + this.tracingContextRunner.withPropertyValues("management.observations.long-task-timer.enabled=false") + .run((context) -> { + TracingAwareMeterObservationHandler tracingHandler = context + .getBean(TracingAwareMeterObservationHandler.class); + Object delegate = ReflectionTestUtils.getField(tracingHandler, "delegate"); + assertThat(delegate).hasFieldOrPropertyWithValue("shouldCreateLongTaskTimer", false); + }); + } + @Configuration(proxyBeanMethods = false) static class ObservationPredicates {