Repository navigation
feat(storage): add StorageMetricsContext for operation metrics state - #14728
Conversation
…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]
[Generated-by: AI]
…pper [Generated-by: AI]
…torage-metrics-context [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]
- Consolidate CONNECTION_REFUSED, CONNECTION_RESET, and CONNECTIVITY into CONNECTION_ERROR. - Keep DEADLINE_EXCEEDED for server/RPC status codes and HTTP 408/504, reserving TIMEOUT for client timeouts. - Map HTTP 409 to ABORTED. - Include IOException in hasSpecificClientCause so wrapped IOExceptions map to CONNECTION_ERROR. - Match server-side CRC32C and MD5 checksum mismatch messages in isChecksumMismatch. [Generated-by: AI]
Explicitly declare com.google.api:gax-httpjson in java-storage/google-cloud-storage/pom.xml to satisfy Maven dependency:analyze. [Generated-by: AI]
cpriti-os
left a comment
There was a problem hiding this comment.
Left a few small comments on attribute filtering and status code fallbacks.
[Generated-by: AI]
- Check status.getCause() and server checksum mismatch descriptions on INVALID_ARGUMENT and DATA_LOSS in mapGrpcStatus - Simplify StorageException cause handling in mapThrowable by calling mapKnownCause directly - Restrict (crc32c || md5) && match server checksum error pattern to HTTP 400 and gRPC INVALID_ARGUMENT / DATA_LOSS - Add unit tests for mapGrpcStatus causes/descriptions and negative 404/412 checksum message cases [Generated-by: AI]
…ic-libraries-bom [Generated-by: AI]
… entry points [Generated-by: AI]
- Move self-causation check to the bottom of the while loop in extractRpcStatusCode and extractHttpStatusCode so top-level self-causing exceptions are inspected first - Add defensive null checks on getStatus() and getCode() for StatusRuntimeException and StatusException in extractRpcStatusCode - Add unit tests for top-level self-causing exceptions and null status on gRPC status exceptions [Generated-by: AI]
cpriti-os
left a comment
There was a problem hiding this comment.
LGTM! Left a few optional cleanup/idiomatic suggestions that can be addressed here or in a follow-up.
| AttributeKey.stringKey("http.request.method"); | ||
| static final AttributeKey<Long> KEY_HTTP_RESPONSE_STATUS_CODE = | ||
| AttributeKey.longKey("http.response.status_code"); | ||
| static final AttributeKey<String> KEY_HTTP_RESPONSE_STATUS_CODE = |
There was a problem hiding this comment.
Ref: https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
In the OTel semantic conventions, http.response.status_code is an int attribute, and it should only be set when a response was actually received. This change makes it a string, and the stack uses "" (gRPC calls) and "0" (no response) as placeholders. I think we should stick to the otel convenetions
There was a problem hiding this comment.
Updated KEY_HTTP_RESPONSE_STATUS_CODE back to AttributeKey (AttributeKey.longKey("http.response.status_code")) with 0L as the fallback when no HTTP response is received or on gRPC attempts (matching the Go SDK's attribute.Int64("http.response.status_code", 0) while still emitting both keys on attempts for Cloud Monitoring MetricDescriptor SEND_ONCE compatibility).
Co-authored by AI Agent
…n StorageErrorTypeMapper - Reword class Javadoc to remove HLD acronym. - Delegate StatusRuntimeException and StatusException directly to mapGrpcStatus. - Cap cause-chain traversal depth (MAX_CAUSE_DEPTH = 20) across mapGrpcStatus and mapThrowable to guard against multi-node cause cycles (A -> B -> A). [Generated-by: AI]
…or-mapping' into feat/storage-metrics-context
[Generated-by: AI]
[Generated-by: AI]
…se.status_code [Generated-by: AI]
Introduces
StorageMetricsContextfor tracking per-operation and per-attempt OpenTelemetry metrics state.StorageMetricsContextto manage operation attributes, attempt counters, and durations.StorageMetricsContextTestunit tests.Stacked on #14694.