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

tracing: add baggage methods to Tracing::Span #12260

Merged
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
14 changes: 14 additions & 0 deletions docs/root/intro/arch_overview/observability/tracing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,17 @@ request ID :ref:`config_http_conn_man_headers_x-request-id` (LightStep) or
the trace ID configuration (Zipkin and Datadog). See
:ref:`v3 API reference <envoy_v3_api_msg_config.trace.v3.Tracing>`
for more information on how to setup tracing in Envoy.

Baggage
-----------------------------
Baggage provides a mechanism for data to be available throughout the entirety of a trace.
While metadata such as tags are usually communicated to collectors out-of-band, baggage data is injected into the actual
request context and available to applications during the duration of the request. This enables metadata to transparently
travel from the beginning of the request throughout your entire mesh without relying on application-specific modifications for
propagation. See `OpenTracing's documentation <https://opentracing.io/docs/overview/tags-logs-baggage/>`_ for more information about baggage.

Tracing providers have varying level of support for getting and setting baggage:

* Lightstep (and any OpenTracing-compliant tracer) can read/write baggage
* Zipkin support is not yet implemented
* X-Ray and OpenCensus don't support baggage
16 changes: 16 additions & 0 deletions include/envoy/tracing/http_tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,22 @@ class Span {
* @param sampled whether the span and any subsequent child spans should be sampled
*/
virtual void setSampled(bool sampled) PURE;

/**
* Retrieve a key's value from the span's baggage.
* This baggage data could've been set by this span or any parent spans.
* @param key baggage key
* @return the baggage's value for the given input key
*/
virtual std::string getBaggage(absl::string_view key) PURE;

/**
* Set a key/value pair in the current span's baggage.
* All subsequent child spans will have access to this baggage.
* @param key baggage key
* @param key baggage value
*/
virtual void setBaggage(absl::string_view key, absl::string_view value) PURE;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions source/common/tracing/http_tracer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class NullSpan : public Span {
void log(SystemTime, const std::string&) override {}
void finishSpan() override {}
void injectContext(Http::RequestHeaderMap&) override {}
void setBaggage(absl::string_view, absl::string_view) override {}
std::string getBaggage(absl::string_view) override { return std::string(); }
SpanPtr spawnChild(const Config&, const std::string&, SystemTime) override {
return SpanPtr{new NullSpan()};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ void OpenTracingSpan::log(SystemTime timestamp, const std::string& event) {
finish_options_.log_records.emplace_back(std::move(record));
}

void OpenTracingSpan::setBaggage(absl::string_view key, absl::string_view value) {
span_->SetBaggageItem({key.data(), key.length()}, {value.data(), value.length()});
}

std::string OpenTracingSpan::getBaggage(absl::string_view key) {
return span_->BaggageItem({key.data(), key.length()});
}

void OpenTracingSpan::injectContext(Http::RequestHeaderMap& request_headers) {
if (driver_.propagationMode() == OpenTracingDriver::PropagationMode::SingleHeader) {
// Inject the span context using Envoy's single-header format.
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/tracers/common/ot/opentracing_driver_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class OpenTracingSpan : public Tracing::Span, Logger::Loggable<Logger::Id::traci
Tracing::SpanPtr spawnChild(const Tracing::Config& config, const std::string& name,
SystemTime start_time) override;
void setSampled(bool) override;
std::string getBaggage(absl::string_view key) override;
void setBaggage(absl::string_view key, absl::string_view value) override;

private:
OpenTracingDriver& driver_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ class Span : public Tracing::Span {
SystemTime start_time) override;
void setSampled(bool sampled) override;

// OpenCensus doesn't support baggage, so noop these OpenTracing functions.
void setBaggage(absl::string_view, absl::string_view) override{};
std::string getBaggage(absl::string_view) override { return std::string(); };

private:
::opencensus::trace::Span span_;
const envoy::config::trace::v3::OpenCensusConfig& oc_config_;
Expand Down
4 changes: 4 additions & 0 deletions source/extensions/tracers/xray/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ class Span : public Tracing::Span, Logger::Loggable<Logger::Id::config> {
*/
void log(Envoy::SystemTime, const std::string&) override {}

// X-Ray doesn't support baggage, so noop these OpenTracing functions.
void setBaggage(absl::string_view, absl::string_view) override {}
std::string getBaggage(absl::string_view) override { return std::string(); }

/**
* Creates a child span.
* In X-Ray terms this creates a sub-segment and sets its parent ID to the current span's ID.
Expand Down
4 changes: 4 additions & 0 deletions source/extensions/tracers/zipkin/zipkin_tracer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ void ZipkinSpan::log(SystemTime timestamp, const std::string& event) {
span_.log(timestamp, event);
}

// TODO(#11622): Implement baggage storage for zipkin spans
void ZipkinSpan::setBaggage(absl::string_view, absl::string_view) {}
matthewgrossman marked this conversation as resolved.
Show resolved Hide resolved
std::string ZipkinSpan::getBaggage(absl::string_view) { return std::string(); }

void ZipkinSpan::injectContext(Http::RequestHeaderMap& request_headers) {
// Set the trace-id and span-id headers properly, based on the newly-created span structure.
request_headers.setReferenceKey(ZipkinCoreConstants::get().X_B3_TRACE_ID,
Expand Down
4 changes: 4 additions & 0 deletions source/extensions/tracers/zipkin/zipkin_tracer_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class ZipkinSpan : public Tracing::Span {

void setSampled(bool sampled) override;

// TODO(#11622): Implement baggage storage for zipkin spans
void setBaggage(absl::string_view, absl::string_view) override;
std::string getBaggage(absl::string_view) override;

/**
* @return a reference to the Zipkin::Span object.
*/
Expand Down
2 changes: 2 additions & 0 deletions test/common/tracing/http_tracer_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,8 @@ TEST(HttpNullTracerTest, BasicFunctionality) {

span_ptr->setOperation("foo");
span_ptr->setTag("foo", "bar");
span_ptr->setBaggage("key", "value");
ASSERT_EQ("", span_ptr->getBaggage("baggage_key"));
span_ptr->injectContext(request_headers);

EXPECT_NE(nullptr, span_ptr->spawnChild(config, "foo", SystemTime()));
Expand Down
14 changes: 14 additions & 0 deletions test/extensions/tracers/common/ot/opentracing_driver_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,20 @@ TEST_F(OpenTracingDriverTest, FlushSpanWithLog) {
EXPECT_EQ(expected_logs, driver_->recorder().top().logs);
}

TEST_F(OpenTracingDriverTest, FlushSpanWithBaggage) {
setupValidDriver();

Tracing::SpanPtr first_span = driver_->startSpan(config_, request_headers_, operation_name_,
start_time_, {Tracing::Reason::Sampling, true});
first_span->setBaggage("abc", "123");
first_span->finishSpan();

const std::map<std::string, std::string> expected_baggage = {{"abc", "123"}};

EXPECT_EQ(1, driver_->recorder().spans().size());
EXPECT_EQ(expected_baggage, driver_->recorder().top().span_context.baggage);
}

TEST_F(OpenTracingDriverTest, TagSamplingFalseByDecision) {
setupValidDriver(OpenTracingDriver::PropagationMode::TracerNative, {});

Expand Down
11 changes: 11 additions & 0 deletions test/extensions/tracers/lightstep/lightstep_tracer_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,17 @@ TEST_F(LightStepDriverTest, SpawnChild) {
EXPECT_FALSE(base2_context.empty());
}

TEST_F(LightStepDriverTest, GetAndSetBaggage) {
setupValidDriver();
Tracing::SpanPtr span = driver_->startSpan(config_, request_headers_, operation_name_,
start_time_, {Tracing::Reason::Sampling, true});

std::string key = "key1";
std::string value = "value1";
span->setBaggage(key, value);
EXPECT_EQ(span->getBaggage(key), value);
}

} // namespace
} // namespace Lightstep
} // namespace Tracers
Expand Down
4 changes: 4 additions & 0 deletions test/extensions/tracers/opencensus/tracer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ TEST(OpenCensusTracerTest, Span) {
child->finishSpan();
span->setSampled(false); // Abandon tracer.
span->finishSpan();

// Baggage methods are a noop in opencensus and won't affect events.
span->setBaggage("baggage_key", "baggage_value");
ASSERT_EQ("", span->getBaggage("baggage_key"));
}

// Retrieve SpanData from the OpenCensus trace exporter.
Expand Down
10 changes: 10 additions & 0 deletions test/extensions/tracers/xray/tracer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ TEST_F(XRayTracerTest, NonSampledSpansNotSerialized) {
span->finishSpan();
}

TEST_F(XRayTracerTest, BaggageNotImplemented) {
Tracer tracer{"" /*span name*/, std::move(broker_), server_.timeSource()};
auto span = tracer.createNonSampledSpan();
span->setBaggage("baggage_key", "baggage_value");
span->finishSpan();

// Baggage isn't supported so getBaggage should always return empty
ASSERT_EQ("", span->getBaggage("baggage_key"));
matthewgrossman marked this conversation as resolved.
Show resolved Hide resolved
}

TEST_F(XRayTracerTest, ChildSpanHasParentInfo) {
NiceMock<Tracing::MockConfig> config;
constexpr auto expected_span_name = "Service 1";
Expand Down
8 changes: 8 additions & 0 deletions test/extensions/tracers/zipkin/zipkin_tracer_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,14 @@ TEST_F(ZipkinDriverTest, ZipkinSpanTest) {
EXPECT_FALSE(zipkin_zipkin_span4.annotations().empty());
EXPECT_EQ(timestamp_count, zipkin_zipkin_span4.annotations().back().timestamp());
EXPECT_EQ("abc", zipkin_zipkin_span4.annotations().back().value());

// ====
// Test baggage noop
// ====
Tracing::SpanPtr span5 = driver_->startSpan(config_, request_headers_, operation_name_,
start_time_, {Tracing::Reason::Sampling, true});
span5->setBaggage("baggage_key", "baggage_value");
EXPECT_EQ("", span5->getBaggage("baggage_key"));
}

TEST_F(ZipkinDriverTest, ZipkinSpanContextFromB3HeadersTest) {
Expand Down
2 changes: 2 additions & 0 deletions test/mocks/tracing/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class MockSpan : public Span {
MOCK_METHOD(void, finishSpan, ());
MOCK_METHOD(void, injectContext, (Http::RequestHeaderMap & request_headers));
MOCK_METHOD(void, setSampled, (const bool sampled));
MOCK_METHOD(void, setBaggage, (absl::string_view key, absl::string_view value));
MOCK_METHOD(std::string, getBaggage, (absl::string_view key));

SpanPtr spawnChild(const Config& config, const std::string& name,
SystemTime start_time) override {
Expand Down