Prometheus verlangt, dass alle Zähler mit demselben Namen über denselben Tag-Schlüsselsatz verfügenJava

Java-Forum
Anonymous
 Prometheus verlangt, dass alle Zähler mit demselben Namen über denselben Tag-Schlüsselsatz verfügen

Post by Anonymous »

Wenn @Around nur @Timed annotierte Methode wie folgt:
package ru.fabit.visor.config.aop;

Code: Select all

import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.lang.NonNullApi;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.scheduling.annotation.Scheduled;

import java.lang.reflect.Method;
import java.util.function.Function;

/**
* The type Targeted timed aspect.
*/
@Aspect
@NonNullApi
public class TargetedTimedAspect {

public static final String DEFAULT_METRIC_NAME = "method.timed";

public static final String EXCEPTION_TAG = "exception";
public static final String BINDING_TAG = "binding";
public static final String SCHEDULED_CRON_TAG = "cron";

private final MeterRegistry registry;
private final Function
> tagsBasedOnJoinPoint;

public TargetedTimedAspect(MeterRegistry registry) {
this(registry, pjp ->
Tags.of("class", pjp.getStaticPart().getSignature().getDeclaringTypeName(),
"method", pjp.getStaticPart().getSignature().getName())
);
}

public TargetedTimedAspect(MeterRegistry registry, Function tagsBasedOnJoinPoint) {
this.registry = registry;
this.tagsBasedOnJoinPoint = tagsBasedOnJoinPoint;
}

// enable TimedAspect only for @StreamListener and @Scheduled annotated methods or allowed methods pointcut
@Around("timedAnnotatedPointcut() )")
public Object timedMethod(ProceedingJoinPoint pjp) throws Throwable {
Method method = ((MethodSignature) pjp.getSignature()).getMethod();

StreamListener streamListener = method.getAnnotation(StreamListener.class);
Scheduled scheduled = method.getAnnotation(Scheduled.class);
// timed can be on method or class
Timed timed = method.getAnnotation(Timed.class);
if (timed == null) {
method = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
timed = method.getAnnotation(Timed.class);
}

final String metricName = timed.value().isEmpty() ? DEFAULT_METRIC_NAME : timed.value();
Timer.Sample sample = Timer.start(registry);
String exceptionClass = "none";

try {
return pjp.proceed();
} catch (Exception ex) {
exceptionClass = ex.getClass().getSimpleName();
throw ex;
} finally {
try {
Timer.Builder timerBuilder = Timer.builder(metricName)
.description(timed.description().isEmpty() ? null : timed.description())
.tags(timed.extraTags())
.tags(EXCEPTION_TAG, exceptionClass)
.tags(tagsBasedOnJoinPoint.apply(pjp))
.publishPercentileHistogram(timed.histogram())
.publishPercentiles(timed.percentiles().length == 0 ? null : timed.percentiles());

if (streamListener != null) {
timerBuilder.tags(
BINDING_TAG,
streamListener.value().isEmpty() ? streamListener.target() : streamListener.value()
);
} else if (scheduled != null) {
timerBuilder.tags(SCHEDULED_CRON_TAG, scheduled.cron());
}

sample.stop(timerBuilder.register(registry));
} catch (Exception e) {
// ignoring on purpose
}
}
}

@Pointcut(
"(@annotation(org.springframework.cloud.stream.annotation.StreamListener) ||"  +
"@annotation(org.springframework.scheduling.annotation.Scheduled))"
)
public void asyncAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}

@Pointcut("execution(public * ru.fabit.visor.service.impl.StorageClientImpl.*(..)) ||" +
"execution(public * ru.fabit.visor.service.s3storage.S3StorageClientImpl.*(..))")
public void allowedMethodPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}

@Pointcut("@annotation(io.micrometer.core.annotation.Timed)")
public void timedAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}

}
Dann zurückgeben: java.lang.IllegalArgumentException: Prometheus erfordert, dass alle Zähler mit demselben Namen denselben Satz von Tag-Schlüsseln haben. Es gibt bereits einen vorhandenen Zähler mit dem Namen „web_photos_gotten_list_seconds“, der Tag-Schlüssel [Klasse, Ausnahme, Methode] enthält. Das Messgerät, das Sie registrieren möchten, verfügt über Schlüssel [Ausnahme, Methode, Ergebnis, Status, URI].
Aber wenn Sie alle @Timed-Methoden in Pointcut hinzufügen, ist das alles gute Arbeit. Ich verstehe nicht, warum wir alle annotierten Methoden separat zu Pointcut hinzufügen müssen?
Diese Arbeit:

