-
Notifications
You must be signed in to change notification settings - Fork 423
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
Enhance existing http example to support w3c trace context propagation #727
Changes from all commits
3329490
d9772f5
2406796
e496519
f9eeb91
56aa0a6
8adedee
550bcd4
de27ebe
2fa979e
4b6a396
b0865c7
6ea9092
ddf413b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#pragma once | ||
#include <atomic> | ||
#include <string> | ||
#include "opentelemetry/ext/http/server/http_server.h" | ||
|
||
namespace | ||
{ | ||
|
||
class HttpServer : public HTTP_SERVER_NS::HttpRequestCallback | ||
{ | ||
|
||
protected: | ||
HTTP_SERVER_NS::HttpServer server_; | ||
std::string server_url_; | ||
uint16_t port_; | ||
std::atomic<bool> is_running_{false}; | ||
|
||
public: | ||
HttpServer(std::string server_name = "test_server", uint16_t port = 8800) : port_(port) | ||
{ | ||
server_.setServerName(server_name); | ||
server_.setKeepalive(false); | ||
} | ||
|
||
void AddHandler(std::string path, HTTP_SERVER_NS::HttpRequestCallback *request_handler) | ||
{ | ||
server_.addHandler(path, *request_handler); | ||
} | ||
|
||
void Start() | ||
{ | ||
if (!is_running_.exchange(true)) | ||
{ | ||
server_.addListeningPort(port_); | ||
server_.start(); | ||
} | ||
} | ||
|
||
void Stop() | ||
{ | ||
if (is_running_.exchange(false)) | ||
{ | ||
server_.stop(); | ||
} | ||
} | ||
|
||
~HttpServer() { Stop(); } | ||
}; | ||
|
||
} // namespace |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#pragma once | ||
#include "opentelemetry/exporters/ostream/span_exporter.h" | ||
#include "opentelemetry/sdk/trace/simple_processor.h" | ||
#include "opentelemetry/sdk/trace/tracer_provider.h" | ||
#include "opentelemetry/trace/provider.h" | ||
|
||
#include "opentelemetry/context/propagation/global_propagator.h" | ||
#include "opentelemetry/context/propagation/text_map_propagator.h" | ||
#include "opentelemetry/trace/propagation/http_trace_context.h" | ||
|
||
#include <cstring> | ||
#include <iostream> | ||
#include <vector> | ||
#include "opentelemetry/ext/http/client/http_client.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we can eventually generalize some of this, since the same / similar logic would be necessary for gRPC metadata. I like how it was handled in dapr examples: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we should eventually reuse part of the code for both HTTP and grpc. |
||
#include "opentelemetry/nostd/shared_ptr.h" | ||
|
||
namespace | ||
{ | ||
// TBD - This function be removed once #723 is merged | ||
inline nostd::shared_ptr<opentelemetry::trace::Span> GetSpanFromContext( | ||
const opentelemetry::context::Context &context) | ||
{ | ||
opentelemetry::context::ContextValue span = context.GetValue(opentelemetry::trace::kSpanKey); | ||
if (nostd::holds_alternative<nostd::shared_ptr<opentelemetry::trace::Span>>(span)) | ||
{ | ||
return nostd::get<nostd::shared_ptr<opentelemetry::trace::Span>>(span); | ||
} | ||
static nostd::shared_ptr<opentelemetry::trace::Span> invalid_span{ | ||
new opentelemetry::trace::DefaultSpan(opentelemetry::trace::SpanContext::GetInvalid())}; | ||
return invalid_span; | ||
} | ||
|
||
template <typename T> | ||
class HttpTextMapCarrier : public opentelemetry::context::propagation::TextMapCarrier | ||
{ | ||
public: | ||
HttpTextMapCarrier<T>(T &headers) : headers_(headers) {} | ||
HttpTextMapCarrier() = default; | ||
virtual nostd::string_view Get(nostd::string_view key) const noexcept override | ||
{ | ||
std::string key_to_compare = key.data(); | ||
// Header's first letter seems to be automatically capitaliazed by our test http-server, so | ||
// compare accordingly. | ||
if (key == opentelemetry::trace::propagation::kTraceParent) | ||
{ | ||
key_to_compare = "Traceparent"; | ||
} | ||
else if (key == opentelemetry::trace::propagation::kTraceState) | ||
{ | ||
key_to_compare == "Tracestate"; | ||
} | ||
auto it = headers_.find(key_to_compare); | ||
if (it != headers_.end()) | ||
{ | ||
return it->second; | ||
} | ||
return ""; | ||
} | ||
|
||
virtual void Set(nostd::string_view key, nostd::string_view value) noexcept override | ||
{ | ||
headers_.insert(std::pair<std::string, std::string>(std::string(key), std::string(value))); | ||
} | ||
|
||
T headers_; | ||
}; | ||
|
||
void initTracer() | ||
{ | ||
auto exporter = std::unique_ptr<sdktrace::SpanExporter>( | ||
new opentelemetry::exporter::trace::OStreamSpanExporter); | ||
auto processor = std::unique_ptr<sdktrace::SpanProcessor>( | ||
new sdktrace::SimpleSpanProcessor(std::move(exporter))); | ||
std::vector<std::unique_ptr<sdktrace::SpanProcessor>> processors; | ||
processors.push_back(std::move(processor)); | ||
// Default is an always-on sampler. | ||
auto context = std::make_shared<sdktrace::TracerContext>(std::move(processors)); | ||
auto provider = nostd::shared_ptr<opentelemetry::trace::TracerProvider>( | ||
new sdktrace::TracerProvider(context)); | ||
// Set the global trace provider | ||
opentelemetry::trace::Provider::SetTracerProvider(provider); | ||
|
||
// set global propagator | ||
opentelemetry::context::propagation::GlobalTextMapPropagator::SetGlobalPropagator( | ||
nostd::shared_ptr<opentelemetry::context::propagation::TextMapPropagator>( | ||
new opentelemetry::trace::propagation::HttpTraceContext())); | ||
} | ||
|
||
nostd::shared_ptr<opentelemetry::trace::Tracer> get_tracer(std::string tracer_name) | ||
{ | ||
auto provider = opentelemetry::trace::Provider::GetTracerProvider(); | ||
return provider->GetTracer(tracer_name); | ||
} | ||
|
||
} // namespace |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this shouldn't be strictly necessary, as
Extract
sets the span as the currently active span in the context?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pyohannes -
Extract
would return a new context with thespan
created with extractedspan_context
, and won't make it active. This is as per the specs :Returns a new Context derived from the Context passed as argument.