Skip to content

Commit 8239f8a

Browse files
Merge pull request #1081 from stanley-cheung/add-instrumentation-metric-tag
Add instrumentation tags to grpc metrics
2 parents de71ce3 + 2516559 commit 8239f8a

File tree

5 files changed

+115
-12
lines changed

5 files changed

+115
-12
lines changed

grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/metrics/MetricsClientStreamTracers.java

+17-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import io.grpc.Status;
3636
import io.grpc.Status.Code;
3737
import io.micrometer.core.instrument.Tags;
38+
import net.devh.boot.grpc.common.util.Constants;
3839

3940
/**
4041
* Provides factories for {@link io.grpc.StreamTracer} that records metrics.
@@ -47,6 +48,8 @@
4748
final class MetricsClientStreamTracers {
4849
private static final Supplier<Stopwatch> STOPWATCH_SUPPLIER = Stopwatch::createUnstarted;
4950
private final Supplier<Stopwatch> stopwatchSupplier;
51+
private static final String INSTRUMENTATION_SOURCE_TAG_KEY = "instrumentation_source";
52+
private static final String INSTRUMENTATION_VERSION_TAG_KEY = "instrumentation_version";
5053

5154
MetricsClientStreamTracers() {
5255
this(STOPWATCH_SUPPLIER);
@@ -127,7 +130,10 @@ public void streamClosed(Status status) {
127130

128131
void recordFinishedAttempt() {
129132
Tags attemptMetricTags =
130-
Tags.of("grpc.method", fullMethodName, "grpc.status", statusCode.toString());
133+
Tags.of("grpc.method", fullMethodName,
134+
"grpc.status", statusCode.toString(),
135+
INSTRUMENTATION_SOURCE_TAG_KEY, Constants.LIBRARY_NAME,
136+
INSTRUMENTATION_VERSION_TAG_KEY, Constants.VERSION);
131137
this.metricsClientMeters.getClientAttemptDuration()
132138
.withTags(attemptMetricTags)
133139
.record(attemptNanos, TimeUnit.NANOSECONDS);
@@ -168,7 +174,9 @@ static final class CallAttemptsTracerFactory extends ClientStreamTracer.Factory
168174

169175
// Record here in case newClientStreamTracer() would never be called.
170176
this.metricsClientMeters.getAttemptCounter()
171-
.withTags(Tags.of("grpc.method", fullMethodName))
177+
.withTags(Tags.of("grpc.method", fullMethodName,
178+
INSTRUMENTATION_SOURCE_TAG_KEY, Constants.LIBRARY_NAME,
179+
INSTRUMENTATION_VERSION_TAG_KEY, Constants.VERSION))
172180
.increment();
173181
}
174182

@@ -188,7 +196,9 @@ public ClientStreamTracer newClientStreamTracer(StreamInfo info, Metadata metada
188196
// attempt, as first attempt cannot be a transparent retry.
189197
if (attemptsPerCall.get() > 0) {
190198
this.metricsClientMeters.getAttemptCounter()
191-
.withTags((Tags.of("grpc.method", fullMethodName)))
199+
.withTags((Tags.of("grpc.method", fullMethodName,
200+
INSTRUMENTATION_SOURCE_TAG_KEY, Constants.LIBRARY_NAME,
201+
INSTRUMENTATION_VERSION_TAG_KEY, Constants.VERSION)))
192202
.increment();
193203
}
194204
if (!info.isTransparentRetry()) {
@@ -248,7 +258,10 @@ void recordFinishedCall() {
248258
}
249259
callLatencyNanos = clientCallStopWatch.elapsed(TimeUnit.NANOSECONDS);
250260
Tags clientCallMetricTags =
251-
Tags.of("grpc.method", this.fullMethodName, "grpc.status", status.getCode().toString());
261+
Tags.of("grpc.method", this.fullMethodName,
262+
"grpc.status", status.getCode().toString(),
263+
INSTRUMENTATION_SOURCE_TAG_KEY, Constants.LIBRARY_NAME,
264+
INSTRUMENTATION_VERSION_TAG_KEY, Constants.VERSION);
252265
this.metricsClientMeters.getClientCallDuration()
253266
.withTags(clientCallMetricTags)
254267
.record(callLatencyNanos, TimeUnit.NANOSECONDS);

grpc-client-spring-boot-starter/src/test/java/net/devh/boot/grpc/client/metrics/MetricsClientStreamTracersTest.java

+39-6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
3838
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
3939
import net.devh.boot.grpc.client.metrics.MetricsClientStreamTracers.CallAttemptsTracerFactory;
40+
import net.devh.boot.grpc.common.util.Constants;
4041

4142
/**
4243
* Tests for {@link MetricsClientStreamTracers}.
@@ -61,6 +62,10 @@ class MetricsClientStreamTracersTest {
6162
private static final String GRPC_METHOD_TAG_KEY = "grpc.method";
6263
private static final String GRPC_STATUS_TAG_KEY = "grpc.status";
6364
private static final String FULL_METHOD_NAME = "package1.service1/method1";
65+
private static final String INSTRUMENTATION_SOURCE_TAG_KEY = "instrumentation_source";
66+
private static final String INSTRUMENTATION_SOURCE_TAG_VALUE = Constants.LIBRARY_NAME;
67+
private static final String INSTRUMENTATION_VERSION_TAG_KEY = "instrumentation_version";
68+
private static final String INSTRUMENTATION_VERSION_TAG_VALUE = Constants.VERSION;
6469

6570
private static class StringInputStream extends InputStream {
6671
final String string;
@@ -125,6 +130,8 @@ void clientBasicMetrics() {
125130

126131
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
127132
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
133+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
134+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
128135
.counter()
129136
.count()).isEqualTo(1);
130137

@@ -146,11 +153,16 @@ void clientBasicMetrics() {
146153

147154
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
148155
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
156+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
157+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
149158
.counter()
150159
.count()).isEqualTo(1);
151160

152161
Tags expectedTags =
153-
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME, GRPC_STATUS_TAG_KEY, Status.Code.OK.toString());
162+
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME,
163+
GRPC_STATUS_TAG_KEY, Status.Code.OK.toString(),
164+
INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE,
165+
INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE);
154166

155167
HistogramSnapshot attemptDurationSnapshot = meterRegistry.get(CLIENT_ATTEMPT_DURATION)
156168
.tags(expectedTags)
@@ -200,6 +212,8 @@ void recordAttemptMetrics() {
200212

201213
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
202214
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
215+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
216+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
203217
.counter()
204218
.count()).isEqualTo(1);
205219

@@ -213,10 +227,15 @@ void recordAttemptMetrics() {
213227
tracer.streamClosed(Status.UNAVAILABLE);
214228

215229
Tags expectedUnailableStatusTags =
216-
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME, GRPC_STATUS_TAG_KEY, Status.Code.UNAVAILABLE.toString());
230+
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME,
231+
GRPC_STATUS_TAG_KEY, Status.Code.UNAVAILABLE.toString(),
232+
INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE,
233+
INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE);
217234

218235
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
219236
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
237+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
238+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
220239
.counter()
221240
.count()).isEqualTo(1);
222241
assertThat(meterRegistry.get(CLIENT_ATTEMPT_DURATION)
@@ -248,10 +267,15 @@ void recordAttemptMetrics() {
248267
tracer.streamClosed(Status.NOT_FOUND);
249268

250269
Tags expectedNotFoundStatusTags =
251-
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME, GRPC_STATUS_TAG_KEY, Status.Code.NOT_FOUND.toString());
270+
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME,
271+
GRPC_STATUS_TAG_KEY, Status.Code.NOT_FOUND.toString(),
272+
INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE,
273+
INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE);
252274

253275
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
254276
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
277+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
278+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
255279
.counter()
256280
.count()).isEqualTo(2);
257281

@@ -290,6 +314,8 @@ void recordAttemptMetrics() {
290314

291315
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
292316
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
317+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
318+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
293319
.counter()
294320
.count()).isEqualTo(3);
295321

@@ -342,10 +368,15 @@ void recordAttemptMetrics() {
342368
callAttemptsTracerFactory.callEnded(Status.OK);
343369

344370
Tags expectedOKStatusTags =
345-
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME, GRPC_STATUS_TAG_KEY, Status.Code.OK.toString());
371+
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME,
372+
GRPC_STATUS_TAG_KEY, Status.Code.OK.toString(),
373+
INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE,
374+
INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE);
346375

347376
assertThat(meterRegistry.get(CLIENT_ATTEMPT_STARTED)
348377
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
378+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
379+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
349380
.counter()
350381
.count()).isEqualTo(4);
351382
assertThat(meterRegistry.get(CLIENT_ATTEMPT_DURATION)
@@ -388,8 +419,10 @@ void clientStreamNeverCreatedStillRecordMetrics() {
388419
callAttemptsTracerFactory.callEnded(status);
389420

390421
Tags expectedDeadlineExceededStatusTags =
391-
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME, GRPC_STATUS_TAG_KEY,
392-
Status.Code.DEADLINE_EXCEEDED.toString());
422+
Tags.of(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME,
423+
GRPC_STATUS_TAG_KEY, Status.Code.DEADLINE_EXCEEDED.toString(),
424+
INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE,
425+
INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE);
393426

394427
HistogramSnapshot attemptDurationSnapshot = meterRegistry.get(CLIENT_ATTEMPT_DURATION)
395428
.tags(expectedDeadlineExceededStatusTags)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2016-2023 The gRPC-Spring Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package net.devh.boot.grpc.common.util;
18+
19+
/**
20+
* Class that contains shared constants.
21+
*/
22+
public final class Constants {
23+
24+
/**
25+
* A constant that defines the current version of the library.
26+
*/
27+
public static final String VERSION = "v" + Constants.class.getPackage().getImplementationVersion();
28+
29+
/**
30+
* A constant that defines the library name that can be used as metric tags.
31+
*/
32+
public static final String LIBRARY_NAME = "grpc-spring";
33+
34+
private Constants() {}
35+
36+
}

