Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -307,6 +307,7 @@ proto_library(
"//envoy/extensions/stat_sinks/open_telemetry/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
"//envoy/extensions/tracers/opentelemetry/resource_detectors/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
9 changes: 9 additions & 0 deletions api/envoy/config/trace/v3/opentelemetry.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;

// Configuration for the OpenTelemetry tracer.
// [#extension: envoy.tracers.opentelemetry]
// [#next-free-field: 6]
message OpenTelemetryConfig {
// The upstream gRPC cluster that will receive OTLP traces.
// Note that the tracer drops traces if the server does not read data fast enough.
Expand Down Expand Up @@ -48,4 +49,12 @@ message OpenTelemetryConfig {
// An ordered list of resource detectors
// [#extension-category: envoy.tracers.opentelemetry.resource_detectors]
repeated core.v3.TypedExtensionConfig resource_detectors = 4;

// Specifies the sampler to be used by the OpenTelemetry tracer.
// The configured sampler implements the Sampler interface defined by the OpenTelemetry specification.
// This field can be left empty. In this case, the default Envoy sampling decision is used.
//
// See: `OpenTelemetry sampler specification <https://opentelemetry.io/docs/specs/otel/trace/sdk/#sampler>`_
// [#extension-category: envoy.tracers.opentelemetry.samplers]
core.v3.TypedExtensionConfig sampler = 5;
}
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,23 @@
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]
// Configuration for the "AlwaysOn" Sampler extension.
// The sampler follows the "AlwaysOn" implementation from the OpenTelemetry
// SDK specification.
//
// See:
// `AlwaysOn sampler specification <https://opentelemetry.io/docs/specs/otel/trace/sdk/#alwayson>`_
// [#extension: envoy.tracers.opentelemetry.samplers.always_on]

message AlwaysOnSamplerConfig {
}
1 change: 1 addition & 0 deletions api/versioning/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ proto_library(
"//envoy/extensions/stat_sinks/open_telemetry/v3:pkg",
"//envoy/extensions/stat_sinks/wasm/v3:pkg",
"//envoy/extensions/tracers/opentelemetry/resource_detectors/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
3 changes: 3 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,8 @@ new_features:
- area: tracing
change: |
Added support for configuring resource detectors on the OpenTelemetry tracer.
- area: tracing
change: |
Added support to configure a sampler for the OpenTelemetry tracer.

deprecated:
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 @@ -13,3 +13,4 @@ HTTP tracers

v3/*
opentelemetry/resource_detectors
opentelemetry/samplers
6 changes: 6 additions & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ EXTENSIONS = {

"envoy.tracers.opentelemetry.resource_detectors.environment": "//source/extensions/tracers/opentelemetry/resource_detectors/environment:config",

#
# OpenTelemetry tracer samplers
#

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

#
# Transport sockets
#
Expand Down
7 changes: 7 additions & 0 deletions source/extensions/extensions_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,13 @@ 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.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 @@ -42,6 +42,7 @@ envoy_cc_library(
"//source/common/tracing:http_tracer_lib",
"//source/extensions/tracers/common:factory_base_lib",
"//source/extensions/tracers/opentelemetry/resource_detectors:resource_detector_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
Expand Up @@ -12,6 +12,7 @@
#include "source/extensions/tracers/opentelemetry/http_trace_exporter.h"
#include "source/extensions/tracers/opentelemetry/resource_detectors/resource_detector.h"
#include "source/extensions/tracers/opentelemetry/resource_detectors/resource_provider.h"
#include "source/extensions/tracers/opentelemetry/samplers/sampler.h"
#include "source/extensions/tracers/opentelemetry/span_context.h"
#include "source/extensions/tracers/opentelemetry/span_context_extractor.h"
#include "source/extensions/tracers/opentelemetry/trace_exporter.h"
Expand All @@ -25,6 +26,25 @@ namespace Extensions {
namespace Tracers {
namespace OpenTelemetry {

namespace {

SamplerSharedPtr
tryCreateSamper(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetry_config,
Server::Configuration::TracerFactoryContext& context) {
SamplerSharedPtr 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()));
}
sampler = factory->createSampler(sampler_config.typed_config(), context);
}
return sampler;
}

} // namespace

Driver::Driver(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetry_config,
Server::Configuration::TracerFactoryContext& context)
: Driver(opentelemetry_config, context, ResourceProviderImpl{}) {}
Expand All @@ -46,9 +66,12 @@ Driver::Driver(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetr
"OpenTelemetry tracer will be disabled.");
}

// Create the sampler if configured
SamplerSharedPtr sampler = tryCreateSamper(opentelemetry_config, context);

// Create the tracer in Thread Local Storage.
tls_slot_ptr_->set([opentelemetry_config, &factory_context, this,
resource_ptr](Event::Dispatcher& dispatcher) {
tls_slot_ptr_->set([opentelemetry_config, &factory_context, this, resource_ptr,
sampler](Event::Dispatcher& dispatcher) {
OpenTelemetryTraceExporterPtr exporter;
if (opentelemetry_config.has_grpc_service()) {
Grpc::AsyncClientFactoryPtr&& factory =
Expand All @@ -63,8 +86,7 @@ Driver::Driver(const envoy::config::trace::v3::OpenTelemetryConfig& opentelemetr
}
TracerPtr tracer = std::make_unique<Tracer>(
std::move(exporter), factory_context.timeSource(), factory_context.api().randomGenerator(),
factory_context.runtime(), dispatcher, tracing_stats_, resource_ptr);

factory_context.runtime(), dispatcher, tracing_stats_, resource_ptr, sampler);
return std::make_shared<TlsTracer>(std::move(tracer));
});
}
Expand All @@ -81,7 +103,6 @@ Tracing::SpanPtr Driver::startSpan(const Tracing::Config& config,
// 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
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",
],
)
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,34 @@
#include "source/extensions/tracers/opentelemetry/samplers/always_on/always_on_sampler.h"

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

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

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

SamplingResult
AlwaysOnSampler::shouldSample(const absl::optional<SpanContext> parent_context,
const std::string& /*trace_id*/, const std::string& /*name*/,
::opentelemetry::proto::trace::v1::Span::SpanKind /*kind*/,
const std::map<std::string, std::string>& /*attributes*/,
const std::vector<SpanContext>& /*links*/) {
SamplingResult result;
result.decision = Decision::RECORD_AND_SAMPLE;
if (parent_context.has_value()) {
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,38 @@
#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.
* https://opentelemetry.io/docs/specs/otel/trace/sdk/#alwayson
* - Returns RECORD_AND_SAMPLE always.
* - Description MUST be AlwaysOnSampler.
*
*/
class AlwaysOnSampler : public Sampler, Logger::Loggable<Logger::Id::tracing> {
public:
explicit AlwaysOnSampler(const Protobuf::Message& /*config*/,
Server::Configuration::TracerFactoryContext& /*context*/) {}
SamplingResult shouldSample(const absl::optional<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::vector<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,27 @@
#include "source/extensions/tracers/opentelemetry/samplers/always_on/config.h"

#include "envoy/server/tracer_config.h"

#include "source/common/config/utility.h"
#include "source/extensions/tracers/opentelemetry/samplers/always_on/always_on_sampler.h"

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

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

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

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