Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bf9194e
add initial sampler prototype
samohte Sep 8, 2023
db030c7
create unique_ptr in Tracer::startSpan()
samohte Sep 8, 2023
f707065
move class Span to a separate header file
samohte Sep 12, 2023
68dfca2
pass SpanPtr to sampler, this is WIP, there is a cyclic dependency wh…
samohte Sep 12, 2023
bd5b746
Revert "pass SpanPtr to sampler, this is WIP, there is a cyclic depen…
samohte Sep 12, 2023
37928c2
Revert "Revert "pass SpanPtr to sampler, this is WIP, there is a cycl…
samohte Sep 12, 2023
9bcb722
Revert "pass SpanPtr to sampler, this is WIP, there is a cyclic depen…
samohte Sep 12, 2023
233ed8e
Revert "move class Span to a separate header file"
samohte Sep 12, 2023
b0b5c6a
towards otel spec
samohte Sep 12, 2023
9f3e20a
towards otel spec
samohte Sep 12, 2023
5eecca8
Use typed config instead of name to configure a sampler
samohte Sep 13, 2023
7b54e17
towards otel sampler interface: SamplingResult
samohte Sep 13, 2023
def36b8
move member sampler_ from opentelemetry_tracer_imp* to tracer*
samohte Sep 13, 2023
de54cad
towards otel sampler interface, extend shouldSample() parameters, add
samohte Sep 13, 2023
60d89de
extend shouldSample interface
samohte Sep 13, 2023
f0d63d0
towards otel sampler: cleanup always_on_sampler
samohte Sep 14, 2023
4dde595
remove redundant setSampled() call (already set in startSpan)
samohte Sep 14, 2023
43f7674
add "Dynatrace" sampler
samohte Sep 14, 2023
04a6bdc
remove Server::Configuration::TracerFactoryContext& from Sampler
samohte Sep 14, 2023
ec50461
add config to samplers constructor
samohte Sep 14, 2023
ead91c3
add "links" parameter, formatting
samohte Sep 14, 2023
ca77aee
make c'tor explicit
samohte Sep 14, 2023
b2a9fc6
remove type SpanPtr
samohte Sep 14, 2023
cd89e8c
formatting, renaming
samohte Sep 15, 2023
a40ec52
add fw4 tag
samohte Oct 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ proto_library(
"//envoy/extensions/stat_sinks/graphite_statsd/v3:pkg",
"//envoy/extensions/stat_sinks/open_telemetry/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
"//envoy/extensions/tracers/opentelemetry/samplers/v3:pkg",
"//envoy/extensions/transport_sockets/alts/v3:pkg",
"//envoy/extensions/transport_sockets/http_11_proxy/v3:pkg",
"//envoy/extensions/transport_sockets/internal_upstream/v3:pkg",
Expand Down
5 changes: 5 additions & 0 deletions api/envoy/config/trace/v3/opentelemetry.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";

package envoy.config.trace.v3;

import "envoy/config/core/v3/extension.proto";
import "envoy/config/core/v3/grpc_service.proto";

import "udpa/annotations/status.proto";
Expand All @@ -25,4 +26,8 @@ message OpenTelemetryConfig {
// The name for the service. This will be populated in the ResourceSpan Resource attributes.
// If it is not provided, it will default to "unknown_service:envoy".
string service_name = 2;

// optional sampler which is used in the opentelemetry tracer
// [#extension-category: envoy.tracers.opentelemetry.samplers]
core.v3.TypedExtensionConfig sampler = 3;
}
9 changes: 9 additions & 0 deletions api/envoy/extensions/tracers/opentelemetry/samplers/v3/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.

load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")

licenses(["notice"]) # Apache 2

api_proto_package(
deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
syntax = "proto3";

package envoy.extensions.tracers.opentelemetry.samplers.v3;

import "udpa/annotations/status.proto";

option java_package = "io.envoyproxy.envoy.extensions.tracers.opentelemetry.samplers.v3";
option java_outer_classname = "AlwaysOnSamplerProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/tracers/opentelemetry/samplers/v3;samplersv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Always On Sampler config]
// [#extension: envoy.tracers.opentelemetry.samplers.always_on]

message AlwaysOnSamplerConfig {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
syntax = "proto3";

package envoy.extensions.tracers.opentelemetry.samplers.v3;

import "udpa/annotations/status.proto";

option java_package = "io.envoyproxy.envoy.extensions.tracers.opentelemetry.samplers.v3";
option java_outer_classname = "DynatraceSamplerProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/tracers/opentelemetry/samplers/v3;samplersv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Always On Sampler config]
// [#extension: envoy.tracers.opentelemetry.samplers.dynatrace]

message DynatraceSamplerConfig {
string tenant_id = 1;

string cluster_id = 2;
}
1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ proto_library(
"//envoy/extensions/stat_sinks/graphite_statsd/v3:pkg",
"//envoy/extensions/stat_sinks/open_telemetry/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
"//envoy/extensions/tracers/opentelemetry/samplers/v3:pkg",
"//envoy/extensions/transport_sockets/alts/v3:pkg",
"//envoy/extensions/transport_sockets/http_11_proxy/v3:pkg",
"//envoy/extensions/transport_sockets/internal_upstream/v3:pkg",
Expand Down
10 changes: 10 additions & 0 deletions docs/root/api-v3/config/trace/opentelemetry/samplers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
OpenTelemetry Samplers
======================

Samplers that can be configured with the OpenTelemetry Tracer:

.. toctree::
:glob:
:maxdepth: 3

../../../extensions/tracers/opentelemetry/samplers/v3/*
1 change: 1 addition & 0 deletions docs/root/api-v3/config/trace/trace.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ HTTP tracers
:maxdepth: 2

v3/*
opentelemetry/samplers
7 changes: 7 additions & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,13 @@ EXTENSIONS = {
"envoy.tracers.skywalking": "//source/extensions/tracers/skywalking:config",
"envoy.tracers.opentelemetry": "//source/extensions/tracers/opentelemetry:config",

#
# Sampler
#

"envoy.tracers.opentelemetry.samplers.always_on": "//source/extensions/tracers/opentelemetry/samplers/always_on:config",
"envoy.tracers.opentelemetry.samplers.dynatrace": "//source/extensions/tracers/opentelemetry/samplers/dynatrace:config",

#
# Transport sockets
#
Expand Down
14 changes: 14 additions & 0 deletions source/extensions/extensions_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,20 @@ envoy.tracers.opentelemetry:
status: wip
type_urls:
- envoy.config.trace.v3.OpenTelemetryConfig
envoy.tracers.opentelemetry.samplers.always_on:
categories:
- envoy.tracers.opentelemetry.samplers
security_posture: unknown
status: wip
type_urls:
- envoy.extensions.tracers.opentelemetry.samplers.v3.AlwaysOnSamplerConfig
envoy.tracers.opentelemetry.samplers.dynatrace:
categories:
- envoy.tracers.opentelemetry.samplers
security_posture: unknown
status: wip
type_urls:
- envoy.extensions.tracers.opentelemetry.samplers.v3.DynatraceSamplerConfig
envoy.tracers.skywalking:
categories:
- envoy.tracers
Expand Down
1 change: 1 addition & 0 deletions source/extensions/tracers/opentelemetry/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ envoy_cc_library(
"//source/common/config:utility_lib",
"//source/common/tracing:http_tracer_lib",
"//source/extensions/tracers/common:factory_base_lib",
"//source/extensions/tracers/opentelemetry/samplers:sampler_lib",
"@envoy_api//envoy/config/trace/v3:pkg_cc_proto",
"@opentelemetry_proto//:trace_cc_proto",
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "source/extensions/tracers/opentelemetry/opentelemetry_tracer_impl.h"

#include <memory>
#include <string>

#include "envoy/config/trace/v3/opentelemetry.pb.h"
Expand Down Expand Up @@ -27,37 +28,51 @@ Driver::Driver(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetr
POOL_COUNTER_PREFIX(context.serverFactoryContext().scope(), "tracing.opentelemetry"))} {
auto& factory_context = context.serverFactoryContext();
// Create the tracer in Thread Local Storage.
tls_slot_ptr_->set([opentelemetry_config, &factory_context, this](Event::Dispatcher& dispatcher) {
OpenTelemetryGrpcTraceExporterPtr exporter;
if (opentelemetry_config.has_grpc_service()) {
Grpc::AsyncClientFactoryPtr&& factory =
factory_context.clusterManager().grpcAsyncClientManager().factoryForGrpcService(
opentelemetry_config.grpc_service(), factory_context.scope(), true);
const Grpc::RawAsyncClientSharedPtr& async_client_shared_ptr =
factory->createUncachedRawAsyncClient();
exporter = std::make_unique<OpenTelemetryGrpcTraceExporter>(async_client_shared_ptr);

SamplerPtr sampler;
if (opentelemetry_config.has_sampler()) {
auto sampler_config = opentelemetry_config.sampler();
auto* factory = Envoy::Config::Utility::getFactory<SamplerFactory>(sampler_config);
if (!factory) {
throw EnvoyException(fmt::format("Sampler factory not found: '{}'", sampler_config.name()));
}
TracerPtr tracer = std::make_unique<Tracer>(
std::move(exporter), factory_context.timeSource(), factory_context.api().randomGenerator(),
factory_context.runtime(), dispatcher, tracing_stats_, opentelemetry_config.service_name());
sampler = factory->createSampler(sampler_config.typed_config(), context);
}

tls_slot_ptr_->set(
[opentelemetry_config, &factory_context, this, sampler](Event::Dispatcher& dispatcher) {
OpenTelemetryGrpcTraceExporterPtr exporter;
if (opentelemetry_config.has_grpc_service()) {
Grpc::AsyncClientFactoryPtr&& factory =
factory_context.clusterManager().grpcAsyncClientManager().factoryForGrpcService(
opentelemetry_config.grpc_service(), factory_context.scope(), true);
const Grpc::RawAsyncClientSharedPtr& async_client_shared_ptr =
factory->createUncachedRawAsyncClient();
exporter = std::make_unique<OpenTelemetryGrpcTraceExporter>(async_client_shared_ptr);
}

return std::make_shared<TlsTracer>(std::move(tracer));
});
TracerPtr tracer = std::make_unique<Tracer>(
std::move(exporter), factory_context.timeSource(),
factory_context.api().randomGenerator(), factory_context.runtime(), dispatcher,
tracing_stats_, opentelemetry_config.service_name(), sampler);

return std::make_shared<TlsTracer>(std::move(tracer));
});
}

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) {

// Get tracer from TLS and start span.
auto& tracer = tls_slot_ptr_->getTyped<Driver::TlsTracer>().tracer();
SpanContextExtractor extractor(trace_context);
if (!extractor.propagationHeaderPresent()) {
// No propagation header, so we can create a fresh span with the given decision.
Tracing::SpanPtr new_open_telemetry_span =
tracer.startSpan(config, operation_name, stream_info.startTime(), tracing_decision);
new_open_telemetry_span->setSampled(tracing_decision.traced);
return new_open_telemetry_span;
} else {
// Try to extract the span context. If we can't, just return a null span.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "source/extensions/tracers/opentelemetry/grpc_trace_exporter.h"
#include "source/extensions/tracers/opentelemetry/tracer.h"

#include "samplers/sampler.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
Expand Down
25 changes: 25 additions & 0 deletions source/extensions/tracers/opentelemetry/samplers/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_extension_package",
)

licenses(["notice"]) # Apache 2

envoy_extension_package()

envoy_cc_library(
name = "sampler_lib",
srcs = [
],
hdrs = [
"sampler.h",
],
deps = [
"//envoy/config:typed_config_interface",
"//envoy/server:tracer_config_interface",
"//source/common/common:logger_lib",
"//source/common/config:utility_lib",
"@opentelemetry_proto//:trace_cc_proto",
],
)
33 changes: 33 additions & 0 deletions source/extensions/tracers/opentelemetry/samplers/always_on/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
load(
"//bazel:envoy_build_system.bzl",
"envoy_cc_extension",
"envoy_cc_library",
"envoy_extension_package",
)

licenses(["notice"]) # Apache 2

envoy_extension_package()

envoy_cc_extension(
name = "config",
srcs = ["config.cc"],
hdrs = ["config.h"],
deps = [
":always_on_sampler_lib",
"//envoy/registry",
"//source/common/config:utility_lib",
"@envoy_api//envoy/extensions/tracers/opentelemetry/samplers/v3:pkg_cc_proto",
],
)

envoy_cc_library(
name = "always_on_sampler_lib",
srcs = ["always_on_sampler.cc"],
hdrs = ["always_on_sampler.h"],
deps = [
"//source/common/config:datasource_lib",
"//source/extensions/tracers/opentelemetry:opentelemetry_tracer_lib",
"//source/extensions/tracers/opentelemetry/samplers:sampler_lib",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "always_on_sampler.h"

#include <memory>
#include <sstream>
#include <string>

#include "source/common/config/datasource.h"
#include "source/extensions/tracers/opentelemetry/samplers/sampler.h"
#include "source/extensions/tracers/opentelemetry/span_context.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace OpenTelemetry {

SamplingResult
AlwaysOnSampler::shouldSample(const absl::StatusOr<SpanContext>& parent_context,
const std::string& /*trace_id*/, const std::string& /*name*/,
::opentelemetry::proto::trace::v1::Span::SpanKind /*spankind*/,
const std::map<std::string, std::string>& /*attributes*/,
const std::set<SpanContext> /*links*/) {
SamplingResult result;
result.decision = Decision::RECORD_AND_SAMPLE;
if (parent_context.ok()) {
result.tracestate = parent_context.value().tracestate();
}
return result;
}

std::string AlwaysOnSampler::getDescription() const { return "AlwaysOnSampler"; }

} // namespace OpenTelemetry
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include "envoy/server/factory_context.h"

#include "source/common/common/logger.h"
#include "source/common/config/datasource.h"
#include "source/extensions/tracers/opentelemetry/samplers/sampler.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace OpenTelemetry {

/**
* @brief A sampler which samples every span
* variable.
*
*/
class AlwaysOnSampler : public Sampler, Logger::Loggable<Logger::Id::tracing> {
public:
explicit AlwaysOnSampler(const Protobuf::Message& /*config*/) {}
SamplingResult shouldSample(const absl::StatusOr<SpanContext>& parent_context,
const std::string& trace_id, const std::string& name,
::opentelemetry::proto::trace::v1::Span::SpanKind spankind,
const std::map<std::string, std::string>& attributes,
const std::set<SpanContext> links) override;
std::string getDescription() const override;

private:
};

} // namespace OpenTelemetry
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "config.h"

#include "envoy/server/tracer_config.h"

#include "source/common/config/utility.h"

#include "always_on_sampler.h"

namespace Envoy {
namespace Extensions {
namespace Tracers {
namespace OpenTelemetry {

SamplerPtr
AlwaysOnSamplerFactory::createSampler(const Protobuf::Message& config,
Server::Configuration::TracerFactoryContext& context) {
(void)context;
return std::make_shared<AlwaysOnSampler>(config);
}

/**
* Static registration for the Env sampler factory. @see RegisterFactory.
*/
REGISTER_FACTORY(AlwaysOnSamplerFactory, SamplerFactory);

} // namespace OpenTelemetry
} // namespace Tracers
} // namespace Extensions
} // namespace Envoy
Loading