Skip to content

feat(storage): add OTel metrics feature gate options and env vars - #16637

Open
cpriti-os wants to merge 5 commits into
googleapis:mainfrom
cpriti-os:feat-storage-otel-metrics-options
Open

cpriti-os wants to merge 5 commits into
googleapis:mainfrom
cpriti-os:feat-storage-otel-metrics-options

Conversation

@cpriti-os

@cpriti-os cpriti-os commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Adds experimental options and environment variable overrides to gate OpenTelemetry client metrics collection for Google Cloud Storage:

  • storage_experimental::EnableOTelMetricsOption (overridden by GCP_STORAGE_CPP_ENABLE_OTEL_METRICS)
  • storage_experimental::EnableOTelDebugMetricsOption (overridden by GCP_STORAGE_CPP_ENABLE_OTEL_DEBUG_METRICS)

Precedence is environment variable ("true" / "false") > option in code > default (false). This PR introduces the configuration options and environment variable parsing; the metric instruments that read these options are wired in follow-up PRs.


Created by cpriti-o11y-agent

Add `storage_experimental::EnableOTelMetricsOption` and
`storage_experimental::EnableOTelDebugMetricsOption` to configure
OpenTelemetry client metrics and debug metrics collection for Storage,
defaulting to `false`.

Support `GCP_STORAGE_CPP_ENABLE_OTEL_METRICS` and
`GCP_STORAGE_CPP_ENABLE_OTEL_DEBUG_METRICS` environment variable
overrides (`"true"` / `"false"") in `DefaultOptions()`, consistent
with the Go and Java Storage SDKs.

[Generated-by: AI]
@product-auto-label product-auto-label Bot added the api: storage Issues related to the Cloud Storage API. label Nov 9, 2026

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

Copy link
Copy Markdown

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 EnableOTelMetricsOption and EnableOTelDebugMetricsOption to configure OpenTelemetry client metrics and debug metrics collection for Storage, allowing overrides via environment variables. Unit tests are also added to verify this behavior. The review feedback recommends explicitly specifying the return type std::optionalstd::string instead of using auto when retrieving environment variables, in order to comply with the repository's style guide against obscuring return types.

Comment thread google/cloud/storage/client.cc Outdated
if (!o.has<storage_experimental::EnableOTelMetricsOption>()) {
o.set<storage_experimental::EnableOTelMetricsOption>(false);
}
auto const otel_metrics_env = GetEnv("GCP_STORAGE_CPP_ENABLE_OTEL_METRICS");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

According to the repository style guide, auto should not be used when it hides function return types. Please explicitly specify the return type std::optional<std::string> instead of using auto.

  std::optional<std::string> const otel_metrics_env =
      GetEnv("GCP_STORAGE_CPP_ENABLE_OTEL_METRICS");
References
  1. Reject Obscured Domain & Return Types: Flag and reject auto when it hides StatusOr<T>, domain objects, protobuf messages/fields, or function return types. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to use std::optional<std::string> const explicitly.


Replied by cpriti-o11y-agent

Comment thread google/cloud/storage/client.cc Outdated
Comment on lines +720 to +721
auto const otel_debug_metrics_env =
GetEnv("GCP_STORAGE_CPP_ENABLE_OTEL_DEBUG_METRICS");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

According to the repository style guide, auto should not be used when it hides function return types. Please explicitly specify the return type std::optional<std::string> instead of using auto.

  std::optional<std::string> const otel_debug_metrics_env =
      GetEnv("GCP_STORAGE_CPP_ENABLE_OTEL_DEBUG_METRICS");
References
  1. Reject Obscured Domain & Return Types: Flag and reject auto when it hides StatusOr<T>, domain objects, protobuf messages/fields, or function return types. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to use std::optional<std::string> const explicitly.


Replied by cpriti-o11y-agent

@cpriti-os
cpriti-os marked this pull request as ready for review November 9, 2026 06:19
@cpriti-os
cpriti-os requested review from a team as code owners November 9, 2026 06:19
@cpriti-os
cpriti-os requested a review from kalragauri November 9, 2026 06:19
@codecov

codecov Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.45%. Comparing base (b1e9b10) to head (f62d677).
⚠️ Report is 27 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #16637      +/-   ##
==========================================
- Coverage   92.48%   92.45%   -0.03%     
==========================================
  Files        2269     2269              
  Lines      222192   222270      +78     
==========================================
+ Hits       205487   205507      +20     
- Misses      16705    16763      +58     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kalragauri kalragauri 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.

nit: the description names the env vars GOOGLE_CLOUD_CPP_STORAGE_ENABLE_OTEL_METRICS / ..._DEBUG_METRICS, but the code uses GCP_STORAGE_CPP_ENABLE_OTEL_METRICS / ..._DEBUG_METRICS. Also, "consistent with Go and Java" only holds for Go: in Java the builder setting takes precedence over the env var. Could you fix the names, state the precedence explicitly, and note that nothing consumes these options yet?

};

/**
* Enable or disable OpenTelemetry client metrics collection for Storage.

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.

EnableOTelMetricsOption is documented as enabling metrics collection, but nothing reads it yet, so setting it has no effect. Is that intentional?

Please also document how it will interact with EnableGrpcMetricsOption.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is intentionally split out first to keep each PR in the series small and easy to review; the metric instruments that read these options are wired in the follow-up PRs. We also updated the docstrings here to clarify that both options are independent of EnableGrpcMetricsOption.


Replied by cpriti-o11y-agent

}
std::optional<std::string> const val = GetEnv(env_var);
if (!val.has_value()) return;
if (*val == "true") {

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.

This accepts only the exact lowercase strings, while storage clients in other languages also accept 1, t, and any casing for the equivalent variables. A deployment that sets =1 across languages would silently get no metrics from C++.

Is the stricter parsing intentional, and if so, should unrecognized values log a warning?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, matching only exact "true" and "false" and silently ignoring other or empty values is intentional to stay consistent with GOOGLE_CLOUD_ENABLE_DIRECT_PATH_XDS_OVER_INTERCONNECT in default_options.cc.


Replied by cpriti-o11y-agent


TEST_F(ClientTest, OTelMetricsEnvVarOverridesOption) {
{
ScopedEnvironment env("GCP_STORAGE_CPP_ENABLE_OTEL_METRICS", "true");

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.

Both env vars and both options are always set to the same value in these tests, so they would still pass if DefaultOptions() read the debug variable for EnableOTelMetricsOption and vice versa.

Consider adding a case where only one variable is "true" and asserting the other option stays false.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch—updated OTelMetricsDefaultAndOption and OTelMetricsEnvVarOverridesOption to test each option and environment variable independently with opposite boolean values.


Replied by cpriti-o11y-agent

/**
* Enable or disable OpenTelemetry client metrics collection for Storage.
*
* The default is `false`. The `GCP_STORAGE_CPP_ENABLE_OTEL_METRICS`

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.

GCP_STORAGE_CPP_ENABLE_OTEL_METRICS and the debug variant are only documented here. Could you also add them to google/cloud/storage/doc/environment-variables.dox, next to the other experimental variables?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added both GCP_STORAGE_CPP_ENABLE_OTEL_METRICS and GCP_STORAGE_CPP_ENABLE_OTEL_DEBUG_METRICS to google/cloud/storage/doc/environment-variables.dox.


Replied by cpriti-o11y-agent

Comment thread google/cloud/storage/client_test.cc Outdated
}

TEST_F(ClientTest, OTelMetricsInvalidEnvVarIgnored) {
for (char const* val : {"1", "0", "TRUE", "False", "ON", "yes", ""}) {

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.

A failure inside these nested loops would not say which val or configured combination failed.

Can we replace this with TEST_P and ::testing::Combine, so each case is reported by name?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added SCOPED_TRACE with val and configured inside the loop so any assertion failure reports the exact combination without the extra boilerplate of a TEST_P fixture.


Replied by cpriti-o11y-agent

@cpriti-os

Copy link
Copy Markdown
Contributor Author

Updated the PR description with the exact GCP_STORAGE_CPP_ENABLE_OTEL_METRICS and GCP_STORAGE_CPP_ENABLE_OTEL_DEBUG_METRICS names, precedence order (environment variable > option in code > default), and note on the follow-up PRs.


Replied by cpriti-o11y-agent

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

api: storage Issues related to the Cloud Storage API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants