Skip to content

Commit

Permalink
tracing: inject the tracing header before the upstream filter chain i…
Browse files Browse the repository at this point in the history
…s started (envoyproxy#27269)

* tracing: inject the tracing header before the upstream filter chain is started

Signed-off-by: wbpcode <[email protected]>

* fix test

Signed-off-by: wbpcode <[email protected]>

* update comment

Signed-off-by: wbpcode <[email protected]>

* update comment

Signed-off-by: wbpcode <[email protected]>

---------

Signed-off-by: wbpcode <[email protected]>
  • Loading branch information
code authored May 15, 2023
1 parent 3c84818 commit 2ede973
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
21 changes: 12 additions & 9 deletions source/common/router/upstream_request.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ UpstreamRequest::UpstreamRequest(RouterFilterInterface& parent,
}
}
}

// The router checks that the connection pool is non-null before creating the upstream request.
auto upstream_host = conn_pool_->host();
if (span_ != nullptr) {
span_->injectContext(*parent_.downstreamHeaders(), upstream_host);
} else {
// No independent child span for current upstream request then inject the parent span's tracing
// context into the request headers.
// The injectContext() of the parent span may be called repeatedly when the request is retried.
parent_.callbacks()->activeSpan().injectContext(*parent_.downstreamHeaders(), upstream_host);
}

stream_info_.setUpstreamInfo(std::make_shared<StreamInfo::UpstreamInfoImpl>());
stream_info_.route_ = parent.callbacks()->route();
parent_.callbacks()->streamInfo().setUpstreamInfo(stream_info_.upstreamInfo());
Expand Down Expand Up @@ -633,15 +645,6 @@ void UpstreamRequest::onPoolReady(std::unique_ptr<GenericUpstream>&& upstream,
route_entry->appendXfh());
}

if (span_ != nullptr) {
span_->injectContext(*parent_.downstreamHeaders(), host);
} else {
// No independent child span for current upstream request then inject the parent span's tracing
// context into the request headers.
// The injectContext() of the parent span may be called repeatedly when the request is retried.
parent_.callbacks()->activeSpan().injectContext(*parent_.downstreamHeaders(), host);
}

stream_info_.setRequestHeaders(*parent_.downstreamHeaders());

if (parent_.config().flush_upstream_log_on_upstream_stream_) {
Expand Down
29 changes: 18 additions & 11 deletions test/common/router/router_2_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -411,21 +411,23 @@ TEST_F(RouterTestChildSpan, BasicFlow) {

NiceMock<Http::MockRequestEncoder> encoder;
Http::ResponseDecoder* response_decoder = nullptr;
Tracing::MockSpan* child_span{new Tracing::MockSpan()};

EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _, _))
.WillOnce(
Invoke([&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks,
const Http::ConnectionPool::Instance::StreamOptions&)
-> Http::ConnectionPool::Cancellable* {
response_decoder = &decoder;
EXPECT_CALL(*child_span, injectContext(_, _));
callbacks.onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_,
upstream_stream_info_, Http::Protocol::Http10);
return nullptr;
}));

Http::TestRequestHeaderMapImpl headers;
HttpTestUtility::addDefaultHeaders(headers);

Tracing::MockSpan* child_span{new Tracing::MockSpan()};
EXPECT_CALL(*child_span, injectContext(_, _));
EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router observability_name egress", _))
.WillOnce(Return(child_span));
EXPECT_CALL(callbacks_, tracingConfig()).Times(2);
Expand Down Expand Up @@ -460,21 +462,23 @@ TEST_F(RouterTestChildSpan, ResetFlow) {

NiceMock<Http::MockRequestEncoder> encoder;
Http::ResponseDecoder* response_decoder = nullptr;
Tracing::MockSpan* child_span{new Tracing::MockSpan()};

EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _, _))
.WillOnce(
Invoke([&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks,
const Http::ConnectionPool::Instance::StreamOptions&)
-> Http::ConnectionPool::Cancellable* {
response_decoder = &decoder;
EXPECT_CALL(*child_span, injectContext(_, _));
callbacks.onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_,
upstream_stream_info_, Http::Protocol::Http10);
return nullptr;
}));

Http::TestRequestHeaderMapImpl headers;
HttpTestUtility::addDefaultHeaders(headers);

