diff --git a/micrometer-core/src/main/java/io/micronaut/configuration/metrics/aggregator/AbstractMethodTagger.java b/micrometer-core/src/main/java/io/micronaut/configuration/metrics/aggregator/AbstractMethodTagger.java index e561463e7..52d54a646 100644 --- a/micrometer-core/src/main/java/io/micronaut/configuration/metrics/aggregator/AbstractMethodTagger.java +++ b/micrometer-core/src/main/java/io/micronaut/configuration/metrics/aggregator/AbstractMethodTagger.java @@ -19,6 +19,7 @@ import io.micronaut.aop.MethodInvocationContext; import io.micronaut.core.annotation.Indexed; import io.micronaut.core.annotation.NonNull; +import io.micronaut.core.order.Ordered; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,7 +33,8 @@ * @since 5.5.0 */ @Indexed(AbstractMethodTagger.class) -public abstract class AbstractMethodTagger { +public abstract class AbstractMethodTagger implements Ordered { + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractMethodTagger.class); private final Class implClass = this.getClass(); diff --git a/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/CountedInterceptor.java b/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/CountedInterceptor.java index bd53b8d10..33e6a225f 100644 --- a/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/CountedInterceptor.java +++ b/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/CountedInterceptor.java @@ -29,6 +29,7 @@ import io.micronaut.core.annotation.Nullable; import io.micronaut.core.async.publisher.Publishers; import io.micronaut.core.convert.ConversionService; +import io.micronaut.core.order.OrderUtil; import io.micronaut.core.util.StringUtils; import jakarta.inject.Inject; import org.reactivestreams.Publisher; @@ -157,6 +158,7 @@ private void doCount(AnnotationMetadata metadata, String metricName, @Nullable T methodTaggers.isEmpty() ? Collections.emptyList() : methodTaggers .stream() + .sorted(OrderUtil.ORDERED_COMPARATOR) .filter(t -> !filter || taggers.contains(t.getClass())) .flatMap(t -> t.getTags(context).stream()) .toList() diff --git a/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/TimedInterceptor.java b/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/TimedInterceptor.java index 592eb9d02..4562209b5 100644 --- a/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/TimedInterceptor.java +++ b/micrometer-core/src/main/java/io/micronaut/configuration/metrics/micrometer/intercept/TimedInterceptor.java @@ -32,6 +32,7 @@ import io.micronaut.core.annotation.TypeHint; import io.micronaut.core.async.publisher.Publishers; import io.micronaut.core.convert.ConversionService; +import io.micronaut.core.order.OrderUtil; import io.micronaut.core.util.CollectionUtils; import jakarta.inject.Inject; import jakarta.inject.Singleton; @@ -225,6 +226,7 @@ private void stopTimed(String metricName, Timer.Sample sample, methodTaggers.isEmpty() ? Collections.emptyList() : methodTaggers .stream() + .sorted(OrderUtil.ORDERED_COMPARATOR) .filter(t -> !filter || taggers.contains(t.getClass())) .flatMap(b -> b.getTags(context).stream()) .toList() diff --git a/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/CountedAnnotationSpec.groovy b/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/CountedAnnotationSpec.groovy index 85bf6de2f..e9ae016f2 100644 --- a/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/CountedAnnotationSpec.groovy +++ b/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/CountedAnnotationSpec.groovy @@ -131,4 +131,28 @@ class CountedAnnotationSpec extends Specification { cleanup: ctx.close() } + + void "taggers are applied in order"(){ + given: + ApplicationContext ctx = ApplicationContext.run() + CountedTarget cc = ctx.getBean(CountedTarget) + MeterRegistry registry = ctx.getBean(MeterRegistry) + + when: + Integer result = cc.max(4, 10) + registry.get("counted.test.max.blocking").tags("ordered", "1", "parameters", "a b").timer() + + then: + thrown(MeterNotFoundException) + + when: + def counter = registry.get("counted.test.max.blocking").tags("ordered", "2", "parameters", "a b").counter() + + then: + result == 10 + counter.count() == 1 + + cleanup: + ctx.close() + } } diff --git a/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/TimeAnnotationSpec.groovy b/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/TimeAnnotationSpec.groovy index 72ece3c92..2962b4695 100644 --- a/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/TimeAnnotationSpec.groovy +++ b/micrometer-core/src/test/groovy/io/micronaut/configuration/metrics/annotation/TimeAnnotationSpec.groovy @@ -144,4 +144,29 @@ class TimeAnnotationSpec extends Specification { cleanup: ctx.close() } + + void "taggers are applied in order"(){ + given: + ApplicationContext ctx = ApplicationContext.run() + TimedTarget tt = ctx.getBean(TimedTarget) + MeterRegistry registry = ctx.getBean(MeterRegistry) + + when: + Integer result = tt.max(4, 10) + registry.get("timed.test.max.blocking").tags("ordered", "1", "parameters", "a b").timer() + + then: + thrown(MeterNotFoundException) + + when: + def timer = registry.get("timed.test.max.blocking").tags("ordered", "2", "parameters", "a b").timer() + + then: + result == 10 + timer.count() == 1 + timer.totalTime(MILLISECONDS) > 0 + + cleanup: + ctx.close() + } } diff --git a/micrometer-core/src/test/java/io/micronaut/configuration/metrics/aggregator/OrderedMethodTagger.java b/micrometer-core/src/test/java/io/micronaut/configuration/metrics/aggregator/OrderedMethodTagger.java new file mode 100644 index 000000000..dc6f2a8ef --- /dev/null +++ b/micrometer-core/src/test/java/io/micronaut/configuration/metrics/aggregator/OrderedMethodTagger.java @@ -0,0 +1,20 @@ +package io.micronaut.configuration.metrics.aggregator; + +import io.micrometer.core.instrument.Tag; +import io.micronaut.aop.MethodInvocationContext; +import jakarta.inject.Singleton; + +import java.util.List; + +@Singleton +public class OrderedMethodTagger extends AbstractMethodTagger{ + @Override + public int getOrder() { + return 1; + } + + @Override + public List buildTags(MethodInvocationContext context) { + return List.of(Tag.of("ordered", String.valueOf(getOrder()))); + } +} diff --git a/micrometer-core/src/test/java/io/micronaut/configuration/metrics/aggregator/OrderedMethodTagger2.java b/micrometer-core/src/test/java/io/micronaut/configuration/metrics/aggregator/OrderedMethodTagger2.java new file mode 100644 index 000000000..0b169a9de --- /dev/null +++ b/micrometer-core/src/test/java/io/micronaut/configuration/metrics/aggregator/OrderedMethodTagger2.java @@ -0,0 +1,20 @@ +package io.micronaut.configuration.metrics.aggregator; + +import io.micrometer.core.instrument.Tag; +import io.micronaut.aop.MethodInvocationContext; +import jakarta.inject.Singleton; + +import java.util.List; + +@Singleton +public class OrderedMethodTagger2 extends AbstractMethodTagger{ + @Override + public int getOrder() { + return 2; + } + + @Override + public List buildTags(MethodInvocationContext context) { + return List.of(Tag.of("ordered", String.valueOf(getOrder()))); + } +}