Skip to content

Commit 9919d82

Browse files
author
Alexander Furer
committed
closes #174
1 parent baba7fa commit 9919d82

File tree

4 files changed

+54
-12
lines changed

4 files changed

+54
-12
lines changed

README.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,9 @@ Please continue to https://docs.spring.io/spring-cloud-sleuth/docs/current/refer
248248
By including `org.springframework.boot:spring-boot-starter-actuator` dependency,
249249
the starter will collect gRPC server metrics , broken down by
250250

251-
. gRPC service method FQN (Fully Qualified Name)
252-
. https://grpc.github.io/grpc-java/javadoc/io/grpc/Status.Code.html[Response status code]
251+
. `method` - gRPC service method FQN (Fully Qualified Name)
252+
. `result` - https://grpc.github.io/grpc-java/javadoc/io/grpc/Status.Code.html[Response status code]
253+
. `address` - server local address (if you exposed additional listen addresses, with `grpc.netty-server.additional-listen-addresses` property)
253254

254255
After configuring the exporter of your https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-metrics[choice],
255256
you should see the `timer` named `grpc.server.calls`.

grpc-spring-boot-starter-demo/src/test/java/org/lognet/springboot/grpc/GrpcMeterTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package org.lognet.springboot.grpc;
22

3+
import io.grpc.examples.GreeterGrpc;
34
import io.micrometer.core.instrument.MeterRegistry;
45
import io.micrometer.core.instrument.Timer;
56
import io.micrometer.core.instrument.simple.SimpleConfig;
67
import org.awaitility.Awaitility;
78
import org.junit.Before;
89
import org.junit.runner.RunWith;
10+
import org.lognet.springboot.grpc.context.LocalRunningGrpcPort;
911
import org.lognet.springboot.grpc.demo.DemoApp;
1012
import org.springframework.beans.factory.annotation.Autowired;
1113
import org.springframework.boot.test.context.SpringBootTest;
@@ -16,7 +18,9 @@
1618
import java.util.concurrent.TimeUnit;
1719

1820
import static org.hamcrest.MatcherAssert.assertThat;
21+
import static org.hamcrest.Matchers.containsString;
1922
import static org.hamcrest.Matchers.greaterThan;
23+
import static org.hamcrest.Matchers.is;
2024
import static org.hamcrest.Matchers.notNullValue;
2125
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
2226

@@ -27,6 +31,9 @@ public class GrpcMeterTest extends GrpcServerTestBase {
2731
@Autowired
2832
private MeterRegistry registry;
2933

34+
@LocalRunningGrpcPort
35+
private int port;
36+
3037
@Autowired
3138
private SimpleConfig registryConfig;
3239

@@ -49,5 +56,14 @@ protected void afterGreeting() {
4956
assertThat(timer.max(TimeUnit.MILLISECONDS),greaterThan(0d));
5057
assertThat(timer.mean(TimeUnit.MILLISECONDS),greaterThan(0d));
5158
assertThat(timer.totalTime(TimeUnit.MILLISECONDS),greaterThan(0d));
59+
60+
61+
final String addressTag = timer.getId().getTag("address");
62+
assertThat(addressTag,notNullValue());
63+
assertThat(addressTag,containsString(String.valueOf(port)));
64+
65+
final String methodTag = timer.getId().getTag("method");
66+
assertThat(methodTag,notNullValue());
67+
assertThat(methodTag,is(GreeterGrpc.getSayHelloMethod().getFullMethodName()));
5268
}
5369
}

grpc-spring-boot-starter-demo/src/test/resources/application-measure.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,10 @@ management:
33
export:
44
simple:
55
step: 10s
6-
enabled: true
6+
enabled: true
7+
8+
grpc:
9+
netty-server:
10+
primary-listen-address: localhost:0
11+
additional-listen-addresses:
12+
- localhost:0

grpc-spring-boot-starter/src/main/java/org/lognet/springboot/grpc/autoconfigure/metrics/GRpcMetricsAutoConfiguration.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.lognet.springboot.grpc.autoconfigure.metrics;
22

