diff --git a/google/cloud/internal/populate_common_options.cc b/google/cloud/internal/populate_common_options.cc index 597c22177daef..c4263a7e013a8 100644 --- a/google/cloud/internal/populate_common_options.cc +++ b/google/cloud/internal/populate_common_options.cc @@ -72,6 +72,10 @@ Options PopulateCommonOptions(Options opts, std::string const& endpoint_env_var, if (e && !e->empty()) { opts.set(true); } + e = GetEnv("GOOGLE_CLOUD_CPP_OPENTELEMETRY_METRICS"); + if (e && !e->empty()) { + opts.set(true); + } if (!opts.has()) { opts.set(DefaultTracingComponents()); } @@ -102,6 +106,10 @@ Options MakeAuthOptions(Options const& options) { opts.set( options.get()); } + if (options.has()) { + opts.set( + options.get()); + } if (options.has()) { opts.set(options.get()); } diff --git a/google/cloud/internal/populate_common_options_test.cc b/google/cloud/internal/populate_common_options_test.cc index a8701ed08927f..87e8895fd48ad 100644 --- a/google/cloud/internal/populate_common_options_test.cc +++ b/google/cloud/internal/populate_common_options_test.cc @@ -249,6 +249,24 @@ TEST(PopulateCommonOptions, OpenTelemetryTracing) { } } +TEST(PopulateCommonOptions, OpenTelemetryMetrics) { + struct TestCase { + std::optional env; + bool value; + }; + std::vector tests = { + {std::nullopt, false}, + {"", false}, + {"ON", true}, + }; + auto const input = Options{}.set(false); + for (auto const& test : tests) { + ScopedEnvironment env("GOOGLE_CLOUD_CPP_OPENTELEMETRY_METRICS", test.env); + auto options = PopulateCommonOptions(input, {}, {}, {}, {}); + EXPECT_EQ(options.get(), test.value); + } +} + TEST(DefaultTracingComponents, NoEnvironment) { ScopedEnvironment env("GOOGLE_CLOUD_CPP_ENABLE_TRACING", std::nullopt); auto const actual = DefaultTracingComponents(); @@ -299,6 +317,12 @@ TEST(MakeAuthOptions, WithTracing) { EXPECT_TRUE(auth_options.get()); } +TEST(MakeAuthOptions, WithMetrics) { + auto options = Options{}.set(true); + auto auth_options = MakeAuthOptions(options); + EXPECT_TRUE(auth_options.get()); +} + TEST(MakeAuthOptions, WithoutLoggingComponents) { auto options = Options{}.set("endpoint_option"); auto auth_options = MakeAuthOptions(options); diff --git a/google/cloud/opentelemetry_options.h b/google/cloud/opentelemetry_options.h index a4592cf4a8a68..7c0eefd7b660d 100644 --- a/google/cloud/opentelemetry_options.h +++ b/google/cloud/opentelemetry_options.h @@ -78,6 +78,27 @@ struct OpenTelemetryTracingOption { using Type = bool; }; +/** + * Enables metrics collection with [OpenTelemetry] + * + * Setting this option enables the generation of SDK metrics by the client + * library. The library uses the global meter provider to generate metrics. + * + * @par Prerequisites + * The library must be compiled with OpenTelemetry in order for this option to + * take effect. + * + * @par Environment variable + * This option is controlled by the `GOOGLE_CLOUD_CPP_OPENTELEMETRY_METRICS` + * environment variable. If the environment variable is set to a non-empty + * value, metrics collection with OpenTelemetry is enabled. + * + * @ingroup options + */ +struct OpenTelemetryMetricsOption { + using Type = bool; +}; + namespace experimental { /// @deprecated Use google::cloud::OpenTelemetryTracingOption instead. using OpenTelemetryTracingOption = ::google::cloud::OpenTelemetryTracingOption; diff --git a/google/cloud/storage/client.cc b/google/cloud/storage/client.cc index c12d8d623b5f1..6a412833ea171 100644 --- a/google/cloud/storage/client.cc +++ b/google/cloud/storage/client.cc @@ -594,6 +594,11 @@ Options DefaultOptions(Options opts) { o.set(true); } + auto metrics = GetEnv("GOOGLE_CLOUD_CPP_OPENTELEMETRY_METRICS"); + if (metrics && !metrics->empty()) { + o.set(true); + } + auto project_id = GetEnv("GOOGLE_CLOUD_PROJECT"); if (project_id.has_value()) { o.set(std::move(*project_id)); diff --git a/google/cloud/storage/client_test.cc b/google/cloud/storage/client_test.cc index 8f37f558c4292..f95cc43d6af8a 100644 --- a/google/cloud/storage/client_test.cc +++ b/google/cloud/storage/client_test.cc @@ -426,6 +426,23 @@ TEST_F(ClientTest, TracingWithEnv) { EXPECT_TRUE(options.get()); } +TEST_F(ClientTest, MetricsWithoutEnv) { + ScopedEnvironment env("GOOGLE_CLOUD_CPP_OPENTELEMETRY_METRICS", std::nullopt); + auto options = internal::DefaultOptions(); + EXPECT_FALSE(options.get()); + + options = + internal::DefaultOptions(Options{}.set(true)); + EXPECT_TRUE(options.get()); +} + +TEST_F(ClientTest, MetricsWithEnv) { + ScopedEnvironment env("GOOGLE_CLOUD_CPP_OPENTELEMETRY_METRICS", "ON"); + auto const options = internal::DefaultOptions( + Options{}.set(false)); + EXPECT_TRUE(options.get()); +} + TEST_F(ClientTest, ProjectIdWithoutEnv) { ScopedEnvironment env("GOOGLE_CLOUD_PROJECT", std::nullopt); auto const options = internal::DefaultOptions(); diff --git a/google/cloud/storage/options.h b/google/cloud/storage/options.h index 2f76f7a215738..0d46772711747 100644 --- a/google/cloud/storage/options.h +++ b/google/cloud/storage/options.h @@ -22,6 +22,7 @@ #include "google/cloud/backoff_policy.h" #include "google/cloud/credentials.h" #include "google/cloud/internal/rest_options.h" +#include "google/cloud/opentelemetry_options.h" #include "google/cloud/options.h" #include #include @@ -392,7 +393,8 @@ using ClientOptionList = ::google::cloud::OptionList< IdempotencyPolicyOption, CARootsFilePathOption, UploadChecksumValidationOption, DownloadChecksumValidationOption, PrecomputedChecksumsOption, storage_experimental::HttpVersionOption, - storage_experimental::OTelSpanEnrichmentOption>; + storage_experimental::OTelSpanEnrichmentOption, OpenTelemetryTracingOption, + OpenTelemetryMetricsOption>; GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END } // namespace storage