Skip to content

Commit

Permalink
feat(otel): control tracing with environment variable (#11897)
Browse files Browse the repository at this point in the history
dbolduc authored Aug 10, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 5c72c70 commit d84d5b9
Showing 4 changed files with 73 additions and 12 deletions.
16 changes: 10 additions & 6 deletions google/cloud/internal/populate_common_options.cc
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
#include "google/cloud/common_options.h"
#include "google/cloud/internal/getenv.h"
#include "google/cloud/internal/user_agent_prefix.h"
#include "google/cloud/opentelemetry_options.h"
#include "absl/strings/str_split.h"

namespace google {
@@ -31,13 +32,13 @@ Options PopulateCommonOptions(Options opts, std::string const& endpoint_env_var,
opts.set<EndpointOption>(default_endpoint);
}
if (!endpoint_env_var.empty()) {
auto e = internal::GetEnv(endpoint_env_var.c_str());
auto e = GetEnv(endpoint_env_var.c_str());
if (e && !e->empty()) {
opts.set<EndpointOption>(*std::move(e));
}
}
if (!emulator_env_var.empty()) {
auto e = internal::GetEnv(emulator_env_var.c_str());
auto e = GetEnv(emulator_env_var.c_str());
if (e && !e->empty()) {
opts.set<EndpointOption>(*std::move(e));
}
@@ -47,7 +48,7 @@ Options PopulateCommonOptions(Options opts, std::string const& endpoint_env_var,
opts.set<AuthorityOption>(std::move(default_endpoint));
}
if (!authority_env_var.empty()) {
auto e = internal::GetEnv(authority_env_var.c_str());
auto e = GetEnv(authority_env_var.c_str());
if (e && !e->empty()) {
opts.set<AuthorityOption>(*std::move(e));
}
@@ -58,8 +59,12 @@ Options PopulateCommonOptions(Options opts, std::string const& endpoint_env_var,
opts.set<UserProjectOption>(*std::move(e));
}

e = GetEnv("GOOGLE_CLOUD_CPP_OPENTELEMETRY_TRACING");
if (e && !e->empty()) {
opts.set<experimental::OpenTelemetryTracingOption>(true);
}
if (!opts.has<TracingComponentsOption>()) {
opts.set<TracingComponentsOption>(internal::DefaultTracingComponents());
opts.set<TracingComponentsOption>(DefaultTracingComponents());
}

auto& products = opts.lookup<UserAgentProductsOption>();
@@ -69,8 +74,7 @@ Options PopulateCommonOptions(Options opts, std::string const& endpoint_env_var,
}

std::set<std::string> DefaultTracingComponents() {
auto tracing =
google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_ENABLE_TRACING");
auto tracing = GetEnv("GOOGLE_CLOUD_CPP_ENABLE_TRACING");
if (!tracing.has_value()) return {};
return absl::StrSplit(*tracing, ',');
}
25 changes: 23 additions & 2 deletions google/cloud/internal/populate_common_options_test.cc
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
#include "google/cloud/internal/populate_common_options.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/user_agent_prefix.h"
#include "google/cloud/opentelemetry_options.h"
#include "google/cloud/testing_util/scoped_environment.h"
#include "absl/types/optional.h"
#include <gmock/gmock.h>
@@ -121,13 +122,33 @@ TEST(PopulateCommonOptions, UserProject) {
}
}

TEST(PopulateCommonOptions, DefaultTracingComponentsNoEnvironment) {
TEST(PopulateCommonOptions, OpenTelemetryTracing) {
struct TestCase {
absl::optional<std::string> env;
bool value;
};
std::vector<TestCase> tests = {
{absl::nullopt, false},
{"", false},
{"ON", true},
};
auto const input =
Options{}.set<experimental::OpenTelemetryTracingOption>(false);
for (auto const& test : tests) {
ScopedEnvironment env("GOOGLE_CLOUD_CPP_OPENTELEMETRY_TRACING", test.env);
auto options = PopulateCommonOptions(input, {}, {}, {}, {});
EXPECT_EQ(options.get<experimental::OpenTelemetryTracingOption>(),
test.value);
}
}

TEST(DefaultTracingComponents, NoEnvironment) {
ScopedEnvironment env("GOOGLE_CLOUD_CPP_ENABLE_TRACING", absl::nullopt);
auto const actual = DefaultTracingComponents();
EXPECT_THAT(actual, ElementsAre());
}

TEST(PopulateCommonOptions, DefaultTracingComponentsWithValue) {
TEST(DefaultTracingComponents, WithValue) {
ScopedEnvironment env("GOOGLE_CLOUD_CPP_ENABLE_TRACING", "a,b,c");
auto const actual = DefaultTracingComponents();
EXPECT_THAT(actual, ElementsAre("a", "b", "c"));
2 changes: 0 additions & 2 deletions google/cloud/opentelemetry/trace_exporter.cc
Original file line number Diff line number Diff line change
@@ -82,8 +82,6 @@ class TraceExporter final : public opentelemetry::sdk::trace::SpanExporter {

std::unique_ptr<opentelemetry::sdk::trace::SpanExporter> MakeTraceExporter(
Project project, Options options) {
// TODO(#11156) - We should filter out options that enable tracing. We should
// not trace requests initiated by the underlying trace_v2 client.
return std::make_unique<TraceExporter>(
std::move(project),
trace_v2::MakeTraceServiceConnection(std::move(options)));
42 changes: 40 additions & 2 deletions google/cloud/opentelemetry_options.h
Original file line number Diff line number Diff line change
@@ -15,7 +15,6 @@
#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_OPENTELEMETRY_OPTIONS_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_OPENTELEMETRY_OPTIONS_H

#ifdef GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY
#include "google/cloud/version.h"

namespace google {
@@ -26,9 +25,49 @@ namespace experimental {
/**
* Enables tracing with [OpenTelemetry]
*
* Setting this option enables the generation of [traces] by the client
* library. The library uses the global [tracer provider] to generate traces.
*
* @par Prerequisites
* The library must be compiled with OpenTelemetry in order for this option to
* take effect.
*
* @see [The OpenTelemetry tracing quickstart][gc-quickstart] for instructions
* on how to compile google-cloud-cpp with opentelemetry-cpp.
*
* @par Effect
* Setting this option enables the generation of [traces] by the client
* library. The library uses the global [tracer provider] to generate traces.
*
* @par Exporting traces
* Providing this option to a client only enables the *generation* of traces. It
* does not enable the *export* of traces.
*
* In order to export the traces, the application must set the global tracer
* provider. The client library recommends using
* `#google::cloud::otel::ConfigureBasicTracing()` to configure the global
* tracer provider. This will send the traces generated by the client library to
* [Cloud Trace], Google Cloud's visualizer for distributed traces.
*
* @see [Google Cloud C++ OpenTelemetry reference docs][gc-otel-docs].
*
* @par Environment variable
* This option is controlled by the `GOOGLE_CLOUD_CPP_OPENTELEMETRY_TRACING`
* environment variable. If the environment variable is set to a non-empty
* value, tracing with OpenTelemetry is enabled.
*
* @ingroup options
*
* [Cloud Trace]: https://cloud.google.com/trace
* [gc-quickstart]:
* https://github.com/googleapis/google-cloud-cpp/tree/main/google/cloud/opentelemetry/quickstart
* [gc-otel-docs]:
* https://cloud.google.com/cpp/docs/reference/opentelemetry/latest
* [opentelemetry]: https://opentelemetry.io/docs/instrumentation/cpp/
* [tracer provider]:
* https://opentelemetry.io/docs/concepts/signals/traces/#tracer-provider
* [traces]:
* https://opentelemetry.io/docs/concepts/observability-primer/#distributed-traces
*/
struct OpenTelemetryTracingOption {
using Type = bool;
@@ -38,6 +77,5 @@ struct OpenTelemetryTracingOption {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace cloud
} // namespace google
#endif // GOOGLE_CLOUD_CPP_HAVE_OPENTELEMETRY

#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_OPENTELEMETRY_OPTIONS_H

0 comments on commit d84d5b9

Please sign in to comment.