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
3 changes: 0 additions & 3 deletions envoy/tracing/trace_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,6 @@ class TraceContext {
*/
virtual void remove(absl::string_view key) PURE;

private:
friend class TraceContextHandler;

/**
* Optional HTTP request headers map. This is valid for HTTP protocol or any protocol that
* that provides HTTP request headers.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,18 @@ SamplingResult CELSampler::shouldSample(const StreamInfo::StreamInfo& stream_inf
const absl::optional<SpanContext> parent_context,
const std::string& /*trace_id*/,
const std::string& /*name*/, OTelSpanKind /*kind*/,
OptRef<const Tracing::TraceContext>,
OptRef<const Tracing::TraceContext> trace_context,
const std::vector<SpanContext>& /*links*/) {

Protobuf::Arena arena;
auto eval_status = Expr::evaluate(*compiled_expr_, arena, &local_info_, stream_info,
nullptr /* request_headers */, nullptr /* response_headers */,
nullptr /* response_trailers */);
const ::Envoy::Http::RequestHeaderMap* request_headers = nullptr;
if (trace_context.has_value() && trace_context->requestHeaders().has_value()) {
request_headers = trace_context->requestHeaders().ptr();
}

auto eval_status = Expr::evaluate(
*compiled_expr_, arena, &local_info_, stream_info, request_headers /* request_headers */,
nullptr /* response_headers */, nullptr /* response_trailers */);
SamplingResult result;
if (!eval_status.has_value() || eval_status.value().IsError()) {
result.decision = Decision::Drop;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,58 @@ TEST_F(CELSamplerTest, TestEval) {
"envoy.tracers.opentelemetry.samplers.cel");
sampler_ = factory->createSampler(typed_config.typed_config(), context_);

Tracing::TestTraceContextImpl request_headers{
{":authority", "test.com"}, {":path", "/"}, {":method", "GET"}};
Http::TestRequestHeaderMapImpl request_headers = {
{":authority", "test.com"}, {":path", "/test-path"}, {":method", "GET"}};
Tracing::TestRequestHeaderTraceContextImpl trace_context{request_headers};

SpanContext span_context("0", "12345", "45678", false, "some_tracestate");
auto sampling_result = sampler_->shouldSample(
stream_info_, span_context, "operation_name", "12345",
::opentelemetry::proto::trace::v1::Span::SPAN_KIND_SERVER, request_headers, {});
::opentelemetry::proto::trace::v1::Span::SPAN_KIND_SERVER, trace_context, {});
EXPECT_EQ(sampling_result.decision, Decision::Drop);
EXPECT_EQ(sampling_result.attributes, nullptr);
EXPECT_STREQ(sampling_result.tracestate.c_str(), "");
EXPECT_FALSE(sampling_result.isRecording());
EXPECT_FALSE(sampling_result.isSampled());
}

TEST_F(CELSamplerTest, TestEvalFail) {
envoy::config::core::v3::TypedExtensionConfig typed_config;
const std::string yaml = R"EOF(
name: envoy.tracers.opentelemetry.samplers.cel
typed_config:
"@type": type.googleapis.com/envoy.extensions.tracers.opentelemetry.samplers.v3.CELSamplerConfig
expression:
cel_expr_parsed:
expr:
id: 3
call_expr:
function: _==_
args:
- id: 2
select_expr:
operand:
id: 1
ident_expr:
name: req
field: path
- id: 4
const_expr:
string_value: "/test-1234-deny"
)EOF";
TestUtility::loadFromYaml(yaml, typed_config);
auto* factory = Registry::FactoryRegistry<SamplerFactory>::getFactory(
"envoy.tracers.opentelemetry.samplers.cel");
sampler_ = factory->createSampler(typed_config.typed_config(), context_);

Http::TestRequestHeaderMapImpl request_headers = {
{":authority", "test.com"}, {":path", "/test-path"}, {":method", "GET"}};
Tracing::TestRequestHeaderTraceContextImpl trace_context{request_headers};

