From 415d7360ff594fd8b204f98c700e71e047ef1b5c Mon Sep 17 00:00:00 2001 From: "Marvin B. Lillehaug" Date: Wed, 8 Nov 2023 13:35:40 +0100 Subject: [PATCH] Support Micrometer @MeterTag --- .../runtime/MicrometerCountedInterceptor.java | 20 +++-- .../runtime/MicrometerTimedInterceptor.java | 15 ++-- .../micrometer/runtime/TagsSupport.java | 74 +++++++++++++++++++ 3 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/TagsSupport.java diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerCountedInterceptor.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerCountedInterceptor.java index 152a36486b4565..4e754ff1103eab 100644 --- a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerCountedInterceptor.java +++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerCountedInterceptor.java @@ -1,5 +1,7 @@ package io.quarkus.micrometer.runtime; +import static io.quarkus.micrometer.runtime.TagsSupport.getTags; + import java.lang.reflect.Method; import java.util.concurrent.CompletionStage; import java.util.function.BiConsumer; @@ -61,7 +63,7 @@ Object countedMethod(ArcInvocationContext context) throws Exception { return context.proceed(); } Method method = context.getMethod(); - Tags commonTags = getCommonTags(method.getDeclaringClass().getName(), method.getName()); + Tags tags = getTags(context); Class returnType = method.getReturnType(); if (TypesUtil.isCompletionStage(returnType)) { @@ -69,11 +71,11 @@ Object countedMethod(ArcInvocationContext context) throws Exception { return ((CompletionStage) context.proceed()).whenComplete(new BiConsumer() { @Override public void accept(Object o, Throwable throwable) { - recordCompletionResult(counted, commonTags, throwable); + recordCompletionResult(counted, tags, throwable); } }); } catch (Throwable e) { - record(counted, commonTags, e); + record(counted, tags, e); } } else if (TypesUtil.isUni(returnType)) { try { @@ -81,22 +83,22 @@ public void accept(Object o, Throwable throwable) { new Functions.TriConsumer<>() { @Override public void accept(Object o, Throwable throwable, Boolean cancelled) { - recordCompletionResult(counted, commonTags, throwable); + recordCompletionResult(counted, tags, throwable); } }); } catch (Throwable e) { - record(counted, commonTags, e); + record(counted, tags, e); } } try { Object result = context.proceed(); if (!counted.recordFailuresOnly()) { - record(counted, commonTags, null); + record(counted, tags, null); } return result; } catch (Throwable e) { - record(counted, commonTags, e); + record(counted, tags, e); throw e; } } @@ -122,8 +124,4 @@ private void record(MicrometerCounted counted, Tags commonTags, Throwable throwa builder.register(meterRegistry).increment(); } - private Tags getCommonTags(String className, String methodName) { - return Tags.of("class", className, "method", methodName); - } - } diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerTimedInterceptor.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerTimedInterceptor.java index 7d6ff73b772607..42459618ea38de 100644 --- a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerTimedInterceptor.java +++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerTimedInterceptor.java @@ -1,6 +1,7 @@ package io.quarkus.micrometer.runtime; -import java.lang.reflect.Method; +import static io.quarkus.micrometer.runtime.TagsSupport.getTags; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -13,10 +14,7 @@ import org.jboss.logging.Logger; import io.micrometer.core.annotation.Timed; -import io.micrometer.core.instrument.LongTaskTimer; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tags; -import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.*; import io.quarkus.arc.ArcInvocationContext; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.tuples.Functions; @@ -85,18 +83,17 @@ public void accept(Object o, Throwable throwable, Boolean cancelled) { } private List getSamples(ArcInvocationContext context) { - Method method = context.getMethod(); - Tags commonTags = getCommonTags(method.getDeclaringClass().getName(), method.getName()); List timed = context.findIterceptorBindings(Timed.class); if (timed.isEmpty()) { return Collections.emptyList(); } + Tags tags = getTags(context); List samples = new ArrayList<>(timed.size()); for (Timed t : timed) { if (t.longTask()) { - samples.add(new LongTimerSample(t, commonTags)); + samples.add(new LongTimerSample(t, tags)); } else { - samples.add(new TimerSample(t, commonTags)); + samples.add(new TimerSample(t, tags)); } } return samples; diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/TagsSupport.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/TagsSupport.java new file mode 100644 index 00000000000000..2c28f3d77969b2 --- /dev/null +++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/TagsSupport.java @@ -0,0 +1,74 @@ +package io.quarkus.micrometer.runtime; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.List; + +import io.micrometer.common.annotation.NoOpValueResolver; +import io.micrometer.common.util.StringUtils; +import io.micrometer.core.aop.MeterTag; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Tags; +import io.quarkus.arc.ArcInvocationContext; + +class TagsSupport { + + static Tags getTags(ArcInvocationContext context) { + return getCommonTags(context) + .and(getMeterTags(context)); + } + + private static Tags getMeterTags(ArcInvocationContext context) { + List tags = new ArrayList<>(); + Method method = context.getMethod(); + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter methodParameter = parameters[i]; + MeterTag annotation = methodParameter.getAnnotation(MeterTag.class); + if (annotation != null) { + Object parameterValue = context.getParameters()[i]; + + tags.add(Tag.of( + resolveTagKey(annotation, methodParameter.getName()), + resolveTagValue(annotation, parameterValue))); + } + } + return Tags.of(tags); + } + + private static Tags getCommonTags(ArcInvocationContext context) { + Method method = context.getMethod(); + String className = method.getDeclaringClass().getName(); + String methodName = method.getName(); + return Tags.of("class", className, "method", methodName); + } + + /* + * Precedence copied from MeterTagAnnotationHandler + */ + private static String resolveTagValue(MeterTag annotation, Object parameterValue) { + if (annotation.resolver() != NoOpValueResolver.class) { + return "?"; + } else if (StringUtils.isNotBlank(annotation.expression())) { + return "?"; + } else if (parameterValue != null) { + return parameterValue.toString(); + } else { + return ""; + } + } + + /* + * Precedence copied from MeterTagAnnotationHandler + */ + private static String resolveTagKey(MeterTag annotation, String parameterName) { + if (StringUtils.isNotBlank(annotation.value())) { + return annotation.value(); + } else if (StringUtils.isNotBlank(annotation.key())) { + return annotation.key(); + } else { + return parameterName; + } + } +}