From 374d7c4b35c2611e4943fb1d90441f559a55774a Mon Sep 17 00:00:00 2001 From: TianlinZhao Date: Thu, 30 Jul 2020 14:36:22 -0400 Subject: [PATCH] tracer workaround --- api/include/opentelemetry/trace/tracer.h | 101 +++--- .../propagation/http_text_format_test.cc | 328 +++++++++--------- 2 files changed, 220 insertions(+), 209 deletions(-) diff --git a/api/include/opentelemetry/trace/tracer.h b/api/include/opentelemetry/trace/tracer.h index 7927a2702e..6b1b07f6bb 100644 --- a/api/include/opentelemetry/trace/tracer.h +++ b/api/include/opentelemetry/trace/tracer.h @@ -28,60 +28,71 @@ class Tracer * Attributes will be processed in order, previous attributes with the same * key will be overwritten. */ - virtual nostd::unique_ptr StartSpan(nostd::string_view name, + virtual Span* StartSpan(nostd::string_view name, const KeyValueIterable &attributes, const StartSpanOptions &options = {}) noexcept = 0; - nostd::unique_ptr StartSpan(nostd::string_view name, + Span* StartSpan(nostd::string_view name, const StartSpanOptions &options = {}) noexcept { return this->StartSpan(name, {}, options); } - template ::value> * = nullptr> - nostd::unique_ptr StartSpan(nostd::string_view name, - const T &attributes, - const StartSpanOptions &options = {}) noexcept - { - return this->StartSpan(name, KeyValueIterableView(attributes), options); - } - - nostd::unique_ptr StartSpan( - nostd::string_view name, - std::initializer_list> attributes, - const StartSpanOptions &options = {}) noexcept - { - return this->StartSpan(name, - nostd::span>{ - attributes.begin(), attributes.end()}, - options); - } - - /** - * Force any buffered spans to flush. - * @param timeout to complete the flush - */ - template - void ForceFlush(std::chrono::duration timeout) noexcept - { - this->ForceFlushWithMicroseconds( - static_cast(std::chrono::duration_cast(timeout))); - } - - virtual void ForceFlushWithMicroseconds(uint64_t timeout) noexcept = 0; - - /** - * ForceFlush any buffered spans and stop reporting spans. - * @param timeout to complete the flush - */ - template - void Close(std::chrono::duration timeout) noexcept - { - this->CloseWithMicroseconds( - static_cast(std::chrono::duration_cast(timeout))); - } - virtual void CloseWithMicroseconds(uint64_t timeout) noexcept = 0; +// virtual nostd::unique_ptr StartSpan(nostd::string_view name, +// const KeyValueIterable &attributes, +// const StartSpanOptions &options = {}) noexcept = 0; +// +// nostd::unique_ptr StartSpan(nostd::string_view name, +// const StartSpanOptions &options = {}) noexcept +// { +// return this->StartSpan(name, {}, options); +// } +// +// template ::value> * = nullptr> +// nostd::unique_ptr StartSpan(nostd::string_view name, +// const T &attributes, +// const StartSpanOptions &options = {}) noexcept +// { +// return this->StartSpan(name, KeyValueIterableView(attributes), options); +// } +// +// nostd::unique_ptr StartSpan( +// nostd::string_view name, +// std::initializer_list> attributes, +// const StartSpanOptions &options = {}) noexcept +// { +// return this->StartSpan(name, +// nostd::span>{ +// attributes.begin(), attributes.end()}, +// options); +// } +// +// /** +// * Force any buffered spans to flush. +// * @param timeout to complete the flush +// */ +// template +// void ForceFlush(std::chrono::duration timeout) noexcept +// { +// this->ForceFlushWithMicroseconds( +// static_cast(std::chrono::duration_cast(timeout))); +// } +// +// virtual void ForceFlushWithMicroseconds(uint64_t timeout) noexcept = 0; +// +// /** +// * ForceFlush any buffered spans and stop reporting spans. +// * @param timeout to complete the flush +// */ +// template +// void Close(std::chrono::duration timeout) noexcept +// { +// this->CloseWithMicroseconds( +// static_cast(std::chrono::duration_cast(timeout))); +// } +// +// virtual void CloseWithMicroseconds(uint64_t timeout) noexcept = 0; }; } // namespace trace OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/api/test/trace/propagation/http_text_format_test.cc b/api/test/trace/propagation/http_text_format_test.cc index 6fbe746a32..ab699d03bb 100644 --- a/api/test/trace/propagation/http_text_format_test.cc +++ b/api/test/trace/propagation/http_text_format_test.cc @@ -14,167 +14,167 @@ #include #include -// -//#include "opentelemetry/trace/default_span.h" -//#include "opentelemetry/trace/propagation/http_text_format.h" -//#include "opentelemetry/trace/propagation/http_trace_context.h" -// -//using namespace opentelemetry; -// -//static nostd::string_view Getter(const std::map &carrier, nostd::string_view trace_type = "traceparent") { -// auto it = carrier.find(std::string(trace_type)); -// if (it != carrier.end()) { -// return nostd::string_view(it->second); -// } -// return ""; -//} -// -//static void Setter(std::map &carrier, nostd::string_view trace_type = "traceparent", nostd::string_view trace_description = "") { -// carrier[std::string(trace_type)] = std::string(trace_description); -//} -// -//static trace::propagation::HttpTraceContext> format = trace::propagation::HttpTraceContext>(); -// -//static const nostd::string_view trace_id = "12345678901234567890123456789012"; -//static const nostd::string_view span_id = "1234567890123456"; -// -//using MapHttpTraceContext = trace::propagation::HttpTraceContext>; -//TEST(HTTPTextFormatTest, TraceIdBufferGeneration) -//{ -// constexpr uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; -// EXPECT_EQ(MapHttpTraceContext::GenerateTraceIdFromString("01020304050607080807aabbccddeeff"),trace::TraceId(buf)); -//} -// -//TEST(HTTPTextFormatTest, SpanIdBufferGeneration) -//{ -// constexpr uint8_t buf[] = {1, 2, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; -// EXPECT_EQ(MapHttpTraceContext::GenerateSpanIdFromString("0102aabbccddeeff"),trace::SpanId(buf)); -//} -// -//TEST(HTTPTextFormatTest, TraceFlagsBufferGeneration) -//{ -// EXPECT_EQ(MapHttpTraceContext::GenerateTraceFlagsFromString("00"),trace::TraceFlags()); -//} -// -//TEST(HTTPTextFormatTest, HeadersWithTraceState) -//{ -// const std::map carrier = {{"traceparent","00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-01"},{"tracestate","congo=congosSecondPosition,rojo=rojosFirstPosition"}}; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter,carrier,ctx1); -// std::map c2 = {}; -// format.Inject(Setter,c2,ctx2); -// EXPECT_EQ(c2["traceparent"],"00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-01"); -// EXPECT_EQ(c2["tracestate"],"congo=congosSecondPosition,rojo=rojosFirstPosition"); -// EXPECT_EQ(carrier.size(),c2.size()); -//} -// -//TEST(HTTPTextFormatTest, NoTraceParentHeader) -//{ -// // When trace context headers are not present, a new SpanContext -// // should be created. -// const std::map carrier = {}; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter, carrier, ctx1); -// trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); -// EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); -// EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); -// EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); -// EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); -//} -// -//TEST(HTTPTextFormatTest, InvalidTraceId) -//{ -// // If the trace id is invalid, we must ignore the full trace parent header, -// // and return a random, valid trace. -// // Also ignore any trace state. -// const std::map carrier = { {"traceparent", "00-00000000000000000000000000000000-1234567890123456-00"}, -// {"tracestate", "foo=1,bar=2,foo=3"} }; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter, carrier, ctx1); -// trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); -// EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); -// EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); -// EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); -// EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); -//} -// -//TEST(HTTPTextFormatTest, InvalidParentId) -//{ -// // If the parent id is invalid, we must ignore the full trace parent -// // header. -// // Also ignore any trace state. -// const std::map carrier = { {"traceparent", "00-00000000000000000000000000000000-0000000000000000-00"}, -// {"tracestate", "foo=1,bar=2,foo=3"} }; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter, carrier, ctx1); -// trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); -// EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); -// EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); -// EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); -// EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); -//} -// -//TEST(HTTPTextFormatTest, NoSendEmptyTraceState) -//{ -// // If the trace state is empty, do not set the header. -// const std::map carrier = {{"traceparent","00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-01"}}; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter,carrier,ctx1); -// std::map c2 = {}; -// format.Inject(Setter,c2,ctx2); -// EXPECT_TRUE(carrier.count("traceparent") > 0); -// EXPECT_FALSE(carrier.count("tracestate") > 0); -//} -// -//TEST(HTTPTextFormatTest, FormatNotSupported) -//{ -// // If the trace parent does not adhere to the supported format, discard it and -// // create a new trace context. -// const std::map carrier = { {"traceparent", "00-12345678901234567890123456789012-1234567890123456-00-residue"}, -// {"tracestate", "foo=1,bar=2,foo=3"} }; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter,carrier,ctx1); -// trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); -// EXPECT_FALSE(span->GetContext().IsValid()); -// EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); -// EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); -// EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); -// EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); -//} -// -//TEST(HTTPTextFormatTest, PropagateInvalidContext) -//{ -// // Do not propagate invalid trace context. -// std::map carrier = {}; -// context::Context ctx{"current-span",nostd::shared_ptr(new trace::DefaultSpan(trace::SpanContext::GetInvalid()))}; -// format.Inject(Setter, carrier, ctx); -// EXPECT_TRUE(carrier.count("traceparent") == 0); -//} -// -//TEST(HTTPTextFormatTest, TraceStateHeaderWithTrailingComma) -//{ -// // Do not propagate invalid trace context. -// const std::map carrier = { {"traceparent", "00-12345678901234567890123456789012-1234567890123456-00"}, -// {"tracestate", "foo=1,"} }; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter,carrier,ctx1); -// trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); -// trace::TraceState trace_state = span->GetContext().trace_state(); -// EXPECT_TRUE(trace_state.Get("foo", "1")); -//} -// -//TEST(HTTPTextFormatTest, TraceStateKeys) -//{ -// // Test for valid key patterns in the tracestate -// std::string trace_state_value = "1a-2f@foo=bar1,1a-_*/2b@foo=bar2,foo=bar3,foo-_*/bar=bar4"; -// const std::map carrier = { {"traceparent", "00-12345678901234567890123456789012-1234567890123456-00"}, -// {"tracestate", trace_state_value} }; -// context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); -// context::Context ctx2 = format.Extract(Getter,carrier,ctx1); -// trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); -// trace::TraceState trace_state = span->GetContext().trace_state(); -// EXPECT_TRUE(trace_state.Get("1a-2f@foo", "bar1")); -// EXPECT_TRUE(trace_state.Get("1a-_*/2b@foo", "bar2")); -// EXPECT_TRUE(trace_state.Get("foo", "bar3")); -// EXPECT_TRUE(trace_state.Get("foo-_*/bar", "bar4")); -//} + +#include "opentelemetry/trace/default_span.h" +#include "opentelemetry/trace/propagation/http_text_format.h" +#include "opentelemetry/trace/propagation/http_trace_context.h" + +using namespace opentelemetry; + +static nostd::string_view Getter(const std::map &carrier, nostd::string_view trace_type = "traceparent") { + auto it = carrier.find(std::string(trace_type)); + if (it != carrier.end()) { + return nostd::string_view(it->second); + } + return ""; +} + +static void Setter(std::map &carrier, nostd::string_view trace_type = "traceparent", nostd::string_view trace_description = "") { + carrier[std::string(trace_type)] = std::string(trace_description); +} + +static trace::propagation::HttpTraceContext> format = trace::propagation::HttpTraceContext>(); + +static const nostd::string_view trace_id = "12345678901234567890123456789012"; +static const nostd::string_view span_id = "1234567890123456"; + +using MapHttpTraceContext = trace::propagation::HttpTraceContext>; +TEST(HTTPTextFormatTest, TraceIdBufferGeneration) +{ + constexpr uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + EXPECT_EQ(MapHttpTraceContext::GenerateTraceIdFromString("01020304050607080807aabbccddeeff"),trace::TraceId(buf)); +} + +TEST(HTTPTextFormatTest, SpanIdBufferGeneration) +{ + constexpr uint8_t buf[] = {1, 2, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; + EXPECT_EQ(MapHttpTraceContext::GenerateSpanIdFromString("0102aabbccddeeff"),trace::SpanId(buf)); +} + +TEST(HTTPTextFormatTest, TraceFlagsBufferGeneration) +{ + EXPECT_EQ(MapHttpTraceContext::GenerateTraceFlagsFromString("00"),trace::TraceFlags()); +} + +TEST(HTTPTextFormatTest, HeadersWithTraceState) +{ + const std::map carrier = {{"traceparent","00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-01"},{"tracestate","congo=congosSecondPosition,rojo=rojosFirstPosition"}}; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter,carrier,ctx1); + std::map c2 = {}; + format.Inject(Setter,c2,ctx2); + EXPECT_EQ(c2["traceparent"],"00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-01"); + EXPECT_EQ(c2["tracestate"],"congo=congosSecondPosition,rojo=rojosFirstPosition"); + EXPECT_EQ(carrier.size(),c2.size()); +} + +TEST(HTTPTextFormatTest, NoTraceParentHeader) +{ + // When trace context headers are not present, a new SpanContext + // should be created. + const std::map carrier = {}; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter, carrier, ctx1); + trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); + EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); + EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); + EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); + EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); +} + +TEST(HTTPTextFormatTest, InvalidTraceId) +{ + // If the trace id is invalid, we must ignore the full trace parent header, + // and return a random, valid trace. + // Also ignore any trace state. + const std::map carrier = { {"traceparent", "00-00000000000000000000000000000000-1234567890123456-00"}, + {"tracestate", "foo=1,bar=2,foo=3"} }; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter, carrier, ctx1); + trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); + EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); + EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); + EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); + EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); +} + +TEST(HTTPTextFormatTest, InvalidParentId) +{ + // If the parent id is invalid, we must ignore the full trace parent + // header. + // Also ignore any trace state. + const std::map carrier = { {"traceparent", "00-00000000000000000000000000000000-0000000000000000-00"}, + {"tracestate", "foo=1,bar=2,foo=3"} }; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter, carrier, ctx1); + trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); + EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); + EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); + EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); + EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); +} + +TEST(HTTPTextFormatTest, NoSendEmptyTraceState) +{ + // If the trace state is empty, do not set the header. + const std::map carrier = {{"traceparent","00-4bf92f3577b34da6a3ce929d0e0e4736-0102030405060708-01"}}; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter,carrier,ctx1); + std::map c2 = {}; + format.Inject(Setter,c2,ctx2); + EXPECT_TRUE(carrier.count("traceparent") > 0); + EXPECT_FALSE(carrier.count("tracestate") > 0); +} + +TEST(HTTPTextFormatTest, FormatNotSupported) +{ + // If the trace parent does not adhere to the supported format, discard it and + // create a new trace context. + const std::map carrier = { {"traceparent", "00-12345678901234567890123456789012-1234567890123456-00-residue"}, + {"tracestate", "foo=1,bar=2,foo=3"} }; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter,carrier,ctx1); + trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); + EXPECT_FALSE(span->GetContext().IsValid()); + EXPECT_EQ(span->GetContext().trace_id(),trace::SpanContext().trace_id()); + EXPECT_EQ(span->GetContext().span_id(),trace::SpanContext().span_id()); + EXPECT_EQ(span->GetContext().trace_flags(),trace::SpanContext().trace_flags()); + EXPECT_EQ(span->GetContext().trace_state(),trace::SpanContext().trace_state()); +} + +TEST(HTTPTextFormatTest, PropagateInvalidContext) +{ + // Do not propagate invalid trace context. + std::map carrier = {}; + context::Context ctx{"current-span",nostd::shared_ptr(new trace::DefaultSpan(trace::SpanContext::GetInvalid()))}; + format.Inject(Setter, carrier, ctx); + EXPECT_TRUE(carrier.count("traceparent") == 0); +} + +TEST(HTTPTextFormatTest, TraceStateHeaderWithTrailingComma) +{ + // Do not propagate invalid trace context. + const std::map carrier = { {"traceparent", "00-12345678901234567890123456789012-1234567890123456-00"}, + {"tracestate", "foo=1,"} }; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter,carrier,ctx1); + trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); + trace::TraceState trace_state = span->GetContext().trace_state(); + EXPECT_TRUE(trace_state.Get("foo", "1")); +} + +TEST(HTTPTextFormatTest, TraceStateKeys) +{ + // Test for valid key patterns in the tracestate + std::string trace_state_value = "1a-2f@foo=bar1,1a-_*/2b@foo=bar2,foo=bar3,foo-_*/bar=bar4"; + const std::map carrier = { {"traceparent", "00-12345678901234567890123456789012-1234567890123456-00"}, + {"tracestate", trace_state_value} }; + context::Context ctx1 = context::Context("current-span",nostd::shared_ptr(new trace::DefaultSpan())); + context::Context ctx2 = format.Extract(Getter,carrier,ctx1); + trace::Span* span = MapHttpTraceContext::GetCurrentSpan(ctx2); + trace::TraceState trace_state = span->GetContext().trace_state(); + EXPECT_TRUE(trace_state.Get("1a-2f@foo", "bar1")); + EXPECT_TRUE(trace_state.Get("1a-_*/2b@foo", "bar2")); + EXPECT_TRUE(trace_state.Get("foo", "bar3")); + EXPECT_TRUE(trace_state.Get("foo-_*/bar", "bar4")); +}