Tracing::MockSpan* child_span{new Tracing::MockSpan()};
EXPECT_CALL(*child_span, injectContext(_, _));
EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router observability_name egress", _))
.WillOnce(Return(child_span));
EXPECT_CALL(callbacks_, tracingConfig()).Times(2);
Expand Down Expand Up @@ -515,19 +519,20 @@ TEST_F(RouterTestChildSpan, CancelFlow) {
EXPECT_CALL(callbacks_.dispatcher_, createTimer_(_)).Times(0);

NiceMock<Http::MockRequestEncoder> encoder;
Tracing::MockSpan* child_span{new Tracing::MockSpan()};

EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _, _))
.WillOnce(Invoke([&](Http::StreamDecoder&, Http::ConnectionPool::Callbacks& callbacks,
const Http::ConnectionPool::Instance::StreamOptions&)
-> Http::ConnectionPool::Cancellable* {
EXPECT_CALL(*child_span, injectContext(_, _));
callbacks.onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_,
upstream_stream_info_, Http::Protocol::Http10);
return nullptr;
}));

Http::TestRequestHeaderMapImpl headers;
HttpTestUtility::addDefaultHeaders(headers);
Tracing::MockSpan* child_span{new Tracing::MockSpan()};
EXPECT_CALL(*child_span, injectContext(_, _));
EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router observability_name egress", _))
.WillOnce(Return(child_span));
EXPECT_CALL(callbacks_, tracingConfig()).Times(2);
Expand Down Expand Up @@ -560,14 +565,13 @@ TEST_F(RouterTestChildSpan, CancelFlow) {
TEST_F(RouterTestChildSpan, ResetRetryFlow) {
NiceMock<Http::MockRequestEncoder> encoder1;
Http::ResponseDecoder* response_decoder = nullptr;
Tracing::MockSpan* child_span_1{new Tracing::MockSpan()};

EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _, _))
.WillOnce(
Invoke([&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks,
const Http::ConnectionPool::Instance::StreamOptions&)
-> Http::ConnectionPool::Cancellable* {
response_decoder = &decoder;
EXPECT_CALL(*child_span_1, injectContext(_, _));
callbacks.onPoolReady(encoder1, cm_.thread_local_cluster_.conn_pool_.host_,
upstream_stream_info_, Http::Protocol::Http10);
return nullptr;
Expand All @@ -577,6 +581,9 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) {
// Upstream responds back to envoy simulating an upstream reset.
Http::TestRequestHeaderMapImpl headers{{"x-envoy-retry-on", "5xx"}, {"x-envoy-internal", "true"}};
HttpTestUtility::addDefaultHeaders(headers);

Tracing::MockSpan* child_span_1{new Tracing::MockSpan()};
EXPECT_CALL(*child_span_1, injectContext(_, _));
EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router observability_name egress", _))
.WillOnce(Return(child_span_1));
EXPECT_CALL(callbacks_, tracingConfig()).Times(2);
Expand Down Expand Up @@ -605,20 +612,20 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) {

// We expect this reset to kick off a new request.
NiceMock<Http::MockRequestEncoder> encoder2;
Tracing::MockSpan* child_span_2{new Tracing::MockSpan()};
EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _, _))
.WillOnce(
Invoke([&](Http::ResponseDecoder& decoder, Http::ConnectionPool::Callbacks& callbacks,
const Http::ConnectionPool::Instance::StreamOptions&)
-> Http::ConnectionPool::Cancellable* {
response_decoder = &decoder;
EXPECT_CALL(*child_span_2, injectContext(_, _));
EXPECT_CALL(*router_->retry_state_, onHostAttempted(_));
callbacks.onPoolReady(encoder2, cm_.thread_local_cluster_.conn_pool_.host_,
upstream_stream_info_, Http::Protocol::Http10);
return nullptr;
}));

Tracing::MockSpan* child_span_2{new Tracing::MockSpan()};
EXPECT_CALL(*child_span_2, injectContext(_, _));
EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router observability_name egress", _))
.WillOnce(Return(child_span_2));
EXPECT_CALL(callbacks_, tracingConfig()).Times(2);
Expand Down Expand Up @@ -665,14 +672,14 @@ TEST_F(RouterTestNoChildSpan, BasicFlow) {
const Http::ConnectionPool::Instance::StreamOptions&)
-> Http::ConnectionPool::Cancellable* {
response_decoder = &decoder;
EXPECT_CALL(callbacks_.active_span_, injectContext(_, _));
callbacks.onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_,
upstream_stream_info_, Http::Protocol::Http10);
return nullptr;
}));

Http::TestRequestHeaderMapImpl headers;
HttpTestUtility::addDefaultHeaders(headers);
EXPECT_CALL(callbacks_.active_span_, injectContext(_, _));
router_->decodeHeaders(headers, true);
EXPECT_EQ(1U,
callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
Expand Down

0 comments on commit 2ede973

Please sign in to comment.