diff --git a/api/envoy/config/trace/v3/opencensus.proto b/api/envoy/config/trace/v3/opencensus.proto index 9b2d2361a49d9..f1f720b34b580 100644 --- a/api/envoy/config/trace/v3/opencensus.proto +++ b/api/envoy/config/trace/v3/opencensus.proto @@ -21,6 +21,8 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE; // [#protodoc-title: OpenCensus tracer] +// [#not-implemented-hide:] +// // Configuration for the OpenCensus tracer. // [#next-free-field: 15] // [#extension: envoy.tracers.opencensus] diff --git a/bazel/external/rapidjson.BUILD b/bazel/external/rapidjson.BUILD index 6138f5fa351fa..a5e457816c434 100644 --- a/bazel/external/rapidjson.BUILD +++ b/bazel/external/rapidjson.BUILD @@ -5,7 +5,4 @@ cc_library( hdrs = glob(["include/rapidjson/**/*.h"]), defines = ["RAPIDJSON_HAS_STDSTRING=1"], includes = ["include"], - # rapidjson is only needed to build external dependency of the Zipkin tracer. - # For Envoy source code plese use source/common/json/json_loader.h - visibility = ["@io_opencensus_cpp//opencensus/exporters/trace/zipkin:__pkg__"], ) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index a33c90baa229d..11892e3ac79f9 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -13,7 +13,6 @@ WINDOWS_SKIP_TARGETS = [ "envoy.filters.http.sxg", "envoy.tracers.dynamic_ot", "envoy.tracers.datadog", - "envoy.tracers.opencensus", ] # Make all contents of an external repository accessible under a filegroup. Used for external HTTP @@ -285,7 +284,6 @@ def envoy_dependencies(skip_targets = []): _com_google_absl() _com_google_googletest() _com_google_protobuf() - _io_opencensus_cpp() _com_github_curl() _com_github_envoyproxy_sqlparser() _v8() @@ -902,47 +900,6 @@ def _com_google_protobuf(): actual = "//bazel:python_headers", ) -def _io_opencensus_cpp(): - external_http_archive( - name = "io_opencensus_cpp", - ) - native.bind( - name = "opencensus_trace", - actual = "@io_opencensus_cpp//opencensus/trace", - ) - native.bind( - name = "opencensus_trace_b3", - actual = "@io_opencensus_cpp//opencensus/trace:b3", - ) - native.bind( - name = "opencensus_trace_cloud_trace_context", - actual = "@io_opencensus_cpp//opencensus/trace:cloud_trace_context", - ) - native.bind( - name = "opencensus_trace_grpc_trace_bin", - actual = "@io_opencensus_cpp//opencensus/trace:grpc_trace_bin", - ) - native.bind( - name = "opencensus_trace_trace_context", - actual = "@io_opencensus_cpp//opencensus/trace:trace_context", - ) - native.bind( - name = "opencensus_exporter_ocagent", - actual = "@io_opencensus_cpp//opencensus/exporters/trace/ocagent:ocagent_exporter", - ) - native.bind( - name = "opencensus_exporter_stdout", - actual = "@io_opencensus_cpp//opencensus/exporters/trace/stdout:stdout_exporter", - ) - native.bind( - name = "opencensus_exporter_stackdriver", - actual = "@io_opencensus_cpp//opencensus/exporters/trace/stackdriver:stackdriver_exporter", - ) - native.bind( - name = "opencensus_exporter_zipkin", - actual = "@io_opencensus_cpp//opencensus/exporters/trace/zipkin:zipkin_exporter", - ) - def _com_github_curl(): # Used by OpenCensus Zipkin exporter. external_http_archive( diff --git a/bazel/repository_locations.bzl b/bazel/repository_locations.bzl index ae7f06a1d3ce9..ac88d0bbca742 100644 --- a/bazel/repository_locations.bzl +++ b/bazel/repository_locations.bzl @@ -759,7 +759,7 @@ REPOSITORY_LOCATIONS_SPEC = dict( urls = ["https://github.com/Tencent/rapidjson/archive/{version}.tar.gz"], use_category = ["observability_ext"], # Rapidjson is used in the external dependency of zipkin tracer. - extensions = ["envoy.tracers.zipkin", "envoy.tracers.opencensus"], + extensions = ["envoy.tracers.zipkin"], release_date = "2019-12-03", cpe = "cpe:2.3:a:tencent:rapidjson:*", license = "RapidJSON", @@ -1045,21 +1045,6 @@ REPOSITORY_LOCATIONS_SPEC = dict( license = "Apache-2.0", license_url = "https://github.com/WebAssembly/wasm-c-api/blob/{version}/LICENSE", ), - io_opencensus_cpp = dict( - project_name = "OpenCensus C++", - project_desc = "OpenCensus tracing library", - project_url = "https://github.com/census-instrumentation/opencensus-cpp", - version = "f68a2d0ea43eb61a4b7889f09987294c4f94d436", - sha256 = "b5fd69da558d08480e254c7e2a91e23a88ec8b72d9aec1a6c2329d7560a61744", - strip_prefix = "opencensus-cpp-{version}", - urls = ["https://github.com/census-instrumentation/opencensus-cpp/archive/{version}.tar.gz"], - use_category = ["observability_ext"], - extensions = ["envoy.tracers.opencensus"], - release_date = "2022-09-20", - cpe = "N/A", - license = "Apache-2.0", - license_url = "https://github.com/census-instrumentation/opencensus-cpp/blob/{version}/LICENSE", - ), # This should be removed, see https://github.com/envoyproxy/envoy/issues/11816. com_github_curl = dict( project_name = "curl", @@ -1074,7 +1059,6 @@ REPOSITORY_LOCATIONS_SPEC = dict( "envoy.filters.http.aws_lambda", "envoy.filters.http.aws_request_signing", "envoy.grpc_credentials.aws_iam", - "envoy.tracers.opencensus", ], release_date = "2023-07-26", cpe = "cpe:2.3:a:haxx:libcurl:*", diff --git a/docs/v2_mapping.json b/docs/v2_mapping.json index 4e9b014276d03..ef2b3efaf29be 100644 --- a/docs/v2_mapping.json +++ b/docs/v2_mapping.json @@ -121,7 +121,6 @@ "envoy/config/trace/v3/dynamic_ot.proto": "envoy/config/trace/v2/dynamic_ot.proto", "envoy/config/trace/v3/http_tracer.proto": "envoy/config/trace/v2/http_tracer.proto", "envoy/config/trace/v3/lightstep.proto": "envoy/config/trace/v2/lightstep.proto", - "envoy/config/trace/v3/opencensus.proto": "envoy/config/trace/v2/opencensus.proto", "envoy/config/trace/v3/service.proto": "envoy/config/trace/v2/service.proto", "envoy/config/trace/v3/zipkin.proto": "envoy/config/trace/v2/zipkin.proto", "envoy/config/trace/v3/xray.proto": "envoy/config/trace/v2alpha/xray.proto", diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl index 7385b590a13ad..d1b77ea77ef86 100644 --- a/source/extensions/extensions_build_config.bzl +++ b/source/extensions/extensions_build_config.bzl @@ -248,7 +248,6 @@ EXTENSIONS = { "envoy.tracers.dynamic_ot": "//source/extensions/tracers/dynamic_ot:config", "envoy.tracers.datadog": "//source/extensions/tracers/datadog:config", "envoy.tracers.zipkin": "//source/extensions/tracers/zipkin:config", - "envoy.tracers.opencensus": "//source/extensions/tracers/opencensus:config", "envoy.tracers.xray": "//source/extensions/tracers/xray:config", "envoy.tracers.skywalking": "//source/extensions/tracers/skywalking:config", "envoy.tracers.opentelemetry": "//source/extensions/tracers/opentelemetry:config", diff --git a/source/extensions/extensions_metadata.yaml b/source/extensions/extensions_metadata.yaml index f1d743fd6e66c..a6ea92a4de652 100644 --- a/source/extensions/extensions_metadata.yaml +++ b/source/extensions/extensions_metadata.yaml @@ -1102,13 +1102,6 @@ envoy.tracers.dynamic_ot: status: stable type_urls: - envoy.config.trace.v3.DynamicOtConfig -envoy.tracers.opencensus: - categories: - - envoy.tracers - security_posture: robust_to_untrusted_downstream - status: stable - type_urls: - - envoy.config.trace.v3.OpenCensusConfig envoy.tracers.opentelemetry: categories: - envoy.tracers diff --git a/source/extensions/tracers/opencensus/BUILD b/source/extensions/tracers/opencensus/BUILD deleted file mode 100644 index f661bed6ddf62..0000000000000 --- a/source/extensions/tracers/opencensus/BUILD +++ /dev/null @@ -1,47 +0,0 @@ -load( - "//bazel:envoy_build_system.bzl", - "envoy_cc_extension", - "envoy_cc_library", - "envoy_extension_package", - "envoy_select_google_grpc", -) - -licenses(["notice"]) # Apache 2 - -# Trace driver for OpenCensus: https://opencensus.io/ - -envoy_extension_package() - -envoy_cc_extension( - name = "config", - srcs = ["config.cc"], - hdrs = ["config.h"], - deps = [ - ":opencensus_tracer_impl", - "//source/extensions/tracers/common:factory_base_lib", - "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", - ], -) - -envoy_cc_library( - name = "opencensus_tracer_impl", - srcs = ["opencensus_tracer_impl.cc"], - hdrs = ["opencensus_tracer_impl.h"], - copts = ["-Wno-unused-parameter"], - external_deps = [ - "opencensus_trace", - "opencensus_trace_b3", - "opencensus_trace_cloud_trace_context", - "opencensus_trace_grpc_trace_bin", - "opencensus_trace_trace_context", - "opencensus_exporter_ocagent", - "opencensus_exporter_stdout", - "opencensus_exporter_stackdriver", - "opencensus_exporter_zipkin", - ], - deps = [ - "//source/common/config:utility_lib", - "//source/common/tracing:http_tracer_lib", - "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", - ] + envoy_select_google_grpc(["//source/common/grpc:google_async_client_lib"]), -) diff --git a/source/extensions/tracers/opencensus/config.cc b/source/extensions/tracers/opencensus/config.cc deleted file mode 100644 index bf33e76de2480..0000000000000 --- a/source/extensions/tracers/opencensus/config.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "source/extensions/tracers/opencensus/config.h" - -#include "envoy/config/trace/v3/opencensus.pb.h" -#include "envoy/config/trace/v3/opencensus.pb.validate.h" -#include "envoy/registry/registry.h" - -#include "source/extensions/tracers/opencensus/opencensus_tracer_impl.h" - -namespace Envoy { -namespace Extensions { -namespace Tracers { -namespace OpenCensus { - -OpenCensusTracerFactory::OpenCensusTracerFactory() : FactoryBase("envoy.tracers.opencensus") {} - -Tracing::DriverSharedPtr OpenCensusTracerFactory::createTracerDriverTyped( - const envoy::config::trace::v3::OpenCensusConfig& proto_config, - Server::Configuration::TracerFactoryContext& context) { - // Since OpenCensus can only support a single tracing configuration per entire process, - // we need to make sure that it is configured at most once. - if (driver_) { - if (Envoy::Protobuf::util::MessageDifferencer::Equals(config_, proto_config)) { - return driver_; - } else { - throw EnvoyException("Opencensus has already been configured with a different config."); - } - } - - driver_ = std::make_shared(proto_config, context.serverFactoryContext().localInfo(), - context.serverFactoryContext().api()); - config_ = proto_config; - return driver_; -} - -/** - * Static registration for the OpenCensus tracer. @see RegisterFactory. - */ -REGISTER_FACTORY(OpenCensusTracerFactory, Server::Configuration::TracerFactory); - -} // namespace OpenCensus -} // namespace Tracers -} // namespace Extensions -} // namespace Envoy diff --git a/source/extensions/tracers/opencensus/config.h b/source/extensions/tracers/opencensus/config.h deleted file mode 100644 index da3d534e36256..0000000000000 --- a/source/extensions/tracers/opencensus/config.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#include "envoy/config/trace/v3/opencensus.pb.h" -#include "envoy/config/trace/v3/opencensus.pb.validate.h" - -#include "source/extensions/tracers/common/factory_base.h" - -namespace Envoy { -namespace Extensions { -namespace Tracers { -namespace OpenCensus { - -/** - * Config registration for the OpenCensus tracer. @see TracerFactory. - */ -class OpenCensusTracerFactory - : public Common::FactoryBase { -public: - OpenCensusTracerFactory(); - -private: - // FactoryBase - Tracing::DriverSharedPtr - createTracerDriverTyped(const envoy::config::trace::v3::OpenCensusConfig& proto_config, - Server::Configuration::TracerFactoryContext& context) override; - - // Since OpenCensus can only support a single tracing configuration per entire process, - // we need to make sure that it is configured at most once. - Tracing::DriverSharedPtr driver_; - envoy::config::trace::v3::OpenCensusConfig config_; -}; - -} // namespace OpenCensus -} // namespace Tracers -} // namespace Extensions -} // namespace Envoy diff --git a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc b/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc deleted file mode 100644 index 436b826667325..0000000000000 --- a/source/extensions/tracers/opencensus/opencensus_tracer_impl.cc +++ /dev/null @@ -1,388 +0,0 @@ -#include "source/extensions/tracers/opencensus/opencensus_tracer_impl.h" - -#include - -#include "envoy/config/trace/v3/opencensus.pb.h" -#include "envoy/http/header_map.h" - -#include "source/common/common/base64.h" -#include "source/common/common/empty_string.h" - -#include "absl/strings/str_cat.h" -#include "google/devtools/cloudtrace/v2/tracing.grpc.pb.h" -#include "opencensus/exporters/trace/ocagent/ocagent_exporter.h" -#include "opencensus/exporters/trace/stackdriver/stackdriver_exporter.h" -#include "opencensus/exporters/trace/stdout/stdout_exporter.h" -#include "opencensus/exporters/trace/zipkin/zipkin_exporter.h" -#include "opencensus/trace/propagation/b3.h" -#include "opencensus/trace/propagation/cloud_trace_context.h" -#include "opencensus/trace/propagation/grpc_trace_bin.h" -#include "opencensus/trace/propagation/trace_context.h" -#include "opencensus/trace/sampler.h" -#include "opencensus/trace/span.h" -#include "opencensus/trace/span_context.h" -#include "opencensus/trace/trace_config.h" -#include "opencensus/trace/trace_params.h" - -#ifdef ENVOY_GOOGLE_GRPC -#include "source/common/grpc/google_grpc_utils.h" -#endif - -namespace Envoy { -namespace Extensions { -namespace Tracers { -namespace OpenCensus { - -#ifdef ENVOY_GOOGLE_GRPC -constexpr char GoogleStackdriverTraceAddress[] = "cloudtrace.googleapis.com"; -#endif - -namespace { - -class ConstantValues { -public: - const Http::LowerCaseString TRACEPARENT{"traceparent"}; - const Http::LowerCaseString GRPC_TRACE_BIN{"grpc-trace-bin"}; - const Http::LowerCaseString X_CLOUD_TRACE_CONTEXT{"x-cloud-trace-context"}; - const Http::LowerCaseString X_B3_TRACEID{"x-b3-traceid"}; - const Http::LowerCaseString X_B3_SPANID{"x-b3-spanid"}; - const Http::LowerCaseString X_B3_SAMPLED{"x-b3-sampled"}; - const Http::LowerCaseString X_B3_FLAGS{"x-b3-flags"}; -}; - -using Constants = ConstSingleton; - -/** - * OpenCensus tracing implementation of the Envoy Span object. - */ -class Span : public Tracing::Span { -public: - Span(const Tracing::Config& config, const envoy::config::trace::v3::OpenCensusConfig& oc_config, - Tracing::TraceContext& trace_context, const std::string& operation_name, - SystemTime start_time, const Tracing::Decision tracing_decision); - - // Used by spawnChild(). - Span(const envoy::config::trace::v3::OpenCensusConfig& oc_config, - ::opencensus::trace::Span&& span); - - void setOperation(absl::string_view operation) override; - void setTag(absl::string_view name, absl::string_view value) override; - void log(SystemTime timestamp, const std::string& event) override; - void finishSpan() override; - void injectContext(Tracing::TraceContext& trace_context, - const Upstream::HostDescriptionConstSharedPtr&) override; - Tracing::SpanPtr spawnChild(const Tracing::Config& config, const std::string& name, - SystemTime start_time) override; - void setSampled(bool sampled) override; - - // OpenCensus doesn't support baggage, so noop these OpenTracing functions. - void setBaggage(absl::string_view, absl::string_view) override{}; - std::string getBaggage(absl::string_view) override { return EMPTY_STRING; }; - - std::string getTraceIdAsHex() const override; - -private: - ::opencensus::trace::Span span_; - const envoy::config::trace::v3::OpenCensusConfig& oc_config_; -}; - -::opencensus::trace::Span -startSpanHelper(const std::string& name, bool traced, const Tracing::TraceContext& trace_context, - const envoy::config::trace::v3::OpenCensusConfig& oc_config) { - // Determine if there is a parent context. - using OpenCensusConfig = envoy::config::trace::v3::OpenCensusConfig; - ::opencensus::trace::SpanContext parent_ctx; - for (const auto& incoming : oc_config.incoming_trace_context()) { - bool found = false; - switch (incoming) { - case OpenCensusConfig::TRACE_CONTEXT: { - const auto entry = trace_context.getByKey(Constants::get().TRACEPARENT); - if (entry.has_value()) { - found = true; - // This is an implicitly untrusted header, so only the first value is used. - parent_ctx = ::opencensus::trace::propagation::FromTraceParentHeader(entry.value()); - } - break; - } - case OpenCensusConfig::GRPC_TRACE_BIN: { - const auto entry = trace_context.getByKey(Constants::get().GRPC_TRACE_BIN); - if (entry.has_value()) { - found = true; - // This is an implicitly untrusted header, so only the first value is used. - parent_ctx = ::opencensus::trace::propagation::FromGrpcTraceBinHeader( - Base64::decodeWithoutPadding(entry.value())); - } - break; - } - case OpenCensusConfig::CLOUD_TRACE_CONTEXT: { - const auto entry = trace_context.getByKey(Constants::get().X_CLOUD_TRACE_CONTEXT); - if (entry.has_value()) { - found = true; - // This is an implicitly untrusted header, so only the first value is used. - parent_ctx = ::opencensus::trace::propagation::FromCloudTraceContextHeader(entry.value()); - } - break; - } - - case OpenCensusConfig::B3: { - absl::string_view b3_trace_id; - absl::string_view b3_span_id; - absl::string_view b3_sampled; - absl::string_view b3_flags; - const auto h_b3_trace_id = trace_context.getByKey(Constants::get().X_B3_TRACEID); - if (h_b3_trace_id.has_value()) { - b3_trace_id = h_b3_trace_id.value(); - } - const auto h_b3_span_id = trace_context.getByKey(Constants::get().X_B3_SPANID); - if (h_b3_span_id.has_value()) { - b3_span_id = h_b3_span_id.value(); - } - const auto h_b3_sampled = trace_context.getByKey(Constants::get().X_B3_SAMPLED); - if (h_b3_sampled.has_value()) { - b3_sampled = h_b3_sampled.value(); - } - const auto h_b3_flags = trace_context.getByKey(Constants::get().X_B3_FLAGS); - if (h_b3_flags.has_value()) { - b3_flags = h_b3_flags.value(); - } - if (h_b3_trace_id.has_value() && h_b3_span_id.has_value()) { - found = true; - parent_ctx = ::opencensus::trace::propagation::FromB3Headers(b3_trace_id, b3_span_id, - b3_sampled, b3_flags); - } - break; - } - } - // First header found wins. - if (found) { - break; - } - } - - // Honor Envoy's tracing decision. - ::opencensus::trace::AlwaysSampler always_sampler; - ::opencensus::trace::NeverSampler never_sampler; - // This is safe because opts are not used after StartSpan. - ::opencensus::trace::StartSpanOptions opts{&never_sampler}; - if (traced) { - opts.sampler = &always_sampler; - } - - if (parent_ctx.IsValid()) { - return ::opencensus::trace::Span::StartSpanWithRemoteParent(name, parent_ctx, opts); - } - return ::opencensus::trace::Span::StartSpan(name, /*parent=*/nullptr, opts); -} - -Span::Span(const Tracing::Config& config, - const envoy::config::trace::v3::OpenCensusConfig& oc_config, - Tracing::TraceContext& trace_context, const std::string& operation_name, - SystemTime /*start_time*/, const Tracing::Decision tracing_decision) - : span_(startSpanHelper(operation_name, tracing_decision.traced, trace_context, oc_config)), - oc_config_(oc_config) { - span_.AddAttribute("OperationName", config.operationName() == Tracing::OperationName::Ingress - ? "Ingress" - : "Egress"); -} - -Span::Span(const envoy::config::trace::v3::OpenCensusConfig& oc_config, - ::opencensus::trace::Span&& span) - : span_(std::move(span)), oc_config_(oc_config) {} - -void Span::setOperation(absl::string_view operation) { span_.SetName(operation); } - -void Span::setTag(absl::string_view name, absl::string_view value) { - span_.AddAttribute(name, value); -} - -void Span::log(SystemTime /*timestamp*/, const std::string& event) { - // timestamp is ignored. - span_.AddAnnotation(event); -} - -void Span::finishSpan() { span_.End(); } - -void Span::injectContext(Tracing::TraceContext& trace_context, - const Upstream::HostDescriptionConstSharedPtr&) { - using OpenCensusConfig = envoy::config::trace::v3::OpenCensusConfig; - const auto& ctx = span_.context(); - for (const auto& outgoing : oc_config_.outgoing_trace_context()) { - switch (outgoing) { - case OpenCensusConfig::TRACE_CONTEXT: - trace_context.setByReferenceKey(Constants::get().TRACEPARENT, - ::opencensus::trace::propagation::ToTraceParentHeader(ctx)); - break; - case OpenCensusConfig::GRPC_TRACE_BIN: { - std::string val = ::opencensus::trace::propagation::ToGrpcTraceBinHeader(ctx); - val = Base64::encode(val.data(), val.size(), /*add_padding=*/false); - trace_context.setByReferenceKey(Constants::get().GRPC_TRACE_BIN, val); - break; - } - case OpenCensusConfig::CLOUD_TRACE_CONTEXT: - trace_context.setByReferenceKey( - Constants::get().X_CLOUD_TRACE_CONTEXT, - ::opencensus::trace::propagation::ToCloudTraceContextHeader(ctx)); - break; - case OpenCensusConfig::B3: - trace_context.setByReferenceKey(Constants::get().X_B3_TRACEID, - ::opencensus::trace::propagation::ToB3TraceIdHeader(ctx)); - trace_context.setByReferenceKey(Constants::get().X_B3_SPANID, - ::opencensus::trace::propagation::ToB3SpanIdHeader(ctx)); - trace_context.setByReferenceKey(Constants::get().X_B3_SAMPLED, - ::opencensus::trace::propagation::ToB3SampledHeader(ctx)); - // OpenCensus's trace context propagation doesn't produce the - // "X-B3-Flags:" header. - break; - } - } -} - -std::string Span::getTraceIdAsHex() const { - const auto& ctx = span_.context(); - return ctx.trace_id().ToHex(); -} - -Tracing::SpanPtr Span::spawnChild(const Tracing::Config& /*config*/, const std::string& name, - SystemTime /*start_time*/) { - return std::make_unique(oc_config_, - ::opencensus::trace::Span::StartSpan(name, /*parent=*/&span_)); -} - -void Span::setSampled(bool sampled) { span_.AddAnnotation("setSampled", {{"sampled", sampled}}); } - -} // namespace - -Driver::Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config, - const LocalInfo::LocalInfo& localinfo, Api::Api& api) - : oc_config_(oc_config), local_info_(localinfo) { - // To give user a chance to correct initially invalid configuration and try to apply it once again - // without a need to restart Envoy, validation checks must be done prior to any side effects. - if (oc_config.stackdriver_exporter_enabled() && oc_config.has_stackdriver_grpc_service() && - !oc_config.stackdriver_grpc_service().has_google_grpc()) { - throw EnvoyException("Opencensus stackdriver tracer only support GoogleGrpc."); - } - if (oc_config.ocagent_exporter_enabled() && oc_config.has_ocagent_grpc_service() && - !oc_config.ocagent_grpc_service().has_google_grpc()) { - throw EnvoyException("Opencensus ocagent tracer only supports GoogleGrpc."); - } - // Process-wide side effects. - if (oc_config.has_trace_config()) { - applyTraceConfig(oc_config.trace_config()); - } - if (oc_config.stdout_exporter_enabled()) { - ::opencensus::exporters::trace::StdoutExporter::Register(); - } - if (oc_config.stackdriver_exporter_enabled()) { - ::opencensus::exporters::trace::StackdriverOptions opts; - opts.project_id = oc_config.stackdriver_project_id(); - if (!oc_config.stackdriver_address().empty()) { - auto channel = - grpc::CreateChannel(oc_config.stackdriver_address(), grpc::InsecureChannelCredentials()); - opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel); - } else if (oc_config.has_stackdriver_grpc_service() && - oc_config.stackdriver_grpc_service().has_google_grpc()) { -#ifdef ENVOY_GOOGLE_GRPC - envoy::config::core::v3::GrpcService stackdriver_service = - oc_config.stackdriver_grpc_service(); - if (stackdriver_service.google_grpc().target_uri().empty()) { - // If stackdriver server address is not provided, the default production stackdriver - // address will be used. - stackdriver_service.mutable_google_grpc()->set_target_uri(GoogleStackdriverTraceAddress); - } - auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(stackdriver_service, api); - // TODO(bianpengyuan): add tests for trace_service_stub and initial_metadata options with mock - // stubs. - opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel); - const auto& initial_metadata = stackdriver_service.initial_metadata(); - if (!initial_metadata.empty()) { - opts.prepare_client_context = [initial_metadata](grpc::ClientContext* ctx) { - for (const auto& metadata : initial_metadata) { - ctx->AddMetadata(metadata.key(), metadata.value()); - } - }; - } -#else - throw EnvoyException("Opencensus tracer: cannot handle stackdriver google grpc service, " - "google grpc is not built in."); -#endif - } - ::opencensus::exporters::trace::StackdriverExporter::Register(std::move(opts)); - } - if (oc_config.zipkin_exporter_enabled()) { - ::opencensus::exporters::trace::ZipkinExporterOptions opts(oc_config.zipkin_url()); - opts.service_name = local_info_.clusterName(); - ::opencensus::exporters::trace::ZipkinExporter::Register(opts); - } - if (oc_config.ocagent_exporter_enabled()) { - ::opencensus::exporters::trace::OcAgentOptions opts; - if (!oc_config.ocagent_address().empty()) { - opts.address = oc_config.ocagent_address(); - } else if (oc_config.has_ocagent_grpc_service() && - oc_config.ocagent_grpc_service().has_google_grpc()) { -#ifdef ENVOY_GOOGLE_GRPC - const envoy::config::core::v3::GrpcService& ocagent_service = - oc_config.ocagent_grpc_service(); - auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(ocagent_service, api); - opts.trace_service_stub = - ::opencensus::proto::agent::trace::v1::TraceService::NewStub(channel); -#else - throw EnvoyException("Opencensus tracer: cannot handle ocagent google grpc service, google " - "grpc is not built in."); -#endif - } - opts.service_name = local_info_.clusterName(); - ::opencensus::exporters::trace::OcAgentExporter::Register(std::move(opts)); - } -} - -void Driver::applyTraceConfig(const opencensus::proto::trace::v1::TraceConfig& config) { - using SamplerCase = opencensus::proto::trace::v1::TraceConfig::SamplerCase; - using opencensus::proto::trace::v1::ConstantSampler; - constexpr double kDefaultSamplingProbability = 1e-4; - double probability = kDefaultSamplingProbability; - - switch (config.sampler_case()) { - case SamplerCase::kProbabilitySampler: - probability = config.probability_sampler().samplingprobability(); - break; - case SamplerCase::kConstantSampler: - switch (config.constant_sampler().decision()) { - case ConstantSampler::ALWAYS_OFF: - probability = 0.; - break; - case ConstantSampler::ALWAYS_ON: - case ConstantSampler::ALWAYS_PARENT: - probability = 1.; - break; - default: - break; /* Keep default probability. */ - } - break; - case SamplerCase::kRateLimitingSampler: - ENVOY_LOG(error, "RateLimitingSampler is not supported."); - break; - case SamplerCase::SAMPLER_NOT_SET: - break; // Keep default. - default: - ENVOY_LOG(error, "Unknown sampler type in TraceConfig."); - } - - ::opencensus::trace::TraceConfig::SetCurrentTraceParams(::opencensus::trace::TraceParams{ - uint32_t(config.max_number_of_attributes()), uint32_t(config.max_number_of_annotations()), - uint32_t(config.max_number_of_message_events()), uint32_t(config.max_number_of_links()), - ::opencensus::trace::ProbabilitySampler(probability)}); -} - -Tracing::SpanPtr Driver::startSpan(const Tracing::Config& config, - Tracing::TraceContext& trace_context, - const StreamInfo::StreamInfo& stream_info, - const std::string& operation_name, - const Tracing::Decision tracing_decision) { - return std::make_unique(config, oc_config_, trace_context, operation_name, - stream_info.startTime(), tracing_decision); -} - -} // namespace OpenCensus -} // namespace Tracers -} // namespace Extensions -} // namespace Envoy diff --git a/source/extensions/tracers/opencensus/opencensus_tracer_impl.h b/source/extensions/tracers/opencensus/opencensus_tracer_impl.h deleted file mode 100644 index 1a392ce9f59dd..0000000000000 --- a/source/extensions/tracers/opencensus/opencensus_tracer_impl.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "envoy/api/api.h" -#include "envoy/config/trace/v3/opencensus.pb.h" -#include "envoy/local_info/local_info.h" -#include "envoy/tracing/trace_driver.h" - -#include "source/common/common/logger.h" - -namespace Envoy { -namespace Extensions { -namespace Tracers { -namespace OpenCensus { - -/** - * OpenCensus tracing driver. - */ -class Driver : public Tracing::Driver, Logger::Loggable { -public: - Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config, - const LocalInfo::LocalInfo& localinfo, Api::Api& api); - - // Tracing::Driver - Tracing::SpanPtr startSpan(const Tracing::Config& config, Tracing::TraceContext& trace_context, - const StreamInfo::StreamInfo& stream_info, - const std::string& operation_name, - const Tracing::Decision tracing_decision) override; - -private: - void applyTraceConfig(const opencensus::proto::trace::v1::TraceConfig& config); - - const envoy::config::trace::v3::OpenCensusConfig oc_config_; - const LocalInfo::LocalInfo& local_info_; -}; - -} // namespace OpenCensus -} // namespace Tracers -} // namespace Extensions -} // namespace Envoy diff --git a/test/extensions/tracers/opencensus/BUILD b/test/extensions/tracers/opencensus/BUILD deleted file mode 100644 index 64e7311cec58a..0000000000000 --- a/test/extensions/tracers/opencensus/BUILD +++ /dev/null @@ -1,42 +0,0 @@ -load( - "//bazel:envoy_build_system.bzl", - "envoy_package", -) -load( - "//test/extensions:extensions_build_system.bzl", - "envoy_extension_cc_test", -) - -licenses(["notice"]) # Apache 2 - -envoy_package() - -envoy_extension_cc_test( - name = "tracer_test", - srcs = ["tracer_test.cc"], - extension_names = ["envoy.tracers.opencensus"], - # TODO(wrowe): envoy_extension_ rules don't currently exclude windows extensions - tags = ["skip_on_windows"], - deps = [ - "//source/extensions/tracers/opencensus:opencensus_tracer_impl", - "//test/mocks/http:http_mocks", - "//test/mocks/local_info:local_info_mocks", - "//test/mocks/stream_info:stream_info_mocks", - "//test/mocks/tracing:tracing_mocks", - "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", - ], -) - -envoy_extension_cc_test( - name = "config_test", - srcs = ["config_test.cc"], - extension_names = ["envoy.tracers.opencensus"], - # TODO(wrowe): envoy_extension_ rules don't currently exclude windows extensions - tags = ["skip_on_windows"], - deps = [ - "//source/extensions/tracers/opencensus:config", - "//test/mocks/server:server_mocks", - "//test/test_common:utility_lib", - "@envoy_api//envoy/config/trace/v3:pkg_cc_proto", - ], -) diff --git a/test/extensions/tracers/opencensus/config_test.cc b/test/extensions/tracers/opencensus/config_test.cc deleted file mode 100644 index b03f3445822bb..0000000000000 --- a/test/extensions/tracers/opencensus/config_test.cc +++ /dev/null @@ -1,403 +0,0 @@ -#include "envoy/config/trace/v3/http_tracer.pb.h" -#include "envoy/config/trace/v3/opencensus.pb.h" -#include "envoy/config/trace/v3/opencensus.pb.validate.h" -#include "envoy/registry/registry.h" - -#include "source/extensions/tracers/opencensus/config.h" - -#include "test/mocks/server/tracer_factory.h" -#include "test/mocks/server/tracer_factory_context.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "opencensus/trace/sampler.h" -#include "opencensus/trace/trace_config.h" - -namespace Envoy { -namespace Extensions { -namespace Tracers { -namespace OpenCensus { - -TEST(OpenCensusTracerConfigTest, InvalidStackdriverConfiguration) { - NiceMock context; - OpenCensusTracerFactory factory; - - const std::string yaml_string = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - stackdriver_exporter_enabled: true - stackdriver_grpc_service: - envoy_grpc: - cluster_name: stackdriver - )EOF"; - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - EXPECT_THROW_WITH_MESSAGE((factory.createTracerDriver(*message, context)), EnvoyException, - "Opencensus stackdriver tracer only support GoogleGrpc."); -} - -TEST(OpenCensusTracerConfigTest, InvalidOcagentConfiguration) { - NiceMock context; - OpenCensusTracerFactory factory; - - const std::string yaml_string = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - ocagent_exporter_enabled: true - ocagent_grpc_service: - envoy_grpc: - cluster_name: opencensus - )EOF"; - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - EXPECT_THROW_WITH_MESSAGE((factory.createTracerDriver(*message, context)), EnvoyException, - "Opencensus ocagent tracer only supports GoogleGrpc."); -} - -TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracer) { - NiceMock context; - const std::string yaml_string = R"EOF( - http: - name: envoy.tracers.opencensus - )EOF"; - - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - OpenCensusTracerFactory factory; - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer = factory.createTracerDriver(*message, context); - EXPECT_NE(nullptr, tracer); -} - -TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracerWithTypedConfig) { - NiceMock context; - const std::string yaml_string = R"EOF( - http: - name: opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - trace_config: - rate_limiting_sampler: - qps: 123 - max_number_of_attributes: 12 - max_number_of_annotations: 34 - max_number_of_message_events: 56 - max_number_of_links: 78 - stdout_exporter_enabled: true - stackdriver_exporter_enabled: true - stackdriver_project_id: test_project_id - ocagent_exporter_enabled: true - ocagent_address: 127.0.0.1:55678 - incoming_trace_context: b3 - incoming_trace_context: trace_context - incoming_trace_context: grpc_trace_bin - incoming_trace_context: cloud_trace_context - outgoing_trace_context: trace_context - )EOF"; - - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - OpenCensusTracerFactory factory; - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer = factory.createTracerDriver(*message, context); - EXPECT_NE(nullptr, tracer); - - // Reset TraceParams back to default. - ::opencensus::trace::TraceConfig::SetCurrentTraceParams( - {32, 32, 128, 32, ::opencensus::trace::ProbabilitySampler(1e-4)}); -} - -TEST(OpenCensusTracerConfigTest, - DEPRECATED_FEATURE_TEST(OpenCensusHttpTracerWithDeprecatedTypedConfig)) { - NiceMock context; - const std::string yaml_string = R"EOF( - http: - name: opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - trace_config: - rate_limiting_sampler: - qps: 123 - zipkin_exporter_enabled: true - zipkin_url: http://127.0.0.1:9411/api/v2/spans - incoming_trace_context: b3 - incoming_trace_context: trace_context - incoming_trace_context: grpc_trace_bin - incoming_trace_context: cloud_trace_context - outgoing_trace_context: trace_context - )EOF"; - - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - OpenCensusTracerFactory factory; - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer = factory.createTracerDriver(*message, context); - EXPECT_NE(nullptr, tracer); - - // Reset TraceParams back to default. - ::opencensus::trace::TraceConfig::SetCurrentTraceParams( - {32, 32, 128, 32, ::opencensus::trace::ProbabilitySampler(1e-4)}); -} - -TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracerGrpc) { - NiceMock context; - const std::string yaml_string = R"EOF( - http: - name: opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - trace_config: - rate_limiting_sampler: - qps: 123 - max_number_of_attributes: 12 - max_number_of_annotations: 34 - max_number_of_message_events: 56 - max_number_of_links: 78 - ocagent_exporter_enabled: true - ocagent_grpc_service: - google_grpc: - target_uri: 127.0.0.1:55678 - stat_prefix: test - incoming_trace_context: b3 - incoming_trace_context: trace_context - incoming_trace_context: grpc_trace_bin - incoming_trace_context: cloud_trace_context - outgoing_trace_context: trace_context - )EOF"; - - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - OpenCensusTracerFactory factory; - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); -#ifdef ENVOY_GOOGLE_GRPC - auto tracer = factory.createTracerDriver(*message, context); - EXPECT_NE(nullptr, tracer); - - // Reset TraceParams back to default. - ::opencensus::trace::TraceConfig::SetCurrentTraceParams( - {32, 32, 128, 32, ::opencensus::trace::ProbabilitySampler(1e-4)}); -#else - EXPECT_THROW_WITH_MESSAGE( - (factory.createTracerDriver(*message, context)), EnvoyException, - "Opencensus tracer: cannot handle ocagent google grpc service, google grpc is not built in."); -#endif -} - -TEST(OpenCensusTracerConfigTest, ShouldCreateAtMostOneOpenCensusTracer) { - NiceMock context; - OpenCensusTracerFactory factory; - - const std::string yaml_string = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - trace_config: - rate_limiting_sampler: - qps: 123 - )EOF"; - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - auto message_one = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer_one = factory.createTracerDriver(*message_one, context); - EXPECT_NE(nullptr, tracer_one); - - auto message_two = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer_two = factory.createTracerDriver(*message_two, context); - // Verify that no new tracer has been created. - EXPECT_EQ(tracer_two, tracer_one); -} - -TEST(OpenCensusTracerConfigTest, ShouldCacheFirstCreatedTracerUsingStrongReference) { - NiceMock context; - OpenCensusTracerFactory factory; - - const std::string yaml_string = R"EOF( - http: - name: envoy.tracers.opencensus - )EOF"; - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - auto message_one = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - std::weak_ptr tracer_one = factory.createTracerDriver(*message_one, context); - // Verify that tracer factory keeps a strong reference. - EXPECT_NE(nullptr, tracer_one.lock()); - - auto message_two = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer_two = factory.createTracerDriver(*message_two, context); - EXPECT_NE(nullptr, tracer_two); - // Verify that no new tracer has been created. - EXPECT_EQ(tracer_two, tracer_one.lock()); -} - -TEST(OpenCensusTracerConfigTest, ShouldNotCacheInvalidConfiguration) { - NiceMock context; - OpenCensusTracerFactory factory; - - const std::string yaml_one = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - ocagent_exporter_enabled: true - ocagent_grpc_service: - envoy_grpc: - cluster_name: opencensus - )EOF"; - envoy::config::trace::v3::Tracing configuration_one; - TestUtility::loadFromYaml(yaml_one, configuration_one); - - auto message_one = Config::Utility::translateToFactoryConfig( - configuration_one.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - EXPECT_THROW_WITH_MESSAGE((factory.createTracerDriver(*message_one, context)), EnvoyException, - "Opencensus ocagent tracer only supports GoogleGrpc."); - - const std::string yaml_two = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - ocagent_exporter_enabled: true - ocagent_grpc_service: - google_grpc: - target_uri: 127.0.0.1:55678 - stat_prefix: test - )EOF"; - envoy::config::trace::v3::Tracing configuration_two; - TestUtility::loadFromYaml(yaml_two, configuration_two); - - auto message_two = Config::Utility::translateToFactoryConfig( - configuration_two.http(), ProtobufMessage::getStrictValidationVisitor(), factory); -#ifdef ENVOY_GOOGLE_GRPC - auto tracer_two = factory.createTracerDriver(*message_two, context); - // Verify that a new tracer has been created despite an earlier failed attempt. - EXPECT_NE(nullptr, tracer_two); -#else - EXPECT_THROW_WITH_MESSAGE( - (factory.createTracerDriver(*message_two, context)), EnvoyException, - "Opencensus tracer: cannot handle ocagent google grpc service, google grpc is not built in."); -#endif -} - -TEST(OpenCensusTracerConfigTest, ShouldRejectSubsequentCreateAttemptsWithDifferentConfig) { - NiceMock context; - OpenCensusTracerFactory factory; - - const std::string yaml_one = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - trace_config: - rate_limiting_sampler: - qps: 123 - )EOF"; - envoy::config::trace::v3::Tracing configuration_one; - TestUtility::loadFromYaml(yaml_one, configuration_one); - - auto message_one = Config::Utility::translateToFactoryConfig( - configuration_one.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer_one = factory.createTracerDriver(*message_one, context); - EXPECT_NE(nullptr, tracer_one); - - const std::string yaml_two = R"EOF( - http: - name: envoy.tracers.opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - trace_config: - rate_limiting_sampler: - qps: 321 - )EOF"; - envoy::config::trace::v3::Tracing configuration_two; - TestUtility::loadFromYaml(yaml_two, configuration_two); - - auto message_two = Config::Utility::translateToFactoryConfig( - configuration_two.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - // Verify that OpenCensus is only configured once in a lifetime. - EXPECT_THROW_WITH_MESSAGE((factory.createTracerDriver(*message_two, context)), EnvoyException, - "Opencensus has already been configured with a different config."); -} - -TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracerStackdriverGrpc) { - NiceMock context; - const std::string yaml_string = R"EOF( - http: - name: opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - stackdriver_exporter_enabled: true - stackdriver_grpc_service: - google_grpc: - target_uri: 127.0.0.1:55678 - stat_prefix: test - initial_metadata: - - key: foo - value: bar - )EOF"; - - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - OpenCensusTracerFactory factory; - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); -#ifdef ENVOY_GOOGLE_GRPC - auto tracer = factory.createTracerDriver(*message, context); - EXPECT_NE(nullptr, tracer); -#else - EXPECT_THROW_WITH_MESSAGE((factory.createTracerDriver(*message, context)), EnvoyException, - "Opencensus tracer: cannot handle stackdriver google grpc service, " - "google grpc is not built in."); -#endif -} - -TEST(OpenCensusTracerConfigTest, OpenCensusHttpTracerStackdriverAddress) { - NiceMock context; - const std::string yaml_string = R"EOF( - http: - name: opencensus - typed_config: - "@type": type.googleapis.com/envoy.config.trace.v3.OpenCensusConfig - stackdriver_exporter_enabled: true - stackdriver_address: 127.0.0.1:55678 - )EOF"; - - envoy::config::trace::v3::Tracing configuration; - TestUtility::loadFromYaml(yaml_string, configuration); - - OpenCensusTracerFactory factory; - auto message = Config::Utility::translateToFactoryConfig( - configuration.http(), ProtobufMessage::getStrictValidationVisitor(), factory); - auto tracer = factory.createTracerDriver(*message, context); - EXPECT_NE(nullptr, tracer); -} - -} // namespace OpenCensus -} // namespace Tracers -} // namespace Extensions -} // namespace Envoy diff --git a/test/extensions/tracers/opencensus/tracer_test.cc b/test/extensions/tracers/opencensus/tracer_test.cc deleted file mode 100644 index 13eeffd2e7c79..0000000000000 --- a/test/extensions/tracers/opencensus/tracer_test.cc +++ /dev/null @@ -1,344 +0,0 @@ -// Usage: -// bazel run //test/extensions/tracers/opencensus:tracer_test -- -l debug - -#include -#include -#include - -#include "envoy/config/trace/v3/opencensus.pb.h" - -#include "source/common/common/base64.h" -#include "source/extensions/tracers/opencensus/opencensus_tracer_impl.h" - -#include "test/mocks/http/mocks.h" -#include "test/mocks/local_info/mocks.h" -#include "test/mocks/stream_info/mocks.h" -#include "test/mocks/tracing/mocks.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include "opencensus/trace/exporter/span_data.h" -#include "opencensus/trace/exporter/span_exporter.h" -#include "opencensus/trace/propagation/b3.h" -#include "opencensus/trace/propagation/cloud_trace_context.h" -#include "opencensus/trace/propagation/grpc_trace_bin.h" -#include "opencensus/trace/propagation/trace_context.h" -#include "opencensus/trace/span.h" -#include "opencensus/trace/span_id.h" - -using testing::NiceMock; - -namespace opencensus { -namespace trace { -namespace exporter { - -class SpanExporterTestPeer { -public: - static constexpr auto& exportForTesting = SpanExporter::ExportForTesting; -}; - -} // namespace exporter -} // namespace trace -} // namespace opencensus - -namespace Envoy { -namespace Extensions { -namespace Tracers { -namespace OpenCensus { - -using envoy::config::trace::v3::OpenCensusConfig; -using ::opencensus::trace::exporter::SpanData; -using ::opencensus::trace::exporter::SpanExporter; - -namespace { - -// Custom export handler. We register this as an OpenCensus trace exporter, and -// use it to catch the spans we produce. -class SpanCatcher : public SpanExporter::Handler { -public: - void Export(const std::vector& spans) override { - absl::MutexLock lock(&mu_); - for (const auto& span : spans) { - spans_.emplace_back(span); - } - } - - // Returns generated SpanData, and clears the catcher. - std::vector catchSpans() { - // OpenCensus's trace exporter is running in a background thread, waiting - // for a periodic export. Force it to flush right now. - opencensus::trace::exporter::SpanExporterTestPeer::exportForTesting(); - absl::MutexLock lock(&mu_); - std::vector ret = std::move(spans_); - spans_.clear(); - return ret; - } - -private: - mutable absl::Mutex mu_; - std::vector spans_ ABSL_GUARDED_BY(mu_); -}; - -// Use a Singleton SpanCatcher. -SpanCatcher* getSpanCatcher() { - static auto g_span_catcher = new SpanCatcher(); - return g_span_catcher; -} - -// Call this before generating spans to register the exporter that catches them. -void registerSpanCatcher() { - static bool done_once = false; - if (done_once) { - return; - } - SpanExporter::RegisterHandler(absl::WrapUnique(getSpanCatcher())); - done_once = true; -} - -} // namespace - -// Create a Span via the driver, test all of the Tracing::Span API, and verify -// the produced SpanData. -TEST(OpenCensusTracerTest, Span) { - registerSpanCatcher(); - OpenCensusConfig oc_config; - NiceMock local_info; - std::unique_ptr driver( - new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); - - NiceMock config; - Http::TestRequestHeaderMapImpl request_headers{ - {":path", "/"}, {":method", "GET"}, {"x-request-id", "foo"}}; - const std::string operation_name{"my_operation_1"}; - SystemTime fake_system_time; - NiceMock stream_info; - - { - Tracing::SpanPtr span = driver->startSpan(config, request_headers, stream_info, operation_name, - {Tracing::Reason::Sampling, true}); - span->setOperation("different_name"); - span->setTag("my_key", "my_value"); - span->log(fake_system_time, "my annotation"); - // injectContext is tested in another unit test. - Tracing::SpanPtr child = span->spawnChild(config, "child_span", fake_system_time); - child->finishSpan(); - span->setSampled(false); // Abandon tracer. - span->finishSpan(); - - // Baggage methods are a noop in opencensus and won't affect events. - span->setBaggage("baggage_key", "baggage_value"); - ASSERT_EQ("", span->getBaggage("baggage_key")); - - // Trace id is automatically created when no parent context exists. - ASSERT_NE(span->getTraceIdAsHex(), ""); - } - - // Retrieve SpanData from the OpenCensus trace exporter. - std::vector spans = getSpanCatcher()->catchSpans(); - ASSERT_EQ(2, spans.size()); - ::opencensus::trace::SpanId parent_span_id; - - // Check contents of parent span. - { - const auto& sd = (spans[0].name() == operation_name) ? spans[0] : spans[1]; - ENVOY_LOG_MISC(debug, "{}", sd.DebugString()); - - EXPECT_EQ("different_name", sd.name()); - EXPECT_TRUE(sd.context().IsValid()); - EXPECT_TRUE(sd.context().trace_options().IsSampled()); - ::opencensus::trace::SpanId zeros; - EXPECT_EQ(zeros, sd.parent_span_id()); - parent_span_id = sd.context().span_id(); - - ASSERT_EQ(2, sd.annotations().events().size()); - EXPECT_EQ("my annotation", sd.annotations().events()[0].event().description()); - EXPECT_EQ("setSampled", sd.annotations().events()[1].event().description()); - EXPECT_TRUE(sd.has_ended()); - } - - // And child span. - { - const auto& sd = (spans[0].name() == "child_span") ? spans[0] : spans[1]; - ENVOY_LOG_MISC(debug, "{}", sd.DebugString()); - - EXPECT_EQ("child_span", sd.name()); - EXPECT_TRUE(sd.context().IsValid()); - EXPECT_TRUE(sd.context().trace_options().IsSampled()); - EXPECT_EQ(parent_span_id, sd.parent_span_id()); - EXPECT_TRUE(sd.has_ended()); - } -} - -namespace { - -using testing::PrintToString; - -MATCHER_P2(ContainHeader, header, expected_value, - "contains the header " + PrintToString(header) + " with value " + - PrintToString(expected_value)) { - const auto found_value = arg.get(Http::LowerCaseString(header)); - if (found_value.empty()) { - return false; - } - return found_value[0]->value().getStringView() == expected_value; -} - -// Given incoming headers, test that trace context propagation works and generates all the expected -// outgoing headers. -void testIncomingHeaders( - const std::initializer_list>& headers) { - registerSpanCatcher(); - OpenCensusConfig oc_config; - NiceMock local_info; - oc_config.add_incoming_trace_context(OpenCensusConfig::NONE); - oc_config.add_incoming_trace_context(OpenCensusConfig::B3); - oc_config.add_incoming_trace_context(OpenCensusConfig::TRACE_CONTEXT); - oc_config.add_incoming_trace_context(OpenCensusConfig::GRPC_TRACE_BIN); - oc_config.add_incoming_trace_context(OpenCensusConfig::CLOUD_TRACE_CONTEXT); - oc_config.add_outgoing_trace_context(OpenCensusConfig::NONE); - oc_config.add_outgoing_trace_context(OpenCensusConfig::B3); - oc_config.add_outgoing_trace_context(OpenCensusConfig::TRACE_CONTEXT); - oc_config.add_outgoing_trace_context(OpenCensusConfig::GRPC_TRACE_BIN); - oc_config.add_outgoing_trace_context(OpenCensusConfig::CLOUD_TRACE_CONTEXT); - std::unique_ptr driver( - new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); - NiceMock config; - Http::TestRequestHeaderMapImpl request_headers{ - {":path", "/"}, - {":method", "GET"}, - {"x-request-id", "foo"}, - }; - for (const auto& kv : headers) { - request_headers.addCopy(Http::LowerCaseString(kv.first), kv.second); - } - - const std::string operation_name{"my_operation_2"}; - NiceMock stream_info; - Http::TestRequestHeaderMapImpl injected_headers; - { - Tracing::SpanPtr span = driver->startSpan(config, request_headers, stream_info, operation_name, - {Tracing::Reason::Sampling, false}); - span->injectContext(injected_headers, nullptr); - span->finishSpan(); - - // Check contents via public API. - // Trace id is set via context propagation headers. - EXPECT_EQ(span->getTraceIdAsHex(), "404142434445464748494a4b4c4d4e4f"); - } - - // Retrieve SpanData from the OpenCensus trace exporter. - std::vector spans = getSpanCatcher()->catchSpans(); - ASSERT_EQ(1, spans.size()); - const auto& sd = spans[0]; - ENVOY_LOG_MISC(debug, "{}", sd.DebugString()); - - // Check contents by inspecting private span data. - EXPECT_TRUE(sd.has_remote_parent()); - EXPECT_EQ("6162636465666768", sd.parent_span_id().ToHex()); - EXPECT_EQ("404142434445464748494a4b4c4d4e4f", sd.context().trace_id().ToHex()); - EXPECT_TRUE(sd.context().trace_options().IsSampled()) - << "parent was sampled, child should be also"; - - // Check injectContext. - // The SpanID is unpredictable so re-serialize context to check it. - const auto& ctx = sd.context(); - const auto& hdrs = injected_headers; - EXPECT_THAT(hdrs, ContainHeader("traceparent", - ::opencensus::trace::propagation::ToTraceParentHeader(ctx))); - { - std::string expected = ::opencensus::trace::propagation::ToGrpcTraceBinHeader(ctx); - expected = Base64::encode(expected.data(), expected.size(), /*add_padding=*/false); - EXPECT_THAT(hdrs, ContainHeader("grpc-trace-bin", expected)); - } - EXPECT_THAT(hdrs, - ContainHeader("x-cloud-trace-context", - ::opencensus::trace::propagation::ToCloudTraceContextHeader(ctx))); - EXPECT_THAT(hdrs, ContainHeader("x-b3-traceid", "404142434445464748494a4b4c4d4e4f")); - EXPECT_THAT( - hdrs, ContainHeader("x-b3-spanid", ::opencensus::trace::propagation::ToB3SpanIdHeader(ctx))); - EXPECT_THAT(hdrs, ContainHeader("x-b3-sampled", "1")); -} -} // namespace - -TEST(OpenCensusTracerTest, PropagateTraceParentContext) { - testIncomingHeaders({{"traceparent", "00-404142434445464748494a4b4c4d4e4f-6162636465666768-01"}}); -} - -TEST(OpenCensusTracerTest, PropagateGrpcTraceBinContext) { - testIncomingHeaders({{"grpc-trace-bin", "AABAQUJDREVGR0hJSktMTU5PAWFiY2RlZmdoAgE"}}); -} - -TEST(OpenCensusTracerTest, PropagateCloudTraceContext) { - testIncomingHeaders( - {{"x-cloud-trace-context", "404142434445464748494a4b4c4d4e4f/7017280452245743464;o=1"}}); -} - -TEST(OpenCensusTracerTest, PropagateB3Context) { - testIncomingHeaders({{"x-b3-traceid", "404142434445464748494a4b4c4d4e4f"}, - {"x-b3-spanid", "6162636465666768"}, - {"x-b3-sampled", "1"}}); -} - -TEST(OpenCensusTracerTest, PropagateB3ContextWithDebugFlag) { - testIncomingHeaders({{"x-b3-traceid", "404142434445464748494a4b4c4d4e4f"}, - {"x-b3-spanid", "6162636465666768"}, - {"x-b3-flags", "1"}}); // Debug flag causes sampling. -} - -namespace { - -// Create a Span using the given config and return how many spans made it to -// the exporter (either zero or one). -int SamplerTestHelper(const OpenCensusConfig& oc_config) { - registerSpanCatcher(); - NiceMock local_info; - std::unique_ptr driver( - new OpenCensus::Driver(oc_config, local_info, *Api::createApiForTest())); - auto span = ::opencensus::trace::Span::StartSpan("test_span"); - span.End(); - // Retrieve SpanData from the OpenCensus trace exporter. - std::vector spans = getSpanCatcher()->catchSpans(); - EXPECT_GE(spans.size(), 0); - EXPECT_LE(spans.size(), 1); - if (!spans.empty()) { - EXPECT_TRUE(spans[0].context().trace_options().IsSampled()); - } - return spans.size(); -} - -} // namespace - -// Test constant_sampler that's always on. -TEST(OpenCensusTracerTest, ConstantSamplerAlwaysOn) { - OpenCensusConfig oc_config; - oc_config.mutable_trace_config()->mutable_constant_sampler()->set_decision( - ::opencensus::proto::trace::v1::ConstantSampler::ALWAYS_ON); - EXPECT_EQ(1, SamplerTestHelper(oc_config)); -} - -// Test constant_sampler that's always off. -TEST(OpenCensusTracerTest, ConstantSamplerAlwaysOff) { - OpenCensusConfig oc_config; - oc_config.mutable_trace_config()->mutable_constant_sampler()->set_decision( - ::opencensus::proto::trace::v1::ConstantSampler::ALWAYS_OFF); - EXPECT_EQ(0, SamplerTestHelper(oc_config)); -} - -// Test probability_sampler that's always on. -TEST(OpenCensusTracerTest, ProbabilitySamplerAlwaysOn) { - OpenCensusConfig oc_config; - oc_config.mutable_trace_config()->mutable_probability_sampler()->set_samplingprobability(1.0); - EXPECT_EQ(1, SamplerTestHelper(oc_config)); -} - -// Test probability_sampler that's always off. -TEST(OpenCensusTracerTest, ProbabilitySamplerAlwaysOff) { - OpenCensusConfig oc_config; - oc_config.mutable_trace_config()->mutable_probability_sampler()->set_samplingprobability(0.0); - EXPECT_EQ(0, SamplerTestHelper(oc_config)); -} - -} // namespace OpenCensus -} // namespace Tracers -} // namespace Extensions -} // namespace Envoy