Skip to content

Commit 250231e

Browse files
feat(storage): add configurable metrics export timeout for GCS gRPC Client (#15629)
1 parent cfcc841 commit 250231e

File tree

4 files changed

+81
-3
lines changed

4 files changed

+81
-3
lines changed

google/cloud/storage/grpc_plugin.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,35 @@ struct GrpcMetricsPeriodOption {
102102
using Type = std::chrono::seconds;
103103
};
104104

105+
/**
106+
* gRPC telemetry export timeout.
107+
*
108+
* When `EnableGrpcMetrics` is enabled, this option controls the maximum time
109+
* to wait for metrics to be exported to [Google Cloud Monitoring]. The default
110+
* is 30 seconds.
111+
*
112+
* This timeout is particularly important for short-lived programs. Setting a
113+
* lower timeout ensures metrics are flushed before the program exits. For
114+
* long-running services, the default value is appropriate.
115+
*
116+
* @par Example: Configure for short-lived programs
117+
* @code
118+
* namespace gcs_ex = google::cloud::storage_experimental;
119+
* auto client = google::cloud::storage::MakeGrpcClient(
120+
* google::cloud::Options{}
121+
* .set<gcs_ex::EnableGrpcMetricsOption>(true)
122+
* .set<gcs_ex::GrpcMetricsPeriodOption>(
123+
* std::chrono::seconds(5))
124+
* .set<gcs_ex::GrpcMetricsExportTimeoutOption>(
125+
* std::chrono::seconds(2)));
126+
* @endcode
127+
*
128+
* [Google Cloud Monitoring]: https://cloud.google.com/monitoring/docs
129+
*/
130+
struct GrpcMetricsExportTimeoutOption {
131+
using Type = std::chrono::seconds;
132+
};
133+
105134
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
106135
} // namespace storage_experimental
107136
} // namespace cloud

google/cloud/storage/internal/grpc/default_options.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ namespace {
3636

3737
auto constexpr kMinMetricsPeriod = std::chrono::seconds(5);
3838
auto constexpr kDefaultMetricsPeriod = std::chrono::seconds(60);
39+
auto constexpr kDefaultMetricsExportTimeout = std::chrono::seconds(30);
3940

4041
int DefaultGrpcNumChannels(std::string const& endpoint) {
4142
// When using Direct Connectivity the gRPC library already does load balancing
@@ -112,7 +113,9 @@ Options DefaultOptionsGrpc(
112113
.set<storage_experimental::EnableGrpcMetricsOption>(
113114
enable_grpc_metrics)
114115
.set<storage_experimental::GrpcMetricsPeriodOption>(
115-
kDefaultMetricsPeriod));
116+
kDefaultMetricsPeriod)
117+
.set<storage_experimental::GrpcMetricsExportTimeoutOption>(
118+
kDefaultMetricsExportTimeout));
116119
if (options.get<storage_experimental::GrpcMetricsPeriodOption>() <
117120
kMinMetricsPeriod) {
118121
options.set<storage_experimental::GrpcMetricsPeriodOption>(

google/cloud/storage/internal/grpc/metrics_exporter_impl.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ auto MakeReaderOptions(Options const& options) {
4949
opentelemetry::sdk::metrics::PeriodicExportingMetricReaderOptions{};
5050
reader_options.export_interval_millis = std::chrono::milliseconds(
5151
options.get<storage_experimental::GrpcMetricsPeriodOption>());
52-
reader_options.export_timeout_millis =
53-
std::chrono::milliseconds(std::chrono::seconds(30));
52+
reader_options.export_timeout_millis = std::chrono::milliseconds(
53+
options.get<storage_experimental::GrpcMetricsExportTimeoutOption>());
5454
return reader_options;
5555
}
5656

google/cloud/storage/internal/grpc/metrics_exporter_impl_test.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,52 @@ TEST(GrpcMetricsExporter, EnabledWithTimeout) {
110110
std::chrono::milliseconds(0));
111111
}
112112

113+
TEST(GrpcMetricsExporter, DefaultExportTime) {
114+
auto config = MakeMeterProviderConfig(FullResource(), TestOptions());
115+
ASSERT_TRUE(config.has_value());
116+
EXPECT_EQ(config->project, Project("project-id-resource"));
117+
EXPECT_EQ(config->reader_options.export_interval_millis,
118+
std::chrono::seconds(60));
119+
EXPECT_EQ(config->reader_options.export_timeout_millis,
120+
std::chrono::seconds(30));
121+
}
122+
123+
TEST(GrpcMetricsExporter, CustomExportTime) {
124+
auto config = MakeMeterProviderConfig(
125+
FullResource(),
126+
TestOptions()
127+
.set<storage_experimental::GrpcMetricsPeriodOption>(
128+
std::chrono::seconds(10))
129+
.set<storage_experimental::GrpcMetricsExportTimeoutOption>(
130+
std::chrono::seconds(2)));
131+
ASSERT_TRUE(config.has_value());
132+
EXPECT_EQ(config->project, Project("project-id-resource"));
133+
EXPECT_EQ(config->reader_options.export_interval_millis,
134+
std::chrono::seconds(10));
135+
EXPECT_EQ(config->reader_options.export_timeout_millis,
136+
std::chrono::seconds(2));
137+
}
138+
139+
TEST(GrpcMetricsExporter, ReaderOptionsAreSetFromConfig) {
140+
auto const expected_interval = std::chrono::seconds(45);
141+
auto const expected_timeout = std::chrono::seconds(25);
142+
143+
auto config = MakeMeterProviderConfig(
144+
FullResource(),
145+
TestOptions()
146+
.set<storage_experimental::GrpcMetricsPeriodOption>(expected_interval)
147+
.set<storage_experimental::GrpcMetricsExportTimeoutOption>(
148+
expected_timeout));
149+
150+
ASSERT_TRUE(config.has_value());
151+
152+
// Verify the conversion from seconds to milliseconds happens correctly.
153+
EXPECT_EQ(config->reader_options.export_interval_millis,
154+
std::chrono::milliseconds(expected_interval));
155+
EXPECT_EQ(config->reader_options.export_timeout_millis,
156+
std::chrono::milliseconds(expected_timeout));
157+
}
158+
113159
} // namespace
114160
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
115161
} // namespace storage_internal

0 commit comments

Comments
 (0)