SpanContext span_context("0", "12345", "45678", false, "some_tracestate");
auto sampling_result = sampler_->shouldSample(
stream_info_, span_context, "operation_name", "12345",
::opentelemetry::proto::trace::v1::Span::SPAN_KIND_SERVER, trace_context, {});
EXPECT_EQ(sampling_result.decision, Decision::Drop);
EXPECT_EQ(sampling_result.attributes, nullptr);
EXPECT_STREQ(sampling_result.tracestate.c_str(), "");
Expand Down Expand Up @@ -179,6 +224,50 @@ TEST_F(CELSamplerTest, TestDecisionDrop) {
EXPECT_FALSE(sampling_result.isSampled());
}

TEST_F(CELSamplerTest, TestHeader) {
envoy::config::core::v3::TypedExtensionConfig typed_config;
const std::string yaml = R"EOF(
name: envoy.tracers.opentelemetry.samplers.cel
typed_config:
"@type": type.googleapis.com/envoy.extensions.tracers.opentelemetry.samplers.v3.CELSamplerConfig
expression:
cel_expr_parsed:
expr:
id: 3
call_expr:
function: _==_
args:
- id: 2
select_expr:
operand:
id: 1
ident_expr:
name: request
field: path
- id: 4
const_expr:
string_value: "/test-path"
)EOF";
TestUtility::loadFromYaml(yaml, typed_config);
auto* factory = Registry::FactoryRegistry<SamplerFactory>::getFactory(
"envoy.tracers.opentelemetry.samplers.cel");
sampler_ = factory->createSampler(typed_config.typed_config(), context_);

Http::TestRequestHeaderMapImpl request_headers = {
{":authority", "test.com"}, {":path", "/test-path"}, {":method", "GET"}};
Tracing::TestRequestHeaderTraceContextImpl trace_context{request_headers};

SpanContext span_context("0", "12345", "45678", false, "some_tracestate");
auto sampling_result = sampler_->shouldSample(
stream_info_, span_context, "operation_name", "12345",
::opentelemetry::proto::trace::v1::Span::SPAN_KIND_SERVER, trace_context, {});
EXPECT_EQ(sampling_result.decision, Decision::RecordAndSample);
EXPECT_EQ(sampling_result.attributes, nullptr);
EXPECT_STREQ(sampling_result.tracestate.c_str(), "some_tracestate");
EXPECT_TRUE(sampling_result.isRecording());
EXPECT_TRUE(sampling_result.isSampled());
}

} // namespace OpenTelemetry
} // namespace Tracers
} // namespace Extensions
Expand Down
33 changes: 33 additions & 0 deletions test/test_common/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,39 @@ class TestTraceContextImpl : public Tracing::TraceContext {
absl::flat_hash_map<std::string, std::string> context_map_;
};

class TestRequestHeaderTraceContextImpl : public Tracing::TraceContext {
public:
TestRequestHeaderTraceContextImpl(Http::RequestHeaderMap& request_headers)
: request_headers_(request_headers) {}

absl::string_view protocol() const override { return request_headers_.getProtocolValue(); }
absl::string_view host() const override { return request_headers_.getHostValue(); }
absl::string_view path() const override { return request_headers_.getPathValue(); }
absl::string_view method() const override { return request_headers_.getMethodValue(); }
void forEach(IterateCallback callback) const override {
request_headers_.iterate([cb = std::move(callback)](const Http::HeaderEntry& entry) {
if (cb(entry.key().getStringView(), entry.value().getStringView())) {
return Http::HeaderMap::Iterate::Continue;
}
return Http::HeaderMap::Iterate::Break;
});
}
absl::optional<absl::string_view> get(absl::string_view key) const override {
Http::LowerCaseString lower_key{std::string(key)};
const auto entry = request_headers_.get(lower_key);
if (!entry.empty()) {
return entry[0]->value().getStringView();
}
return absl::nullopt;
}
void set(absl::string_view, absl::string_view) override {}
void remove(absl::string_view) override {}
OptRef<const Http::RequestHeaderMap> requestHeaders() const override { return request_headers_; };
OptRef<Http::RequestHeaderMap> requestHeaders() override { return request_headers_; };

Http::RequestHeaderMap& request_headers_;
};

} // namespace Tracing

namespace Http {
Expand Down
Loading