Skip to content

Commit

Permalink
Support Micrometer @MeterTag
Browse files Browse the repository at this point in the history
  • Loading branch information
computerlove committed Nov 8, 2023
1 parent 59bc85b commit 415d736
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -61,42 +63,42 @@ 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)) {
try {
return ((CompletionStage<?>) context.proceed()).whenComplete(new BiConsumer<Object, Throwable>() {
@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 {
return ((Uni<Object>) context.proceed()).onTermination().invoke(
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;
}
}
Expand All @@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -85,18 +83,17 @@ public void accept(Object o, Throwable throwable, Boolean cancelled) {
}

private List<Sample> getSamples(ArcInvocationContext context) {
Method method = context.getMethod();
Tags commonTags = getCommonTags(method.getDeclaringClass().getName(), method.getName());
List<Timed> timed = context.findIterceptorBindings(Timed.class);
if (timed.isEmpty()) {
return Collections.emptyList();
}
Tags tags = getTags(context);
List<Sample> 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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Tag> 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;
}
}
}

0 comments on commit 415d736

Please sign in to comment.