Skip to content

Commit d153228

Browse files
JesseLovelaceFrank NatividadBenWhitehead
authored
feat: enable gRPC client open telemetry metrics reporting (#2590)
Co-authored-by: Frank Natividad <franknatividad@google.com> Co-authored-by: BenWhitehead <BenWhitehead@users.noreply.github.com>
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy