Repository navigation
feat(storage): add StorageErrorTypeMapper for standard metrics - #14694
nidhiii-27 wants to merge 33 commits into
Conversation
a1393ca to
41c47ff
Compare
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive support for OpenTelemetry client metrics and debug metrics in Google Cloud Storage, including configuration options in StorageOptions, GrpcStorageOptions, and HttpStorageOptions. It adds utility classes such as StorageClientMetrics for instrument registration, StorageErrorTypeMapper for mapping exceptions to canonical error strings, StorageMetricsConfig for environment-based configuration, and StorageMetricsContext for tracking metric state across boundaries, along with corresponding unit tests. Feedback on the changes suggests simplifying a redundant null check on a transient field in StorageOptions, defensively preventing infinite loops from self-causation in StorageErrorTypeMapper's exception unwrapping, and robustly checking for authentication exceptions by using full class names instead of simple names to correctly handle anonymous classes.
I am having trouble creating individual review comments. Click here to see my feedback.
java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageOptions.java (262)
Since meterProvider is marked as transient, it will not be serialized and will always be null after deserialization. Therefore, the check this.meterProvider != null in readObject is redundant and will always evaluate to false. We can simplify this to only check this.customMeterProviderConfigured.
if (this.customMeterProviderConfigured) {
java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageErrorTypeMapper.java (159-162)
To prevent potential infinite loops in case of custom exceptions with self-causation (where t.getCause() == t), we should defensively add a check for t.getCause() != t in the while loop condition, similar to how it is handled at the end of the mapThrowable method.
while ((t instanceof ExecutionException || t instanceof CompletionException)
&& t.getCause() != null
&& t.getCause() != t) {
t = t.getCause();
}
java-storage/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageErrorTypeMapper.java (258)
Using t.getClass().getSimpleName() can return an empty string "" for anonymous classes, which would bypass the contains("Auth") check even if the base class name contains "Auth". Using the full class name className.contains("Auth") is more robust and avoids extra string parsing overhead.
if (className.contains("Auth")) {
608c46a to
1bf9a9d
Compare
- Map HTTP 401 to UNAUTHENTICATED and HTTP 502 to UNAVAILABLE. - Guard against self-causation cycles in ExecutionException/CompletionException loops. - Check hasSpecificClientCause on StatusRuntimeException, StatusException, and ApiException before status code mapping. - Support cause unwrapping for gRPC exceptions on StorageException. - Add unit tests for gRPC network causes and self-referencing exceptions. [Generated-by: AI]
…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]
6374b3e to
98fb508
Compare
98fb508 to
84a5ac6
Compare
84a5ac6 to
ed62afa
Compare
…eErrorTypeMapper [Generated-by: AI]
[Generated-by: AI]
…pper [Generated-by: AI]
… tests - Walk the class hierarchy in isAuthException to support anonymous and custom subclasses, and remove redundant simpleName check. - Extract mapSpecificClientCause and mapKnownCause helpers and check specific client causes on HttpResponseException. - Guard against null StatusCode on ApiException. - Restrict single-use HTTP mapping status constants to private visibility, use Ascii.toLowerCase, add boolean parameter comments, and move private constructor to bottom of class. - Split multi-behavior tests in StorageErrorTypeMapperTest, deduplicate test exception classes and CRC32C fixtures, and import SigningException. [Generated-by: AI]
Adds mapping logic to classify exceptions, gRPC status codes, and HTTP response codes into standard OpenTelemetry error types.