Repository navigation
feat(storage): OpenTelemetry client metrics configuration and options - #14484
nidhiii-27 wants to merge 29 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces OpenTelemetry client metrics configuration across GrpcStorageOptions, HttpStorageOptions, and StorageOptions, supported by a new StorageMetricsConfig class and comprehensive unit tests. The review feedback highlights critical issues regarding backward compatibility during deserialization, where the newly added metricInterval field could be null and cause a NullPointerException, and recommends declaring the static resolvers in StorageMetricsConfig as volatile to ensure thread safety during parallel test execution.
cpriti-os
left a comment
There was a problem hiding this comment.
Requesting changes mainly for serialization behaviour and the enablement configuration (see inline comments).
cpriti-os
left a comment
There was a problem hiding this comment.
LGTM once the getMeterProvider() default behavior below is addressed.
c21ff47 to
f1d51f3
Compare
Dhriti07
left a comment
There was a problem hiding this comment.
Suggestion: We repeat the same test cases for both HttpStorageOptions and GrpcStorageOptions across most of StorageOptionsTest. Could we deduplicate these via a small helper or parameterization to reduce duplication across code. This prevents copy-paste drift between HTTP and gRPC and makes future test maintenance easier.
…nfiguration - Add configuration options to StorageOptions, GrpcStorageOptions, and HttpStorageOptions (enableOtelMetrics, enableOtelDebugMetrics, meterProvider, metricInterval). - Add development gate checking system properties and environment variables in StorageMetricsConfig. - Implement package-private instrument registry in StorageClientMetrics. - Update OpenTelemetryBootstrappingUtils to register client views with custom histogram boundaries and create client meter provider. - Add comprehensive unit tests in StorageOptionsTest, StorageClientMetricsTest, and OpenTelemetryBootstrappingUtilsTest.
Apply spotify fmt-maven-plugin formatting to StorageMetricsConfig, StorageClientMetrics, StorageOptionsTest, and StorageClientMetricsTest. [Generated-by: AI]
Use simple class name Duration instead of fully qualified java.time.Duration in GrpcStorageOptions and OpenTelemetryBootstrappingUtils. [Generated-by: AI]
…trappingUtils Apply spotify fmt-maven-plugin formatting to OpenTelemetryBootstrappingUtils. [Generated-by: AI]
…nd views [Generated-by: AI]
… metrics Refactor addClientHistogramView in OpenTelemetryBootstrappingUtils to remove unit selector and custom view description, preserving instrument default descriptions. Remove deferred Phase 2 connection metrics (dnsLookupDuration, tcpConnectDuration, tlsHandshakeDuration) from StorageClientMetrics, CLIENT_LATENCY_HISTOGRAMS, and StorageClientMetricsTest. Ensure clean Duration imports. [Generated-by: AI]
…rProvider Default api parameter to "grpc" instead of "storage" in createClientMeterProvider, allow specifying "json" / "http" transport protocols for Cloud Monitoring monitored resource storage.googleapis.com/Client, and add unit test coverage in OpenTelemetryBootstrappingUtilsTest. [Generated-by: AI]
Update createClientMeterProvider to use prefix custom.googleapis.com with default monitored resource mapping. Add KEY_URL_TEMPLATE attribute key constant in StorageClientMetrics. [Generated-by: AI]
…for default monitored resource
…geClientMetricsTest [Generated-by: AI]
…m boundary helpers
…ions [Generated-by: AI]
…rialization [Generated-by: AI]
… options - In GrpcStorageOptions and HttpStorageOptions: - Add null check in getMetricInterval() defaulting to 60 seconds - Use getMetricInterval() in equals() and hashCode() - Update Javadoc for setMeterProvider to document nullable/default behavior - In StorageOptions: - Update Javadoc for setMeterProvider on Builder - In StorageMetricsConfig: - Make sysPropResolver and envResolver volatile for thread safety - In StorageOptionsTest: - Add unit test verifying deserialization with null metricInterval defaults to 60s and equals/hashCode match - Verify explicit client options take precedence over env vars and sysprops [Generated-by: AI]
[Generated-by: AI]
Format StorageOptions, GrpcStorageOptions, HttpStorageOptions, and StorageOptionsTest using com.spotify.fmt:fmt-maven-plugin:2.25:format under JDK 17 to resolve CI lint check failure. [Generated-by: AI]
[Generated-by: AI]
…iew comments Clamp metric export interval to at least 60 seconds when meterProvider is null and no custom OpenTelemetry is configured, preventing invalid sub-60s intervals during deserialization when falling back to default Cloud Monitoring exporter. [Generated-by: AI]
…ig and tests Deduplicate flag resolution in StorageMetricsConfig by extracting resolveFlag helper, separate multi-behavior tests per go/tott/726, and add input diagnostic messages in looped assertions. [Generated-by: AI]
…Test [Generated-by: AI]
4c7531d to
e7a3588
Compare
…iews (#14398) This PR implements Phase 1 (Core Metrics Registry & Views) of OpenTelemetry Client Metrics in the Java Cloud Storage SDK (`google-cloud-storage`). Following review feedback and architectural alignment across Storage SDKs, this PR focuses strictly on the package-private instrument registry and OpenTelemetry view/histogram bootstrapping, decoupling core infrastructure from public configuration options (handled in follow-up PR #14484). ## Summary of Changes - **Instrument Registry (`StorageClientMetrics`)**: - Implemented package-private registry defining standard and debug OpenTelemetry instruments (call/request durations, operation and retry counters, transfer sizes, TTFB, active requests, stall duration, etc.). - Configured standardized attribute keys and UCUM unit strings (e.g., `s`, `By`, `{operation}`, `{attempt}`, `{retry}`). - **OpenTelemetry Views & Exporter Bootstrapping (`OpenTelemetryBootstrappingUtils`)**: - Registered custom explicit-bucket histogram boundaries for latency (2ms resolution) and size distributions (128KiB to 16GiB). - Configured metric name view translation (`.` to `/`). - Added `createClientMeterProvider` to bootstrap Google Cloud Monitoring export under `custom.googleapis.com` with client attributes (`instance_id`, `api`). - **Testing**: - Added unit test suites (`StorageClientMetricsTest`, `OpenTelemetryBootstrappingUtilsTest`) verifying metric registrations, custom view bucket distributions, and exporter bootstrapping using `InMemoryMetricReader`. --- [Generated-by: AI] --------- Co-authored-by: Dhriti07 <56169283+Dhriti07@users.noreply.github.com>
Description
This PR implements Phase 2 (Configuration & Options API) of the OpenTelemetry Client Metrics feature in the Java Cloud Storage SDK (
google-cloud-storage), building on top of PR #14398 (feat/storage-client-metrics-infra).Key Changes
Public Options API (
StorageOptions,GrpcStorageOptions,HttpStorageOptions):isEnableOtelMetrics()(default:false)isEnableOtelDebugMetrics()(default:false)getMeterProvider()returningio.opentelemetry.api.metrics.MeterProvider(fromopentelemetry-api, avoiding leaking SDK implementation types in public API surface)getMetricInterval()(default: 60 seconds; clamped to 60 seconds when using default Cloud Monitoring exporter)@BetaApi:setEnableOtelMetrics(boolean)setEnableOtelDebugMetrics(boolean)setMeterProvider(MeterProvider)setMetricInterval(Duration)with precondition check requiring positive, non-zero durations (and >= 60 seconds unless a custom MeterProvider or OpenTelemetry is configured).Feature Gates & Environment Variables (
StorageMetricsConfig):GCP_STORAGE_JAVA_ENABLE_OTEL_METRICSGCP_STORAGE_JAVA_ENABLE_OTEL_DEBUG_METRICSfalse).1/t/trueand0/f/false).Serialization Resiliency for Distributed Runtimes:
StorageOptionsis serialized across worker nodes:meterProvideras transient (non-serializable).readObject()when deserializing an instance configured with a custom MeterProvider, indicating fallback to the default provider.getMetricInterval(), clamped interval to minimum 60 seconds ifmeterProvider == null && !customOpenTelemetryConfiguredto ensure compatibility with Cloud Monitoring.Testing:
StorageOptionsTest:IllegalArgumentExceptionon null, zero, negative, or invalid (< 60s without custom provider) metric intervals.ByteArrayOutputStream/ObjectInputStream) ensuring transient meterProvider handling, fallback defaults, and interval clamping post-deserialization.[Generated-by: AI]