Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generic proxy: tracing support for the generic proxy based on the generic tracing #24790

Merged
merged 13 commits into from
Feb 14, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ licenses(["notice"]) # Apache 2
api_proto_package(
deps = [
"//envoy/config/core/v3:pkg",
"//envoy/extensions/filters/network/http_connection_manager/v3:pkg",
"@com_github_cncf_udpa//udpa/annotations:pkg",
"@com_github_cncf_udpa//xds/annotations/v3:pkg",
"@com_github_cncf_udpa//xds/type/matcher/v3:pkg",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package envoy.extensions.filters.network.generic_proxy.v3;
import "contrib/envoy/extensions/filters/network/generic_proxy/v3/route.proto";
import "envoy/config/core/v3/config_source.proto";
import "envoy/config/core/v3/extension.proto";
import "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto";

import "xds/annotations/v3/status.proto";

Expand All @@ -22,7 +23,7 @@ option (xds.annotations.v3.file_status).work_in_progress = true;
// Generic proxy.
// [#extension: envoy.filters.network.generic_proxy]

// [#next-free-field: 6]
// [#next-free-field: 7]
message GenericProxy {
// The human readable prefix to use when emitting statistics.
string stat_prefix = 1 [(validate.rules).string = {min_len: 1}];
Expand All @@ -47,6 +48,9 @@ message GenericProxy {
// happen.
// [#extension-category: envoy.generic_proxy.filters]
repeated config.core.v3.TypedExtensionConfig filters = 5;

// Tracing configuration for the generic proxy.
http_connection_manager.v3.HttpConnectionManager.Tracing tracing = 6;
}

message GenericRds {
Expand Down
1 change: 1 addition & 0 deletions contrib/generic_proxy/filters/network/source/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ envoy_cc_library(
"//source/common/common:linked_object",
"//source/common/common:minimal_logger_lib",
"//source/common/stream_info:stream_info_lib",
"//source/common/tracing:custom_tag_lib",
"//source/extensions/filters/network/common:factory_base_lib",
"@envoy_api//contrib/envoy/extensions/filters/network/generic_proxy/v3:pkg_cc_proto",
"@envoy_api//envoy/config/core/v3:pkg_cc_proto",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ envoy_cc_library(
hdrs = [
"stream.h",
],
deps = [
"//envoy/tracing:trace_context_interface",
],
)

envoy_cc_library(
Expand Down Expand Up @@ -91,5 +94,6 @@ envoy_cc_library(
":codec_interface",
":filter_interface",
":route_interface",
"//source/common/http:conn_manager_config_interface",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
#include "contrib/generic_proxy/filters/network/source/interface/filter.h"
#include "contrib/generic_proxy/filters/network/source/interface/route.h"

#include "source/common/http/conn_manager_config.h"

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace GenericProxy {

using TracingConnectionManagerConfig = Http::TracingConnectionManagerConfig;
using TracingConnectionManagerConfigPtr = std::unique_ptr<TracingConnectionManagerConfig>;

/**
* Filter config interface for generic proxy read filter.
*/
Expand All @@ -32,6 +37,16 @@ class FilterConfig : public FilterChainFactory {
* determine if they should be doing graceful closes on connections when possible.
*/
virtual const Network::DrainDecision& drainDecision() const PURE;

/**
* @return Tracing::Driver tracing driver to use.
*/
virtual OptRef<Tracing::Driver> tracingProvider() const PURE;

/**
* @return tracing config.
*/
virtual OptRef<const TracingConnectionManagerConfig> tracingConfig() const PURE;
};

} // namespace GenericProxy
Expand Down
26 changes: 7 additions & 19 deletions contrib/generic_proxy/filters/network/source/interface/stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <string>

#include "envoy/common/pure.h"
#include "envoy/tracing/trace_context.h"

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
Expand Down Expand Up @@ -69,12 +70,9 @@ class StreamBase {
* @param val The metadata value of string view type.
*/
virtual void setByReference(absl::string_view key, absl::string_view val) PURE;

// Used for matcher.
static constexpr absl::string_view name() { return "generic_proxy"; }
};

class Request : public StreamBase {
class Request : public Tracing::TraceContext {
public:
/**
* Get request host.
Expand All @@ -85,22 +83,12 @@ class Request : public StreamBase {
*/
virtual absl::string_view host() const PURE;

/**
* Get request path.
*
* @return The path of generic request. The meaning of the return value may be different For
* different application protocols. It typically should be RPC service name that used to
* represents set of method or functionality provided by target service.
*/
virtual absl::string_view path() const PURE;
// TODO(wbpcode): remove this method after we update the authority() in the TraceContext to
// host().
absl::string_view authority() const final { return host(); }

/**
* Get request method.
*
* @return The method of generic request. The meaning of the return value may be different For
* different application protocols.
*/
virtual absl::string_view method() const PURE;
// Used for matcher.
static constexpr absl::string_view name() { return "generic_proxy"; }
};
using RequestPtr = std::unique_ptr<Request>;
using RequestSharedPtr = std::shared_ptr<Request>;
Expand Down
76 changes: 76 additions & 0 deletions contrib/generic_proxy/filters/network/source/proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,87 @@
#include "contrib/generic_proxy/filters/network/source/interface/filter.h"
#include "contrib/generic_proxy/filters/network/source/route.h"

#include "source/common/tracing/custom_tag_impl.h"

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
namespace GenericProxy {

namespace {
using ProtoTracingConfig = envoy::extensions::filters::network::http_connection_manager::v3::
HttpConnectionManager::Tracing;

// TODO(wbpcode): Move
TracingConnectionManagerConfigPtr
getTracingConfig(const ProtoTracingConfig& tracing_config,
envoy::config::core::v3::TrafficDirection direction) {

Tracing::OperationName tracing_operation_name;

// Listener level traffic direction overrides the operation name
switch (direction) {
PANIC_ON_PROTO_ENUM_SENTINEL_VALUES;
case envoy::config::core::v3::UNSPECIFIED:
// Continuing legacy behavior; if unspecified, we treat this as ingress.
tracing_operation_name = Tracing::OperationName::Ingress;
break;
case envoy::config::core::v3::INBOUND:
tracing_operation_name = Tracing::OperationName::Ingress;
break;
case envoy::config::core::v3::OUTBOUND:
tracing_operation_name = Tracing::OperationName::Egress;
break;
}

Tracing::CustomTagMap custom_tags;
for (const auto& tag : tracing_config.custom_tags()) {
custom_tags.emplace(tag.tag(), Tracing::CustomTagUtility::createCustomTag(tag));
}

envoy::type::v3::FractionalPercent client_sampling;
client_sampling.set_numerator(
tracing_config.has_client_sampling() ? tracing_config.client_sampling().value() : 100);
envoy::type::v3::FractionalPercent random_sampling;
// TODO: Random sampling historically was an integer and default to out of 10,000. We should
// deprecate that and move to a straight fractional percent config.
uint64_t random_sampling_numerator{PROTOBUF_PERCENT_TO_ROUNDED_INTEGER_OR_DEFAULT(
tracing_config, random_sampling, 10000, 10000)};
random_sampling.set_numerator(random_sampling_numerator);
random_sampling.set_denominator(envoy::type::v3::FractionalPercent::TEN_THOUSAND);
envoy::type::v3::FractionalPercent overall_sampling;
uint64_t overall_sampling_numerator{PROTOBUF_PERCENT_TO_ROUNDED_INTEGER_OR_DEFAULT(
tracing_config, overall_sampling, 10000, 10000)};
overall_sampling.set_numerator(overall_sampling_numerator);
overall_sampling.set_denominator(envoy::type::v3::FractionalPercent::TEN_THOUSAND);

const uint32_t max_path_tag_length = PROTOBUF_GET_WRAPPED_OR_DEFAULT(
tracing_config, max_path_tag_length, Tracing::DefaultMaxPathTagLength);

return std::make_unique<TracingConnectionManagerConfig>(TracingConnectionManagerConfig{
tracing_operation_name, custom_tags, client_sampling, random_sampling, overall_sampling,
tracing_config.verbose(), max_path_tag_length});
}
} // namespace

FilterConfigImpl::FilterConfigImpl(const ProxyConfig& proto_config, const std::string& stat_prefix,
CodecFactoryPtr codec,
Rds::RouteConfigProviderSharedPtr route_config_provider,
std::vector<NamedFilterFactoryCb> factories,
Envoy::Server::Configuration::FactoryContext& context)
: stat_prefix_(stat_prefix), codec_factory_(std::move(codec)),
route_config_provider_(std::move(route_config_provider)), factories_(std::move(factories)),
drain_decision_(context.drainDecision()) {

if (proto_config.has_tracing()) {
if (!proto_config.tracing().has_provider()) {
throw EnvoyException("generic proxy: tracing configuration must have provider");
}

tracing_config_ = getTracingConfig(proto_config.tracing(), context.direction());
}
}

ActiveStream::ActiveStream(Filter& parent, RequestPtr request)
: parent_(parent), downstream_request_stream_(std::move(request)) {}

Expand Down
14 changes: 8 additions & 6 deletions contrib/generic_proxy/filters/network/source/proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "contrib/generic_proxy/filters/network/source/rds_impl.h"
#include "contrib/generic_proxy/filters/network/source/route.h"

#include "envoy/tracing/trace_driver.h"

namespace Envoy {
namespace Extensions {
namespace NetworkFilters {
Expand All @@ -43,13 +45,10 @@ struct NamedFilterFactoryCb {

class FilterConfigImpl : public FilterConfig {
public:
FilterConfigImpl(const std::string& stat_prefix, CodecFactoryPtr codec,
Rds::RouteConfigProviderSharedPtr route_config_provider,
FilterConfigImpl(const ProxyConfig& proto_config, const std::string& stat_prefix,
CodecFactoryPtr codec, Rds::RouteConfigProviderSharedPtr route_config_provider,
std::vector<NamedFilterFactoryCb> factories,
Envoy::Server::Configuration::FactoryContext& context)
: stat_prefix_(stat_prefix), codec_factory_(std::move(codec)),
route_config_provider_(std::move(route_config_provider)), factories_(std::move(factories)),
drain_decision_(context.drainDecision()) {}
Envoy::Server::Configuration::FactoryContext& context);

// FilterConfig
RouteEntryConstSharedPtr routeEntry(const Request& request) const override {
Expand Down Expand Up @@ -78,6 +77,9 @@ class FilterConfigImpl : public FilterConfig {

std::vector<NamedFilterFactoryCb> factories_;

Tracing::DriverSharedPtr tracing_driver_;
TracingConnectionManagerConfigPtr tracing_config_;

const Network::DrainDecision& drain_decision_;
};

Expand Down