33
import io.grpc.ForwardingServerCall;
4+
import io.grpc.Grpc;
45
import io.grpc.Metadata;
56
import io.grpc.ServerCall;
67
import io.grpc.ServerCallHandler;
@@ -10,6 +11,7 @@
1011
import io.micrometer.core.instrument.Timer;
1112
import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
1213
import org.lognet.springboot.grpc.GRpcService;
14+
import org.lognet.springboot.grpc.autoconfigure.GRpcServerProperties;
1315
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
1416
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
1517
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@@ -21,6 +23,9 @@
2123
import org.springframework.context.annotation.Configuration;
2224
import org.springframework.core.Ordered;
2325

26+
import java.net.SocketAddress;
27+
import java.util.Optional;
28+
2429
@Configuration
2530
@AutoConfigureAfter({MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class})
2631
@ConditionalOnClass({MeterRegistry.class})
@@ -45,21 +50,28 @@ static class GrpcServiceCondition {
4550

4651
static class MonitoringServerCall<ReqT, RespT> extends ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT> {
4752

53+
private final boolean addAddressTag;
4854
private MeterRegistry registry;
4955
final Timer.Sample start;
50-
protected MonitoringServerCall(ServerCall<ReqT, RespT> delegate, MeterRegistry registry) {
56+
protected MonitoringServerCall(ServerCall<ReqT, RespT> delegate, MeterRegistry registry, boolean addAddressTag) {
5157
super(delegate);
5258
this.start = Timer.start(registry);
5359
this.registry = registry;
60+
this.addAddressTag = addAddressTag;
5461

5562

5663
}
5764
@Override
5865
public void close(Status status, Metadata trailers) {
59-
start.stop(Timer.builder("grpc.server.calls")
60-
.tag("method",getMethodDescriptor().getFullMethodName())
61-
.tag("result",status.getCode().name())
62-
.register(registry));
66+
final Timer.Builder timerBuilder = Timer.builder("grpc.server.calls")
67+
.tag("method", getMethodDescriptor().getFullMethodName())
68+
.tag("result", status.getCode().name());
69+
if (addAddressTag){
70+
Optional.ofNullable(delegate().getAttributes().get(Grpc.TRANSPORT_ATTR_LOCAL_ADDR))
71+
.map(SocketAddress::toString)
72+
.ifPresent(a->timerBuilder.tag("address",a));
73+
}
74+
start.stop(timerBuilder.register(registry));
6375

6476
super.close(status, trailers);
6577
}
@@ -69,14 +81,17 @@ static class MonitoringServerInterceptor implements ServerInterceptor, Ordered {
6981

7082

7183
private MeterRegistry registry;
84+
private boolean addAddressTag;
85+
7286

73-
public MonitoringServerInterceptor(MeterRegistry registry) {
87+
public MonitoringServerInterceptor(MeterRegistry registry,boolean addAddressTag) {
7488
this.registry = registry;
89+
this.addAddressTag = addAddressTag;
7590
}
7691

7792
@Override
7893
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
79-
return next.startCall(new MonitoringServerCall<>(call,registry), headers);
94+
return next.startCall(new MonitoringServerCall<>(call,registry,addAddressTag), headers);
8095

8196
}
8297

@@ -88,7 +103,11 @@ public int getOrder() {
88103

89104
@Bean
90105
@GRpcGlobalInterceptor
91-
public ServerInterceptor measure(MeterRegistry registry){
92-
return new MonitoringServerInterceptor(registry);
106+
public ServerInterceptor measure(MeterRegistry registry, GRpcServerProperties properties){
107+
final Boolean hasMultipleAddresses = Optional.ofNullable(properties.getNettyServer())
108+
.map(GRpcServerProperties.NettyServerProperties::getAdditionalListenAddresses)
109+
.map(l -> !l.isEmpty())
110+
.orElse(false);
111+
return new MonitoringServerInterceptor(registry,hasMultipleAddresses);
93112
}
94113
}

0 commit comments

Comments
 (0)