Switch to jersey-micrometer for Jersey metrics

Closes gh-39502
This commit is contained in:
Andy Wilkinson 2024-02-09 14:18:08 +00:00
parent 78dc1b6eb6
commit 1f7a983701
3 changed files with 89 additions and 12 deletions

View File

@ -102,6 +102,7 @@ dependencies {
optional("org.flywaydb:flyway-core")
optional("org.glassfish.jersey.core:jersey-server")
optional("org.glassfish.jersey.containers:jersey-container-servlet-core")
optional("org.glassfish.jersey.ext:jersey-micrometer")
optional("org.hibernate.orm:hibernate-core")
optional("org.hibernate.orm:hibernate-micrometer")
optional("org.hibernate.validator:hibernate-validator")

View File

@ -20,13 +20,16 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.jersey.server.AnnotationFinder;
import io.micrometer.core.instrument.binder.jersey.server.DefaultJerseyTagsProvider;
import io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider;
import io.micrometer.core.instrument.binder.jersey.server.MetricsApplicationEventListener;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.config.MeterFilter;
import org.glassfish.jersey.micrometer.server.AnnotationFinder;
import org.glassfish.jersey.micrometer.server.DefaultJerseyTagsProvider;
import org.glassfish.jersey.micrometer.server.JerseyTagsProvider;
import org.glassfish.jersey.micrometer.server.MetricsApplicationEventListener;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.monitoring.RequestEvent;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
import org.springframework.boot.actuate.autoconfigure.metrics.OnlyOnceLoggingDenyMeterFilter;
@ -66,17 +69,22 @@ public class JerseyServerMetricsAutoConfiguration {
}
@Bean
@ConditionalOnMissingBean(JerseyTagsProvider.class)
@SuppressWarnings("deprecation")
@ConditionalOnMissingBean({ JerseyTagsProvider.class,
io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider.class })
public DefaultJerseyTagsProvider jerseyTagsProvider() {
return new DefaultJerseyTagsProvider();
}
@Bean
@SuppressWarnings("deprecation")
public ResourceConfigCustomizer jerseyServerMetricsResourceConfigCustomizer(MeterRegistry meterRegistry,
JerseyTagsProvider tagsProvider) {
ObjectProvider<JerseyTagsProvider> tagsProvider,
ObjectProvider<io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider> micrometerTagsProvider) {
String metricName = this.observationProperties.getHttp().getServer().getRequests().getName();
return (config) -> config.register(new MetricsApplicationEventListener(meterRegistry, tagsProvider, metricName,
true, new AnnotationUtilsAnnotationFinder()));
return (config) -> config.register(new MetricsApplicationEventListener(meterRegistry,
tagsProvider.getIfAvailable(() -> new JerseyTagsProviderAdapter(micrometerTagsProvider.getObject())),
metricName, true, new AnnotationUtilsAnnotationFinder()));
}
@Bean
@ -101,4 +109,26 @@ public class JerseyServerMetricsAutoConfiguration {
}
@SuppressWarnings("deprecation")
static final class JerseyTagsProviderAdapter implements JerseyTagsProvider {
private final io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider delegate;
private JerseyTagsProviderAdapter(
io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider delegate) {
this.delegate = delegate;
}
@Override
public Iterable<Tag> httpRequestTags(RequestEvent event) {
return this.delegate.httpRequestTags(event);
}
@Override
public Iterable<Tag> httpLongRequestTags(RequestEvent event) {
return this.delegate.httpLongRequestTags(event);
}
}
}

View File

@ -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.
@ -17,22 +17,25 @@
package org.springframework.boot.actuate.autoconfigure.metrics.jersey;
import java.net.URI;
import java.util.Set;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Timer;
import io.micrometer.core.instrument.binder.jersey.server.DefaultJerseyTagsProvider;
import io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider;
import io.micrometer.core.instrument.binder.jersey.server.MetricsApplicationEventListener;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.glassfish.jersey.micrometer.server.DefaultJerseyTagsProvider;
import org.glassfish.jersey.micrometer.server.JerseyTagsProvider;
import org.glassfish.jersey.micrometer.server.MetricsApplicationEventListener;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.monitoring.RequestEvent;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.jersey.JerseyServerMetricsAutoConfiguration.JerseyTagsProviderAdapter;
import org.springframework.boot.actuate.autoconfigure.metrics.test.MetricsRun;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -87,6 +90,22 @@ class JerseyServerMetricsAutoConfigurationTests {
.run((context) -> assertThat(context).hasSingleBean(CustomJerseyTagsProvider.class));
}
@Test
@Deprecated(since = "3.3.0", forRemoval = true)
void shouldHonorExistingMicrometerTagProvider() {
this.webContextRunner.withUserConfiguration(CustomMicrometerJerseyTagsProviderConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(CustomMicrometerJerseyTagsProvider.class);
ResourceConfig config = new ResourceConfig();
context.getBean(ResourceConfigCustomizer.class).customize(config);
Set<Object> instances = config.getInstances();
assertThat(instances).hasSize(1)
.first(InstanceOfAssertFactories.type(MetricsApplicationEventListener.class))
.satisfies((listener) -> assertThat(listener).extracting("tagsProvider")
.isInstanceOf(JerseyTagsProviderAdapter.class));
});
}
@Test
void httpRequestsAreTimed() {
this.webContextRunner.run((context) -> {
@ -161,4 +180,31 @@ class JerseyServerMetricsAutoConfigurationTests {
}
@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
static class CustomMicrometerJerseyTagsProviderConfiguration {
@Bean
io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider customJerseyTagsProvider() {
return new CustomMicrometerJerseyTagsProvider();
}
}
@SuppressWarnings("deprecation")
static class CustomMicrometerJerseyTagsProvider
implements io.micrometer.core.instrument.binder.jersey.server.JerseyTagsProvider {
@Override
public Iterable<Tag> httpRequestTags(RequestEvent event) {
return null;
}
@Override
public Iterable<Tag> httpLongRequestTags(RequestEvent event) {
return null;
}
}
}