Code: Select all

    package ru.fabit.visor.config.aop;

import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.lang.NonNullApi;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.scheduling.annotation.Scheduled;

import java.lang.reflect.Method;
import java.util.function.Function;

/**
* The type Targeted timed aspect.
*/
@Aspect
@NonNullApi
public class TargetedTimedAspect {

public static final String DEFAULT_METRIC_NAME = "method.timed";

public static final String EXCEPTION_TAG = "exception";
public static final String BINDING_TAG = "binding";
public static final String SCHEDULED_CRON_TAG = "cron";

private final MeterRegistry registry;
private final Function
> tagsBasedOnJoinPoint;

public TargetedTimedAspect(MeterRegistry registry) {
this(registry, pjp ->
Tags.of("class", pjp.getStaticPart().getSignature().getDeclaringTypeName(),
"method", pjp.getStaticPart().getSignature().getName())
);
}

public TargetedTimedAspect(MeterRegistry registry, Function tagsBasedOnJoinPoint) {
this.registry = registry;
this.tagsBasedOnJoinPoint = tagsBasedOnJoinPoint;
}

// enable TimedAspect only for @StreamListener and @Scheduled annotated methods or allowed methods pointcut
@Around("timedAnnotatedPointcut() && (asyncAnnotatedPointcut() || allowedMethodPointcut())")
public Object timedMethod(ProceedingJoinPoint pjp) throws Throwable {
Method method = ((MethodSignature) pjp.getSignature()).getMethod();

StreamListener streamListener = method.getAnnotation(StreamListener.class);
Scheduled scheduled = method.getAnnotation(Scheduled.class);
// timed can be on method or class
Timed timed = method.getAnnotation(Timed.class);
if (timed == null) {
method = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
timed = method.getAnnotation(Timed.class);
}

final String metricName = timed.value().isEmpty() ? DEFAULT_METRIC_NAME : timed.value();
Timer.Sample sample = Timer.start(registry);
String exceptionClass = "none";

try {
return pjp.proceed();
} catch (Exception ex) {
exceptionClass = ex.getClass().getSimpleName();
throw ex;
} finally {
try {
Timer.Builder timerBuilder = Timer.builder(metricName)
.description(timed.description().isEmpty() ? null : timed.description())
.tags(timed.extraTags())
.tags(EXCEPTION_TAG, exceptionClass)
.tags(tagsBasedOnJoinPoint.apply(pjp))
.publishPercentileHistogram(timed.histogram())
.publishPercentiles(timed.percentiles().length == 0 ? null : timed.percentiles());

if (streamListener != null) {
timerBuilder.tags(
BINDING_TAG,
streamListener.value().isEmpty() ? streamListener.target() : streamListener.value()
);
} else if (scheduled != null) {
timerBuilder.tags(SCHEDULED_CRON_TAG, scheduled.cron());
}

sample.stop(timerBuilder.register(registry));
} catch (Exception e) {
// ignoring on purpose
}
}
}

@Pointcut(
"(@annotation(org.springframework.cloud.stream.annotation.StreamListener) ||"  +
"@annotation(org.springframework.scheduling.annotation.Scheduled))"
)
public void asyncAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}

@Pointcut("execution(public * ru.fabit.visor.service.impl.StorageClientImpl.*(..)) ||" +
"execution(public * ru.fabit.visor.service.s3storage.S3StorageClientImpl.*(..))")
public void allowedMethodPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}

@Pointcut("@annotation(io.micrometer.core.annotation.Timed)")
public void timedAnnotatedPointcut() {
// Method is empty as this is just a Pointcut, the implementations are in the advices.
}

}
pom.xml:

Code: Select all

 
io.dropwizard.metrics
metrics-core


io.micrometer
micrometer-registry-prometheus

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post