Skip to content

Commit d153228

Browse files
JesseLovelaceFrank NatividadBenWhitehead
authored
feat: enable gRPC client open telemetry metrics reporting (#2590)
Co-authored-by: Frank Natividad <[email protected]> Co-authored-by: BenWhitehead <[email protected]>
1 parent 0555b4a commit d153228

File tree

6 files changed

+634
-7
lines changed

6 files changed

+634
-7
lines changed

google-cloud-storage/pom.xml

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,53 @@
124124
<groupId>com.google.api.grpc</groupId>
125125
<artifactId>gapic-google-cloud-storage-v2</artifactId>
126126
</dependency>
127+
<!-- Open Telemetry dependencies -->
128+
<dependency>
129+
<groupId>io.opentelemetry</groupId>
130+
<artifactId>opentelemetry-sdk</artifactId>
131+
</dependency>
132+
<dependency>
133+
<groupId>io.grpc</groupId>
134+
<artifactId>grpc-opentelemetry</artifactId>
135+
</dependency>
136+
<dependency>
137+
<groupId>io.opentelemetry</groupId>
138+
<artifactId>opentelemetry-api</artifactId>
139+
</dependency>
140+
141+
<dependency>
142+
<groupId>io.opentelemetry</groupId>
143+
<artifactId>opentelemetry-sdk-metrics</artifactId>
144+
</dependency>
145+
<dependency>
146+
<groupId>io.opentelemetry</groupId>
147+
<artifactId>opentelemetry-sdk-common</artifactId>
148+
</dependency>
149+
150+
<dependency>
151+
<groupId>io.opentelemetry</groupId>
152+
<artifactId>opentelemetry-sdk-extension-autoconfigure-spi</artifactId>
153+
</dependency>
154+
155+
<dependency>
156+
<groupId>io.opentelemetry.semconv</groupId>
157+
<artifactId>opentelemetry-semconv</artifactId>
158+
</dependency>
159+
160+
<dependency>
161+
<groupId>com.google.cloud.opentelemetry</groupId>
162+
<artifactId>exporter-metrics</artifactId>
163+
</dependency>
164+
165+
<dependency>
166+
<groupId>io.opentelemetry.contrib</groupId>
167+
<artifactId>opentelemetry-gcp-resources</artifactId>
168+
</dependency>
169+
170+
<dependency>
171+
<groupId>org.checkerframework</groupId>
172+
<artifactId>checker-qual</artifactId>
173+
</dependency>
127174

128175
<!-- Access to exception for retry handling -->
129176
<dependency>
@@ -159,10 +206,7 @@
159206
<artifactId>grpc-googleapis</artifactId>
160207
<scope>runtime</scope>
161208
</dependency>
162-
<dependency>
163-
<groupId>org.checkerframework</groupId>
164-
<artifactId>checker-qual</artifactId>
165-
</dependency>
209+
166210
<!--
167211
We're not using this directly, however there appears to be some resolution
168212
issues when we don't list this dependency. Specifically, the check to ensure the flattened
@@ -184,6 +228,7 @@
184228
<version>0.140.0</version>
185229
<scope>test</scope>
186230
</dependency>
231+
187232
<dependency>
188233
<groupId>com.google.cloud</groupId>
189234
<artifactId>google-cloud-kms</artifactId>
@@ -307,6 +352,12 @@
307352
Add in vintage engine so that both JUnit4 and JUnit5 tests are run by the JUnit5 runner.
308353
-->
309354
<dependency>org.junit.vintage:junit-vintage-engine</dependency>
355+
356+
<!--
357+
These are needed at runtime, but it causes unused declared dependency errors
358+
-->
359+
<dependency>io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi</dependency>
360+
<dependency>io.opentelemetry.semconv:opentelemetry-semconv</dependency>
310361
</ignoredDependencies>
311362
</configuration>
312363
</plugin>

google-cloud-storage/src/main/java/com/google/cloud/storage/GrpcStorageOptions.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ public final class GrpcStorageOptions extends StorageOptions
116116
private final GrpcRetryAlgorithmManager retryAlgorithmManager;
117117
private final Duration terminationAwaitDuration;
118118
private final boolean attemptDirectPath;
119+
private final boolean enableGrpcClientMetrics;
120+
121+
private final boolean grpcClientMetricsManuallyEnabled;
119122
private final GrpcInterceptorProvider grpcInterceptorProvider;
120123
private final BlobWriteSessionConfig blobWriteSessionConfig;
121124

@@ -129,6 +132,8 @@ private GrpcStorageOptions(Builder builder, GrpcStorageDefaults serviceDefaults)
129132
MoreObjects.firstNonNull(
130133
builder.terminationAwaitDuration, serviceDefaults.getTerminationAwaitDuration());
131134
this.attemptDirectPath = builder.attemptDirectPath;
135+
this.enableGrpcClientMetrics = builder.enableGrpcClientMetrics;
136+
this.grpcClientMetricsManuallyEnabled = builder.grpcMetricsManuallyEnabled;
132137
this.grpcInterceptorProvider = builder.grpcInterceptorProvider;
133138
this.blobWriteSessionConfig = builder.blobWriteSessionConfig;
134139
}
@@ -287,6 +292,16 @@ private Tuple<StorageSettings, Opts<UserProject>> resolveSettingsAndOpts() throw
287292
if (scheme.equals("http")) {
288293
channelProviderBuilder.setChannelConfigurator(ManagedChannelBuilder::usePlaintext);
289294
}
295+
296+
if (enableGrpcClientMetrics) {
297+
OpenTelemetryBootstrappingUtils.enableGrpcMetrics(
298+
channelProviderBuilder,
299+
endpoint,
300+
this.getProjectId(),
301+
this.getUniverseDomain(),
302+
!grpcClientMetricsManuallyEnabled);
303+
}
304+
290305
builder.setTransportChannelProvider(channelProviderBuilder.build());
291306
RetrySettings baseRetrySettings = getRetrySettings();
292307
RetrySettings readRetrySettings =
@@ -350,6 +365,7 @@ public int hashCode() {
350365
retryAlgorithmManager,
351366
terminationAwaitDuration,
352367
attemptDirectPath,
368+
enableGrpcClientMetrics,
353369
grpcInterceptorProvider,
354370
blobWriteSessionConfig,
355371
baseHashCode());
@@ -365,6 +381,7 @@ public boolean equals(Object o) {
365381
}
366382
GrpcStorageOptions that = (GrpcStorageOptions) o;
367383
return attemptDirectPath == that.attemptDirectPath
384+
&& enableGrpcClientMetrics == that.enableGrpcClientMetrics
368385
&& Objects.equals(retryAlgorithmManager, that.retryAlgorithmManager)
369386
&& Objects.equals(terminationAwaitDuration, that.terminationAwaitDuration)
370387
&& Objects.equals(grpcInterceptorProvider, that.grpcInterceptorProvider)
@@ -408,11 +425,15 @@ public static final class Builder extends StorageOptions.Builder {
408425
private StorageRetryStrategy storageRetryStrategy;
409426
private Duration terminationAwaitDuration;
410427
private boolean attemptDirectPath = GrpcStorageDefaults.INSTANCE.isAttemptDirectPath();
428+
private boolean enableGrpcClientMetrics =
429+
GrpcStorageDefaults.INSTANCE.isEnableGrpcClientMetrics();
411430
private GrpcInterceptorProvider grpcInterceptorProvider =
412431
GrpcStorageDefaults.INSTANCE.grpcInterceptorProvider();
413432
private BlobWriteSessionConfig blobWriteSessionConfig =
414433
GrpcStorageDefaults.INSTANCE.getDefaultStorageWriterConfig();
415434

435+
private boolean grpcMetricsManuallyEnabled = false;
436+
416437
Builder() {}
417438

418439
Builder(StorageOptions options) {
@@ -421,6 +442,7 @@ public static final class Builder extends StorageOptions.Builder {
421442
this.storageRetryStrategy = gso.getRetryAlgorithmManager().retryStrategy;
422443
this.terminationAwaitDuration = gso.getTerminationAwaitDuration();
423444
this.attemptDirectPath = gso.attemptDirectPath;
445+
this.enableGrpcClientMetrics = gso.enableGrpcClientMetrics;
424446
this.grpcInterceptorProvider = gso.grpcInterceptorProvider;
425447
this.blobWriteSessionConfig = gso.blobWriteSessionConfig;
426448
}
@@ -454,6 +476,21 @@ public GrpcStorageOptions.Builder setAttemptDirectPath(boolean attemptDirectPath
454476
this.attemptDirectPath = attemptDirectPath;
455477
return this;
456478
}
479+
/**
480+
* Option for whether this client should emit internal gRPC client internal metrics to Cloud
481+
* Monitoring. To disable metric reporting, set this to false. True by default. Emitting metrics
482+
* is free and requires minimal CPU and memory.
483+
*
484+
* @since 2.41.0 This new api is in preview and is subject to breaking changes.
485+
*/
486+
@BetaApi
487+
public GrpcStorageOptions.Builder setEnableGrpcClientMetrics(boolean enableGrpcClientMetrics) {
488+
this.enableGrpcClientMetrics = enableGrpcClientMetrics;
489+
if (enableGrpcClientMetrics) {
490+
grpcMetricsManuallyEnabled = true;
491+
}
492+
return this;
493+
}
457494

458495
/** @since 2.14.0 This new api is in preview and is subject to breaking changes. */
459496
@BetaApi
@@ -660,6 +697,12 @@ public boolean isAttemptDirectPath() {
660697
return false;
661698
}
662699

700+
/** @since 2.41.0 This new api is in preview and is subject to breaking changes. */
701+
@BetaApi
702+
public boolean isEnableGrpcClientMetrics() {
703+
return true;
704+
}
705+
663706
/** @since 2.22.3 This new api is in preview and is subject to breaking changes. */
664707
@BetaApi
665708
public GrpcInterceptorProvider grpcInterceptorProvider() {

0 commit comments

Comments
 (0)