Skip to content

Commit 99c8ad0

Browse files
committed
#1: Autoconfigure metric registry support
Signed-off-by: Sunny <hmtang@gmail.com> [resolves #1]
1 parent 5ab408b commit 99c8ad0

File tree

6 files changed

+78
-8
lines changed

6 files changed

+78
-8
lines changed

samples/grpc-server/src/test/java/org/springframework/grpc/sample/GrpcServerApplicationTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.springframework.grpc.sample;
22

3+
import static org.assertj.core.api.Assertions.assertThat;
34
import static org.junit.jupiter.api.Assertions.assertEquals;
45

6+
import io.micrometer.core.instrument.MeterRegistry;
57
import org.apache.commons.logging.Log;
68
import org.apache.commons.logging.LogFactory;
79
import org.junit.jupiter.api.Test;
@@ -30,6 +32,9 @@ public static void main(String[] args) {
3032
@Autowired
3133
private SimpleGrpc.SimpleBlockingStub stub;
3234

35+
@Autowired
36+
private MeterRegistry meterRegistry;
37+
3338
@Test
3439
@DirtiesContext
3540
void contextLoads() {
@@ -43,6 +48,18 @@ void serverResponds() {
4348
assertEquals("Hello ==> Alien", response.getMessage());
4449
}
4550

51+
@Test
52+
@DirtiesContext
53+
void verifyMetrics() {
54+
log.info("Verify stats are collected");
55+
stub.sayHello(HelloRequest.newBuilder().setName("Alien").build());
56+
assertThat(meterRegistry.get("grpc.server.requests.received").counter().count()).isEqualTo(1);
57+
assertThat(meterRegistry.get("grpc.server.responses.sent").counter().count()).isEqualTo(1);
58+
stub.sayHello(HelloRequest.newBuilder().setName("Jamie").build());
59+
assertThat(meterRegistry.get("grpc.server.requests.received").counter().count()).isEqualTo(2);
60+
assertThat(meterRegistry.get("grpc.server.responses.sent").counter().count()).isEqualTo(2);
61+
}
62+
4663
@TestConfiguration
4764
static class ExtraConfiguration {
4865

spring-grpc-core/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,23 @@
6767
<artifactId>grpc-stub</artifactId>
6868
</dependency>
6969

70+
<dependency>
71+
<groupId>io.micrometer</groupId>
72+
<artifactId>micrometer-core</artifactId>
73+
</dependency>
74+
<dependency>
75+
<groupId>io.micrometer</groupId>
76+
<artifactId>micrometer-registry-prometheus</artifactId>
77+
</dependency>
78+
7079
<dependency>
7180
<groupId>org.junit.jupiter</groupId>
7281
<artifactId>junit-jupiter</artifactId>
7382
<version>${junit.version}</version>
7483
<scope>test</scope>
7584
</dependency>
7685

86+
7787
</dependencies>
7888

7989

spring-grpc-core/src/main/java/org/springframework/grpc/server/DefaultGrpcServerFactory.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,11 @@
2323

2424
import com.google.common.collect.Lists;
2525

26-
import io.grpc.Grpc;
27-
import io.grpc.InsecureServerCredentials;
28-
import io.grpc.Server;
29-
import io.grpc.ServerBuilder;
30-
import io.grpc.ServerCredentials;
31-
import io.grpc.ServerProvider;
32-
import io.grpc.ServerServiceDefinition;
26+
import io.grpc.*;
3327

3428
import org.apache.commons.logging.Log;
3529
import org.apache.commons.logging.LogFactory;
30+
import org.springframework.beans.factory.annotation.Autowired;
3631
import org.springframework.grpc.internal.GrpcUtils;
3732

3833
/**
@@ -56,6 +51,9 @@ public class DefaultGrpcServerFactory<T extends ServerBuilder<T>> implements Grp
5651

5752
private final List<ServerBuilderCustomizer<T>> serverBuilderCustomizers;
5853

54+
@Autowired
55+
private List<ServerInterceptor> serverInterceptors;
56+
5957
public DefaultGrpcServerFactory(String address, List<ServerBuilderCustomizer<T>> serverBuilderCustomizers) {
6058
this.address = address;
6159
this.serverBuilderCustomizers = Objects.requireNonNull(serverBuilderCustomizers, "serverBuilderCustomizers");
@@ -83,7 +81,11 @@ public void addService(ServerServiceDefinition service) {
8381
*/
8482
@SuppressWarnings("unchecked")
8583
protected T newServerBuilder() {
86-
return (T) Grpc.newServerBuilderForPort(port(), credentials());
84+
var builder = Grpc.newServerBuilderForPort(port(), credentials());
85+
for (ServerInterceptor interceptor : serverInterceptors) {
86+
builder.intercept(interceptor);
87+
}
88+
return (T) builder;
8789
}
8890

8991
/**

spring-grpc-dependencies/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
<grpc.version>1.63.2</grpc.version>
5555
<protobuf-java.version>3.25.5</protobuf-java.version>
5656
<google-common-protos.version>2.46.0</google-common-protos.version>
57+
<micrometer.version>1.13.6</micrometer.version>
5758
</properties>
5859

5960
<dependencyManagement>
@@ -112,6 +113,16 @@
112113
<artifactId>proto-google-common-protos</artifactId>
113114
<version>${google-common-protos.version}</version>
114115
</dependency>
116+
<dependency>
117+
<groupId>io.micrometer</groupId>
118+
<artifactId>micrometer-core</artifactId>
119+
<version>${micrometer.version}</version>
120+
</dependency>
121+
<dependency>
122+
<groupId>io.micrometer</groupId>
123+
<artifactId>micrometer-registry-prometheus</artifactId>
124+
<version>${micrometer.version}</version>
125+
</dependency>
115126
</dependencies>
116127
</dependencyManagement>
117128

spring-grpc-spring-boot-autoconfigure/src/main/java/org/springframework/grpc/autoconfigure/server/GrpcServerAutoConfiguration.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
*/
1616
package org.springframework.grpc.autoconfigure.server;
1717

18+
import io.grpc.ServerInterceptor;
19+
import io.micrometer.core.instrument.MeterRegistry;
20+
import io.micrometer.core.instrument.binder.grpc.MetricCollectingServerInterceptor;
21+
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
1822
import org.springframework.beans.factory.ObjectProvider;
1923
import org.springframework.boot.autoconfigure.AutoConfiguration;
2024
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -69,4 +73,15 @@ ServerBuilderCustomizers serverBuilderCustomizers(ObjectProvider<ServerBuilderCu
6973
return new ServerBuilderCustomizers(customizers.orderedStream().toList());
7074
}
7175

76+
@ConditionalOnMissingBean
77+
@Bean
78+
public MeterRegistry meterRegistry() {
79+
return new SimpleMeterRegistry();
80+
}
81+
82+
@Bean
83+
public ServerInterceptor metricCollectingServerInterceptor(MeterRegistry meterRegistry) {
84+
return new MetricCollectingServerInterceptor(meterRegistry);
85+
}
86+
7287
}

spring-grpc-spring-boot-autoconfigure/src/test/java/org/springframework/grpc/autoconfigure/server/GrpcServerAutoConfigurationTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.List;
2828
import java.util.concurrent.TimeUnit;
2929

30+
import io.micrometer.core.instrument.MeterRegistry;
3031
import org.assertj.core.api.InstanceOfAssertFactories;
3132
import org.junit.jupiter.api.Test;
3233
import org.mockito.InOrder;
@@ -246,6 +247,20 @@ void nettyServerFactoryAutoConfiguredWithSsl() {
246247
NettyGrpcServerFactory.class);
247248
}
248249

250+
@Test
251+
void whenHasUserDefinedMeterRegistryDoesNotAutoConfigureBean() {
252+
MeterRegistry customMeterRegistry = mock(MeterRegistry.class);
253+
this.contextRunner()
254+
.withBean("customMeterRegistry", MeterRegistry.class, () -> customMeterRegistry)
255+
.run((context) -> assertThat(context).getBean(MeterRegistry.class).isSameAs(customMeterRegistry));
256+
}
257+
258+
@Test
259+
void serverMeterRegistryAutoConfiguredAsExpected() {
260+
this.contextRunner()
261+
.run((context) -> assertThat(context).getBean(MeterRegistry.class).hasFieldOrProperty("config"));
262+
}
263+
249264
@Configuration(proxyBeanMethods = false)
250265
static class ServerBuilderCustomizersConfig {
251266

0 commit comments

Comments
 (0)