grpc-server-spring-boot-starter/src/main/java/net/devh/boot/grpc/server/metrics/MetricsServerStreamTracers.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.grpc.Status;
3131
import io.micrometer.core.instrument.MeterRegistry;
3232
import io.micrometer.core.instrument.Tags;
33+
import net.devh.boot.grpc.common.util.Constants;
3334

3435
/**
3536
* Provides factories for {@link io.grpc.StreamTracer} that records metrics.
@@ -45,6 +46,8 @@ public final class MetricsServerStreamTracers {
4546

4647
private static final Supplier<Stopwatch> STOPWATCH_SUPPLIER = Stopwatch::createUnstarted;
4748
private final Supplier<Stopwatch> stopwatchSupplier;
49+
private static final String INSTRUMENTATION_SOURCE_TAG_KEY = "instrumentation_source";
50+
private static final String INSTRUMENTATION_VERSION_TAG_KEY = "instrumentation_version";
4851

4952
public MetricsServerStreamTracers() {
5053
this(STOPWATCH_SUPPLIER);
@@ -100,7 +103,9 @@ private static final class ServerTracer extends ServerStreamTracer {
100103
@Override
101104
public void serverCallStarted(ServerCallInfo<?, ?> callInfo) {
102105
this.metricsServerMeters.getServerCallCounter()
103-
.withTags(Tags.of("grpc.method", this.fullMethodName))
106+
.withTags(Tags.of("grpc.method", this.fullMethodName,
107+
INSTRUMENTATION_SOURCE_TAG_KEY, Constants.LIBRARY_NAME,
108+
INSTRUMENTATION_VERSION_TAG_KEY, Constants.VERSION))
104109
.increment();
105110
}
106111

@@ -122,7 +127,10 @@ public void streamClosed(Status status) {
122127
long callLatencyNanos = stopwatch.elapsed(TimeUnit.NANOSECONDS);
123128

124129
Tags serverMetricTags =
125-
Tags.of("grpc.method", this.fullMethodName, "grpc.status", status.getCode().toString());
130+
Tags.of("grpc.method", this.fullMethodName,
131+
"grpc.status", status.getCode().toString(),
132+
INSTRUMENTATION_SOURCE_TAG_KEY, Constants.LIBRARY_NAME,
133+
INSTRUMENTATION_VERSION_TAG_KEY, Constants.VERSION);
126134
this.metricsServerMeters.getServerCallDuration()
127135
.withTags(serverMetricTags)
128136
.record(callLatencyNanos, TimeUnit.NANOSECONDS);

grpc-server-spring-boot-starter/src/test/java/net/devh/boot/grpc/server/metrics/MetricsServerStreamTracersTest.java

+13
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import io.micrometer.core.instrument.distribution.CountAtBucket;
3939
import io.micrometer.core.instrument.distribution.HistogramSnapshot;
4040
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
41+
import net.devh.boot.grpc.common.util.Constants;
4142

4243
/**
4344
* Tests for {@link MetricsServerStreamTracers}.
@@ -54,6 +55,10 @@ class MetricsServerStreamTracersTest {
5455
private static final String FULL_METHOD_NAME = "package1.service1/method1";
5556
private static final String GRPC_METHOD_TAG_KEY = "grpc.method";
5657
private static final String GRPC_STATUS_TAG_KEY = "grpc.status";
58+
private static final String INSTRUMENTATION_SOURCE_TAG_KEY = "instrumentation_source";
59+
private static final String INSTRUMENTATION_SOURCE_TAG_VALUE = Constants.LIBRARY_NAME;
60+
private static final String INSTRUMENTATION_VERSION_TAG_KEY = "instrumentation_version";
61+
private static final String INSTRUMENTATION_VERSION_TAG_VALUE = Constants.VERSION;
5762

5863

5964
private static class StringInputStream extends InputStream {
@@ -150,6 +155,8 @@ void serverBasicMetrics() {
150155

151156
assertThat(meterRegistry.get(SERVER_CALL_STARTED)
152157
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
158+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
159+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
153160
.counter()
154161
.count()).isEqualTo(1);
155162

@@ -170,6 +177,8 @@ void serverBasicMetrics() {
170177
HistogramSnapshot sentMessageSizeSnapShot = meterRegistry.get(SERVER_SENT_COMPRESSED_MESSAGE_SIZE)
171178
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
172179
.tag(GRPC_STATUS_TAG_KEY, Status.Code.CANCELLED.toString())
180+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
181+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
173182
.summary()
174183
.takeSnapshot();
175184
HistogramSnapshot expectedSentMessageSizeHistogram = HistogramSnapshot.empty(1L, 1127L, 1127L);
@@ -181,6 +190,8 @@ void serverBasicMetrics() {
181190
meterRegistry.get(SERVER_RECEIVED_COMPRESSED_MESSAGE_SIZE)
182191
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
183192
.tag(GRPC_STATUS_TAG_KEY, Status.Code.CANCELLED.toString())
193+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
194+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
184195
.summary()
185196
.takeSnapshot();
186197
HistogramSnapshot expectedReceivedMessageSizeHistogram = HistogramSnapshot.empty(1L, 188L, 188L);
@@ -197,6 +208,8 @@ void serverBasicMetrics() {
197208
HistogramSnapshot callDurationSnapshot = meterRegistry.get(SERVER_CALL_DURATION)
198209
.tag(GRPC_METHOD_TAG_KEY, FULL_METHOD_NAME)
199210
.tag(GRPC_STATUS_TAG_KEY, Status.Code.CANCELLED.toString())
211+
.tag(INSTRUMENTATION_SOURCE_TAG_KEY, INSTRUMENTATION_SOURCE_TAG_VALUE)
212+
.tag(INSTRUMENTATION_VERSION_TAG_KEY, INSTRUMENTATION_VERSION_TAG_VALUE)
200213
.timer()
201214
.takeSnapshot();
202215
HistogramSnapshot expectedCallDurationHistogram = HistogramSnapshot.empty(1L, 40L, 40);

0 commit comments

Comments
 (0)