Skip to content

Commit

Permalink
Skeleton of a tracer for AWS X-Ray (#8526)
Browse files Browse the repository at this point in the history
A skeleton tracer to incrementally add support for AWS X-Ray

Risk Level: Low
Testing: unit tests for functionality in util - the rest of files have no business logic to test yet

Signed-off-by: Marco Magdy <mmagdy@gmail.com>
  • Loading branch information
marcomagdy authored and htuch committed Oct 22, 2019
1 parent 37544e6 commit f68368f
Show file tree
Hide file tree
Showing 21 changed files with 689 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ extensions/filters/common/original_src @snowp @klarose
/*/extensions/filters/network/sni_cluster @rshriram @lizan
# tracers.datadog extension
/*/extensions/tracers/datadog @cgilmour @palazzem
# tracers.xray extension
/*/extensions/tracers/xray @marcomagdy @lavignes
# mysql_proxy extension
/*/extensions/filters/network/mysql_proxy @rshriram @venilnoronha @mattklein123
# quic extension
Expand Down
18 changes: 18 additions & 0 deletions api/envoy/config/trace/v2/trace.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ option java_outer_classname = "TraceProto";
option java_multiple_files = true;
option java_package = "io.envoyproxy.envoy.config.trace.v2";

import "envoy/api/v2/core/base.proto";
import "envoy/api/v2/core/grpc_service.proto";

import "google/protobuf/any.proto";
Expand Down Expand Up @@ -34,6 +35,7 @@ message Tracing {
// - *envoy.dynamic.ot*
// - *envoy.tracers.datadog*
// - *envoy.tracers.opencensus*
// - *envoy.tracers.xray*
string name = 1 [(validate.rules).string = {min_bytes: 1}];

// Trace driver specific configuration which depends on the driver being instantiated.
Expand All @@ -44,6 +46,8 @@ message Tracing {
// - :ref:`DynamicOtConfig <envoy_api_msg_config.trace.v2.DynamicOtConfig>`
// - :ref:`DatadogConfig <envoy_api_msg_config.trace.v2.DatadogConfig>`
// - :ref:`OpenCensusConfig <envoy_api_msg_config.trace.v2.OpenCensusConfig>`
// [#comment: TODO(marco) when XRay is implemented, uncomment the following; - :ref:`XRayConfig
// <envoy_api_msg_config.trace.v2.XRayConfig>`]
oneof config_type {
google.protobuf.Struct config = 2;

Expand Down Expand Up @@ -199,6 +203,20 @@ message OpenCensusConfig {
repeated TraceContext outgoing_trace_context = 9;
}

// [#not-implemented-hide:]
// Configuration for AWS X-Ray tracer.
message XRayConfig {
// The endpoint of the X-Ray Daemon where the spans will be sent. Since by default daemon
// listens to localhost:2000, so the default value is 127.0.0.1:2000.
string daemon_endpoint = 1 [(validate.rules).string = {min_bytes: 1}];

// The custom name to name a X-Ray segment. By default will use cluster name.
string segment_name = 2;

// The location of custom sampling rule json file.
api.v2.core.DataSource sampling_rule_manifest = 3;
}

// Configuration structure.
message TraceServiceConfig {
// The upstream gRPC cluster that hosts the metrics service.
Expand Down
18 changes: 18 additions & 0 deletions api/envoy/config/trace/v3alpha/trace.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ option java_outer_classname = "TraceProto";
option java_multiple_files = true;
option java_package = "io.envoyproxy.envoy.config.trace.v3alpha";

import "envoy/api/v3alpha/core/base.proto";
import "envoy/api/v3alpha/core/grpc_service.proto";

import "google/protobuf/any.proto";
Expand Down Expand Up @@ -34,6 +35,7 @@ message Tracing {
// - *envoy.dynamic.ot*
// - *envoy.tracers.datadog*
// - *envoy.tracers.opencensus*
// - *envoy.tracers.xray*
string name = 1 [(validate.rules).string = {min_bytes: 1}];

// Trace driver specific configuration which depends on the driver being instantiated.
Expand All @@ -44,6 +46,8 @@ message Tracing {
// - :ref:`DynamicOtConfig <envoy_api_msg_config.trace.v3alpha.DynamicOtConfig>`
// - :ref:`DatadogConfig <envoy_api_msg_config.trace.v3alpha.DatadogConfig>`
// - :ref:`OpenCensusConfig <envoy_api_msg_config.trace.v3alpha.OpenCensusConfig>`
// [#comment: TODO(marco) when XRay is implemented, uncomment the following; - :ref:`XRayConfig
// <envoy_api_msg_config.trace.v3alpha.XRayConfig>`]
oneof config_type {
google.protobuf.Struct config = 2;

Expand Down Expand Up @@ -199,6 +203,20 @@ message OpenCensusConfig {
repeated TraceContext outgoing_trace_context = 9;
}

// [#not-implemented-hide:]
// Configuration for AWS X-Ray tracer.
message XRayConfig {
// The endpoint of the X-Ray Daemon where the spans will be sent. Since by default daemon
// listens to localhost:2000, so the default value is 127.0.0.1:2000.
string daemon_endpoint = 1 [(validate.rules).string = {min_bytes: 1}];

// The custom name to name a X-Ray segment. By default will use cluster name.
string segment_name = 2;

// The location of custom sampling rule json file.
api.v3alpha.core.DataSource sampling_rule_manifest = 3;
}

// Configuration structure.
message TraceServiceConfig {
// The upstream gRPC cluster that hosts the metrics service.
Expand Down
1 change: 1 addition & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ EXTENSIONS = {
"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",

#
# Transport sockets
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/tracers/well_known_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class TracerNameValues {
const std::string Datadog = "envoy.tracers.datadog";
// OpenCensus tracer
const std::string OpenCensus = "envoy.tracers.opencensus";
// AWS XRay tracer
const std::string XRay = "envoy.tracers.xray";
};

using TracerNames = ConstSingleton<TracerNameValues>;
Expand Down
47 changes: 47 additions & 0 deletions source/extensions/tracers/xray/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
licenses(["notice"]) # Apache 2

# Trace driver for AWS X-Ray.

load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_package",
)

envoy_package()

envoy_cc_library(
name = "xray_lib",
srcs = [
"util.cc",
"xray_tracer_impl.cc",
],
hdrs = [
"sampling_strategy.h",
"tracer.h",
"util.h",
"xray_configuration.h",
"xray_tracer_impl.h",
],
deps = [
"//include/envoy/common:time_interface",
"//include/envoy/server:instance_interface",
"//include/envoy/tracing:http_tracer_interface",
"//source/common/common:macros",
"//source/common/http:header_map_lib",
"//source/common/json:json_loader_lib",
"//source/common/tracing:http_tracer_lib",
],
)

envoy_cc_library(
name = "config",
srcs = ["config.cc"],
hdrs = ["config.h"],
deps = [
":xray_lib",
"//source/common/config:datasource_lib",
"//source/extensions/tracers:well_known_names",
"//source/extensions/tracers/common:factory_base_lib",
],
)
47 changes: 47 additions & 0 deletions source/extensions/tracers/xray/config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "extensions/tracers/xray/config.h"

#include <string>

#include "envoy/registry/registry.h"

#include "common/common/utility.h"
#include "common/config/datasource.h"
#include "common/tracing/http_tracer_impl.h"

#include "extensions/tracers/well_known_names.h"
#include "extensions/tracers/xray/xray_tracer_impl.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace XRay {

XRayTracerFactory::XRayTracerFactory() : FactoryBase(TracerNames::get().XRay) {}

Tracing::HttpTracerPtr
XRayTracerFactory::createHttpTracerTyped(const envoy::config::trace::v2::XRayConfig& proto_config,
Server::Instance& server) {
std::string sampling_rules_json;
try {
sampling_rules_json =
Config::DataSource::read(proto_config.sampling_rule_manifest(), true, server.api());
} catch (EnvoyException& e) {
ENVOY_LOG(error, "Failed to read sampling rules manifest because of {}.", e.what());
}

XRayConfiguration xconfig(proto_config.daemon_endpoint(), proto_config.segment_name(),
sampling_rules_json);
auto xray_driver = std::make_unique<XRay::Driver>(xconfig, server);

return std::make_unique<Tracing::HttpTracerImpl>(std::move(xray_driver), server.localInfo());
}

/**
* Static registration for the XRay tracer. @see RegisterFactory.
*/
REGISTER_FACTORY(XRayTracerFactory, Server::Configuration::TracerFactory);

} // namespace XRay
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
31 changes: 31 additions & 0 deletions source/extensions/tracers/xray/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "envoy/config/trace/v2/trace.pb.validate.h"

#include "common/common/logger.h"

#include "extensions/tracers/common/factory_base.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace XRay {

/**
* Config registration for the XRay tracer. @see TracerFactory.
*/
class XRayTracerFactory : public Common::FactoryBase<envoy::config::trace::v2::XRayConfig>,
Logger::Loggable<Logger::Id::tracing> {
public:
XRayTracerFactory();

private:
Tracing::HttpTracerPtr
createHttpTracerTyped(const envoy::config::trace::v2::XRayConfig& proto_config,
Server::Instance& server) override;
};

} // namespace XRay
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
61 changes: 61 additions & 0 deletions source/extensions/tracers/xray/sampling_strategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once

#include <memory>
#include <random>

#include "envoy/common/pure.h"

#include "common/common/macros.h"

#include "absl/strings/string_view.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace XRay {

struct SamplingRequest {
/**
* Creates a new SamplingRequest
*
* @param host_name The host name the request.
* @param http_method The http method of the request e.g. GET, POST, etc.
* @param http_url The path part of the URL of the request.
* @param service The name of the service (user specified)
* @param service_type The type of the service (user specified)
*/
SamplingRequest(absl::string_view host_name, absl::string_view http_method,
absl::string_view http_url)
: host_(host_name), http_method_(http_method), http_url_(http_url) {}

const std::string host_;
const std::string http_method_;
const std::string http_url_;
};

/**
* Strategy provides an interface for implementing trace sampling strategies.
*/
class SamplingStrategy {
public:
explicit SamplingStrategy(uint64_t rng_seed) : rng_(rng_seed) {}
virtual ~SamplingStrategy() = default;

/**
* sampleRequest determines if the given request should be traced or not.
*/
virtual bool sampleRequest(const SamplingRequest& sampling_request) {
UNREFERENCED_PARAMETER(sampling_request); // unused for now
return rng_() % 100 == 42;
}

private:
std::mt19937 rng_;
};

using SamplingStrategyPtr = std::unique_ptr<SamplingStrategy>;

} // namespace XRay
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
37 changes: 37 additions & 0 deletions source/extensions/tracers/xray/tracer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <string>

#include "envoy/common/time.h"
#include "envoy/tracing/http_tracer.h"

#include "extensions/tracers/xray/sampling_strategy.h"

#include "absl/strings/string_view.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace XRay {

class Tracer {
public:
Tracer(absl::string_view segment_name, TimeSource& time_source)
: segment_name_(segment_name), time_source_(time_source) {
UNREFERENCED_PARAMETER(time_source_);
}

/**
* Starts a tracing span for XRay
*/
Tracing::SpanPtr startSpan() { return nullptr; }

private:
const std::string segment_name_;
TimeSource& time_source_;
};

} // namespace XRay
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
Loading

0 comments on commit f68368f

Please sign in to comment.