Skip to content

Commit

Permalink
tracing: add baggage methods to Tracing::Span (#12260)
Browse files Browse the repository at this point in the history
* WIP add some header info on baggage

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* messing w/ stuff

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* get a compiling solution

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* lint

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* format again

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* formatting

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* change the test slightly

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* s/std::string/string_view

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add note about baggage and child/parent spans

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add in test for OpenTracingDriverTest

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add in test for OpenCensus

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add in baggage test for xray

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add in zipkin tests

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add in http tracer impl test

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* fix test for nulltracer

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* Add additional TODO for zipkin impl and add in comments for tests

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* add in draft docs

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* fix doc link

Signed-off-by: Matthew Grossman <matthewryangrossman@gmail.com>

* Inline empty methods per mklein's nit

Signed-off-by: Jake Kaufman <jkaufman@lyft.com>

Co-authored-by: Jake Kaufman <jkaufman@lyft.com>
  • Loading branch information
matthewgrossman and theevocater authored Aug 11, 2020
1 parent 89b594e commit 9ad7d4c
Show file tree
Hide file tree
Showing 16 changed files with 109 additions and 0 deletions.
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) {}
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"));
}

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 @@ -689,6 +689,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

0 comments on commit 9ad7d4c

Please sign in to comment.