Skip to content

Commit bc1c094

Browse files
authored
Extract trace context from http request and connect with replicas (#2603)
* Extract trace context from http request and connect with replicas * Move trace extraction to common reusable utility
1 parent 794ce04 commit bc1c094

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

client/clientservice/src/request_service.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
#include "client/clientservice/request_service.hpp"
1616
#include "client/concordclient/concord_client.hpp"
1717
#include "concord_client_request.pb.h"
18+
#include "client/thin-replica-client/trace_contexts.hpp"
1819

20+
using namespace client::thin_replica_client;
1921
using namespace vmware::concord::client::concord_client_request::v1;
2022

2123
namespace concord::client::clientservice {
@@ -173,18 +175,21 @@ void RequestServiceCallData::sendToConcordClient() {
173175
this->populateResult(grpc::Status::OK);
174176
};
175177

178+
auto tracer = opentracing::Tracer::Global();
179+
auto parent_span = TraceContexts::ExtractSpanFromMetadata(*tracer, ctx_);
180+
176181
if (request_.read_only()) {
177182
bft::client::ReadConfig config;
178183
config.request = req_config;
179-
auto span = opentracing::Tracer::Global()->StartSpan("send_ro", {});
184+
auto span = opentracing::Tracer::Global()->StartSpan("send_ro", {opentracing::ChildOf(parent_span.get())});
180185
std::ostringstream carrier;
181186
opentracing::Tracer::Global()->Inject(span->context(), carrier);
182187
config.request.span_context = carrier.str();
183188
client_->send(config, std::move(msg), callback);
184189
} else {
185190
bft::client::WriteConfig config;
186191
config.request = req_config;
187-
auto span = opentracing::Tracer::Global()->StartSpan("send", {});
192+
auto span = opentracing::Tracer::Global()->StartSpan("send", {opentracing::ChildOf(parent_span.get())});
188193
std::ostringstream carrier;
189194
opentracing::Tracer::Global()->Inject(span->context(), carrier);
190195
config.request.span_context = carrier.str();

client/thin-replica-client/include/client/thin-replica-client/trace_contexts.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define THIN_REPLICA_CLIENT_TRACE_CONTEXTS_HPP_
1616

1717
#include <opentracing/span.h>
18+
#include <grpcpp/server.h>
1819
#include <optional>
1920

2021
#include "thin_replica.pb.h"
@@ -30,12 +31,14 @@ namespace client::thin_replica_client {
3031
class TraceContexts {
3132
public:
3233
using SpanPtr = std::unique_ptr<opentracing::Span>;
34+
using SpanCtxPtr = std::unique_ptr<opentracing::SpanContext>;
3335

3436
static void InjectSpan(const SpanPtr& span, cc::EventVariant& update);
3537
static expected<std::unique_ptr<opentracing::SpanContext>> ExtractSpan(const cc::EventVariant& update);
3638
static SpanPtr CreateChildSpanFromBinary(const std::string& trace_context,
3739
const std::string& child_name,
3840
const std::string& correlation_id = {});
41+
static SpanCtxPtr ExtractSpanFromMetadata(const opentracing::Tracer& tracer, const grpc::ServerContext& context);
3942
};
4043

4144
} // namespace client::thin_replica_client

client/thin-replica-client/src/trace_contexts.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,47 @@ SpanPtr TraceContexts::CreateChildSpanFromBinary(const std::string& trace_contex
111111
return opentracing::Tracer::Global()->StartSpan(
112112
child_name, {opentracing::FollowsFrom(&**parent_span_context), opentracing::SetTag{kCorrelationIdTag, cid}});
113113
}
114+
115+
struct GrpcMetadataCarrierForReading : opentracing::TextMapReader {
116+
GrpcMetadataCarrierForReading(const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata)
117+
: client_metadata_(client_metadata) {}
118+
119+
using F = std::function<opentracing::expected<void>(opentracing::string_view, opentracing::string_view)>;
120+
121+
opentracing::expected<void> ForeachKey(F f) const override {
122+
// Iterate through all key-value pairs, the tracer will use the relevant keys
123+
// to extract a span context.
124+
for (auto& key_value : client_metadata_) {
125+
auto was_successful = f(FromStringRef(key_value.first), FromStringRef(key_value.second));
126+
if (!was_successful) {
127+
// If the callback returns and unexpected value, bail out of the loop.
128+
return was_successful;
129+
}
130+
}
131+
// Indicate successful iteration.
132+
return {};
133+
}
134+
135+
opentracing::expected<opentracing::string_view> LookupKey(opentracing::string_view key) const override {
136+
auto find_it = client_metadata_.find(grpc::string_ref(key));
137+
if (find_it != client_metadata_.end()) {
138+
return opentracing::make_unexpected(opentracing::key_not_found_error);
139+
}
140+
return opentracing::string_view{FromStringRef(find_it->second)};
141+
}
142+
143+
private:
144+
static std::string FromStringRef(const grpc::string_ref& string_ref) {
145+
return std::string(string_ref.data(), string_ref.size());
146+
}
147+
148+
const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata_;
149+
};
150+
151+
TraceContexts::SpanCtxPtr TraceContexts::ExtractSpanFromMetadata(const opentracing::Tracer& tracer,
152+
const grpc::ServerContext& context) {
153+
GrpcMetadataCarrierForReading metadata_carrier(context.client_metadata());
154+
return *tracer.Extract(metadata_carrier);
155+
}
156+
114157
} // namespace client::thin_replica_client

0 commit comments

Comments
 (0)