Auto-configure Micrometer Observations
This commit auto-configures in the Micrometer Observations API and its Observation server interceptor. Resolves #1 Signed-off-by: Sunny <hmtang@gmail.com>
This commit is contained in:
@@ -54,6 +54,7 @@
|
||||
<grpc.version>1.63.2</grpc.version>
|
||||
<protobuf-java.version>3.25.5</protobuf-java.version>
|
||||
<google-common-protos.version>2.46.0</google-common-protos.version>
|
||||
<micrometer.version>1.13.6</micrometer.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
@@ -112,6 +113,13 @@
|
||||
<artifactId>proto-google-common-protos</artifactId>
|
||||
<version>${google-common-protos.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-bom</artifactId>
|
||||
<version>${micrometer.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
@@ -75,6 +75,16 @@
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-observation</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.springframework.grpc.autoconfigure.server;
|
||||
|
||||
import io.grpc.ServerBuilder;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.micrometer.core.instrument.binder.grpc.ObservationGrpcServerInterceptor;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.grpc.server.ServerBuilderCustomizer;
|
||||
|
||||
@AutoConfiguration(
|
||||
afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")
|
||||
@ConditionalOnClass(value = { ObservationRegistry.class, ObservationGrpcServerInterceptor.class })
|
||||
@ConditionalOnBean(ObservationRegistry.class)
|
||||
@ConditionalOnProperty(value = "spring.grpc.server.observation.enabled", matchIfMissing = true)
|
||||
public class GrpcServerObservationAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServerInterceptor observationGrpcServerInterceptor(ObservationRegistry observationRegistry) {
|
||||
return new ObservationGrpcServerInterceptor(observationRegistry);
|
||||
}
|
||||
|
||||
@Bean
|
||||
<T extends ServerBuilder<T>> ServerBuilderCustomizer<T> metricsInterceptor(
|
||||
ServerInterceptor observationGrpcServerInterceptor) {
|
||||
return (serverBuilder) -> serverBuilder.intercept(observationGrpcServerInterceptor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.springframework.grpc.autoconfigure.server;
|
||||
|
||||
import io.grpc.ServerBuilder;
|
||||
import io.grpc.ServerInterceptor;
|
||||
import io.micrometer.observation.ObservationRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.grpc.server.ServerBuilderCustomizer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GrpcServerObservationAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(GrpcServerObservationAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void whenObservationRegistryNotProvided_thenObservationInterceptorNotConfigured() {
|
||||
this.contextRunner.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(ServerBuilderCustomizer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenObservationInterceptorConfigured_thenServerBuilderCustomizerConfigured() {
|
||||
this.contextRunner.withBean(ObservationRegistry.class, ObservationRegistry::create).run(context -> {
|
||||
assertThat(context).hasSingleBean(ServerBuilderCustomizer.class);
|
||||
assertThat(context).hasSingleBean(ServerInterceptor.class);
|
||||
ServerInterceptor interceptor = context.getBean(ServerInterceptor.class);
|
||||
ServerBuilderCustomizer customizer = context.getBean(ServerBuilderCustomizer.class);
|
||||
ServerBuilder<?> builder = org.mockito.Mockito.mock(ServerBuilder.class);
|
||||
customizer.customize(builder);
|
||||
org.mockito.Mockito.verify(builder, org.mockito.Mockito.times(1)).intercept(interceptor);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenObservationPropertyDisabled_thenServerBuilderCustomizerNotConfigured() {
|
||||
this.contextRunner.withPropertyValues("spring.grpc.server.observation.enabled=false")
|
||||
.withBean(ObservationRegistry.class, ObservationRegistry::create)
|
||||
.run(context -> {
|
||||
assertThat(context).doesNotHaveBean(ServerBuilderCustomizer.class);
|
||||
assertThat(context).doesNotHaveBean(ServerInterceptor.class);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user