Skip to content

feat(storage): add StorageMetricsContext for operation metrics state - #14728

Open
nidhiii-27 wants to merge 13 commits into
feat/storage-metrics-context-error-mappingfrom
feat/storage-metrics-context
Open

nidhiii-27 wants to merge 13 commits into
feat/storage-metrics-context-error-mappingfrom
feat/storage-metrics-context

Conversation

@nidhiii-27

Copy link
Copy Markdown
Contributor

Introduces StorageMetricsContext for tracking per-operation and per-attempt OpenTelemetry metrics state.

  • Adds StorageMetricsContext to manage operation attributes, attempt counters, and durations.
  • Adds StorageMetricsContextTest unit tests.

Stacked on #14694.

@nidhiii-27
nidhiii-27 requested review from a team as code owners October 22, 2026 05:39

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces StorageMetricsContext and its corresponding unit tests to manage operation metric state across asynchronous and thread-hopping boundaries. The review feedback suggests simplifying the API surface of StorageMetricsContext by making the primary constructor private, relying on static factory methods, and refactoring from(ApiCallContext) to delegate directly to from(GrpcCallContext) to eliminate duplicate logic. Additionally, the feedback recommends updating the unit tests to utilize these static factory methods instead of constructors.

@nidhiii-27
nidhiii-27 force-pushed the feat/storage-metrics-context branch from f943017 to edb3def Compare October 22, 2026 05:54
@nidhiii-27
nidhiii-27 requested a review from Dhriti07 October 26, 2026 12:47
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 cpriti-os left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few small comments on attribute filtering and status code fallbacks.

@nidhiii-27
nidhiii-27 requested a review from cpriti-os November 2, 2026 12:30
- 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 cpriti-os left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Left a few optional cleanup/idiomatic suggestions that can be addressed here or in a follow-up.

this.attemptCount = requireNonNull(attemptCount, "attemptCount cannot be null");
this.requestBytes = requireNonNull(requestBytes, "requestBytes cannot be null");
this.responseBytes = requireNonNull(responseBytes, "responseBytes cannot be null");
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use ApiClock here instead of System.nanoTime() so it stays consistent with the rest of the repo and the interceptors? Also, we can initialize the Atomic* fields inline rather than passing them into the constructor.

StorageClientMetrics.KEY_HTTP_RESPONSE_STATUS_CODE, httpCode != null ? httpCode : "");
}
metrics.getAttempts().add(1, builder.build());
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the context holds a reference to StorageClientMetrics, callers won't have to pass both objects around everywhere. We can also pull the duplicated gRPC/HTTP status-code branching in recordAttemptSuccess and recordAttemptFailure into a small helper.

}

private @Nullable String extractRpcStatusCode(@Nullable Throwable e) {
String fromContext = baseAttributes.get(StorageClientMetrics.KEY_RPC_RESPONSE_STATUS_CODE);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we move the exception status-code extraction into StorageErrorTypeMapper so we only have one place walking the cause chain? Also, baseAttributes already includes the client attributes, so we don't need to copy them twice in buildAttemptBaseAttributes.

}

AttributesBuilder attributesBuilder() {
return baseAttributes.toBuilder();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several attachment helpers (Map, ApiCallContext), attemptCount, and attributesBuilder() aren't used anywhere in the stack—let's drop the unused ones to keep this class lean.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants