Skip to content

Commit

Permalink
Merge branch 'main' into active-span-doc
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Jul 6, 2021
2 parents 1023cfb + 4292a57 commit 019c2b1
Show file tree
Hide file tree
Showing 40 changed files with 584 additions and 82 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ on each other), the owner should try to get people aligned by:
split it up.

If none of the above worked and the PR has been stuck for more than 2 weeks, the
owner should bring it to the [OpenTelemetry C++ SIG
meeting](https://zoom.us/j/8203130519). The meeting passcode is _77777_.
owner should bring it to the OpenTelemetry C++ SIG meeting. See
[README.md](README.md#contributing) for the meeting link.

## Useful Resources

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ contributors' availability. Check the [OpenTelemetry community
calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com)
for specific dates.

Meetings take place via [Zoom video conference](https://zoom.us/j/8203130519).
Meetings take place via [Zoom video conference](https://zoom.us/j/6729396170).
The passcode is _77777_.

Meeting notes are available as a public [Google
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class BaggagePropagator : public context::propagation::TextMapPropagator
auto baggage = Baggage::FromHeader(baggage_str);
return SetBaggage(context, baggage);
}

bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
return callback(kBaggageHeader);
}
};
} // namespace propagation
} // namespace baggage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ class CompositePropagator : public TextMapPropagator
return propagators_.size() ? tmp_context : context;
}

/**
* Invoke callback with fields set to carrier by `inject` method for all the
* configured propagators
* Returns true if all invocation return true
*/
bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
bool status = true;
for (auto &p : propagators_)
{
status = status && p->Fields(callback);
}
return status;
}

private:
std::vector<std::unique_ptr<TextMapPropagator>> propagators_;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class NoOpPropagator : public TextMapPropagator

/** Noop inject function does nothing */
void Inject(TextMapCarrier & /*carrier*/, const context::Context &context) noexcept override {}

bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
return true;
}
};
} // namespace propagation
} // namespace context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,19 @@ namespace propagation
class TextMapCarrier
{
public:
/*returns the value associated with the passed key.*/
// returns the value associated with the passed key.
virtual nostd::string_view Get(nostd::string_view key) const noexcept = 0;

/*stores the key-value pair.*/
// stores the key-value pair.
virtual void Set(nostd::string_view key, nostd::string_view value) noexcept = 0;

/* list of all the keys in the carrier.
By default, it returns true without invoking callback */
virtual bool Keys(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept
{
return true;
}
virtual ~TextMapCarrier() = default;
};

// The TextMapPropagator class provides an interface that enables extracting and injecting
Expand All @@ -40,6 +48,11 @@ class TextMapPropagator

// Sets the context for carrier with self defined rules.
virtual void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept = 0;

// Gets the fields set in the carrier by the `inject` method
virtual bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept = 0;

virtual ~TextMapPropagator() = default;
};
} // namespace propagation
} // namespace context
Expand Down
2 changes: 1 addition & 1 deletion api/include/opentelemetry/context/runtime_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ inline Token::~Token()
}

// The ThreadLocalContextStorage class is a derived class from
// RuntimeContextStorage and provides a wrapper for propogating context through
// RuntimeContextStorage and provides a wrapper for propagating context through
// cpp thread locally. This file must be included to use the RuntimeContext
// class if another implementation has not been registered.
class ThreadLocalContextStorage : public RuntimeContextStorage
Expand Down
11 changes: 8 additions & 3 deletions api/include/opentelemetry/trace/noop.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ class NoopSpan final : public Span
{
public:
explicit NoopSpan(const std::shared_ptr<Tracer> &tracer) noexcept
: tracer_{tracer}, span_context_{SpanContext::GetInvalid()}
: tracer_{tracer}, span_context_{new SpanContext(false, false)}
{}

explicit NoopSpan(const std::shared_ptr<Tracer> &tracer,
nostd::unique_ptr<SpanContext> span_context) noexcept
: tracer_{tracer}, span_context_{std::move(span_context)}
{}

void SetAttribute(nostd::string_view /*key*/,
Expand All @@ -55,11 +60,11 @@ class NoopSpan final : public Span

bool IsRecording() const noexcept override { return false; }

SpanContext GetContext() const noexcept override { return span_context_; }
SpanContext GetContext() const noexcept override { return *span_context_.get(); }

private:
std::shared_ptr<Tracer> tracer_;
SpanContext span_context_;
nostd::unique_ptr<SpanContext> span_context_;
};

/**
Expand Down
10 changes: 10 additions & 0 deletions api/include/opentelemetry/trace/propagation/b3_propagator.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ class B3Propagator : public B3PropagatorExtractor

carrier.Set(kB3CombinedHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
}

bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
return callback(kB3CombinedHeader);
}
};

class B3PropagatorMultiHeader : public B3PropagatorExtractor
Expand All @@ -173,6 +178,11 @@ class B3PropagatorMultiHeader : public B3PropagatorExtractor
carrier.Set(kB3SpanIdHeader, nostd::string_view(span_id, sizeof(span_id)));
carrier.Set(kB3SampledHeader, nostd::string_view(trace_flags + 1, 1));
}

bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
return callback(kB3TraceIdHeader) && callback(kB3SpanIdHeader) && callback(kB3SampledHeader);
}
};

} // namespace propagation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ class HttpTraceContext : public opentelemetry::context::propagation::TextMapProp

return ExtractContextFromTraceHeaders(trace_parent, trace_state);
}

bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
return (callback(kTraceParent) && callback(kTraceState));
}
};
} // namespace propagation
} // namespace trace
Expand Down
11 changes: 8 additions & 3 deletions api/include/opentelemetry/trace/propagation/jaeger.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace trace
namespace propagation
{

static const nostd::string_view kTraceHeader = "uber-trace-id";
static const nostd::string_view kJaegerTraceHeader = "uber-trace-id";

class JaegerPropagator : public context::propagation::TextMapPropagator
{
Expand Down Expand Up @@ -45,7 +45,7 @@ class JaegerPropagator : public context::propagation::TextMapPropagator
trace_identity[trace_id_length + span_id_length + 4] = '0';
trace_identity[trace_id_length + span_id_length + 5] = span_context.IsSampled() ? '1' : '0';

carrier.Set(kTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
carrier.Set(kJaegerTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
}

context::Context Extract(const context::propagation::TextMapCarrier &carrier,
Expand All @@ -56,6 +56,11 @@ class JaegerPropagator : public context::propagation::TextMapPropagator
return SetSpan(context, sp);
}

bool Fields(nostd::function_ref<bool(nostd::string_view)> callback) const noexcept override
{
return callback(kJaegerTraceHeader);
}

private:
static constexpr uint8_t kIsSampled = 0x01;

Expand All @@ -67,7 +72,7 @@ class JaegerPropagator : public context::propagation::TextMapPropagator

static SpanContext ExtractImpl(const context::propagation::TextMapCarrier &carrier)
{
nostd::string_view trace_identity = carrier.Get(kTraceHeader);
nostd::string_view trace_identity = carrier.Get(kJaegerTraceHeader);

const size_t trace_field_count = 4;
nostd::string_view trace_fields[trace_field_count];
Expand Down
8 changes: 8 additions & 0 deletions api/test/baggage/propagation/baggage_propagator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,13 @@ TEST(BaggagePropagatorTest, ExtractAndInjectBaggage)
BaggageCarrierTest carrier2;
format.Inject(carrier2, ctx2);
EXPECT_EQ(carrier2.headers_[kBaggageHeader.data()], baggage.second);

std::vector<std::string> fields;
format.Fields([&fields](nostd::string_view field) {
fields.push_back(field.data());
return true;
});
EXPECT_EQ(fields.size(), 1);
EXPECT_EQ(fields[0], kBaggageHeader.data());
}
}
10 changes: 10 additions & 0 deletions api/test/context/propagation/composite_propagator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,14 @@ TEST_F(CompositePropagatorTest, Inject)
EXPECT_EQ(carrier.headers_["traceparent"],
"00-0102030405060708090a0b0c0d0e0f10-0102030405060708-01");
EXPECT_EQ(carrier.headers_["b3"], "0102030405060708090a0b0c0d0e0f10-0102030405060708-1");

std::vector<std::string> fields;
composite_propagator_->Fields([&fields](nostd::string_view field) {
fields.push_back(field.data());
return true;
});
EXPECT_EQ(fields.size(), 3);
EXPECT_EQ(fields[0], opentelemetry::trace::propagation::kTraceParent);
EXPECT_EQ(fields[1], opentelemetry::trace::propagation::kTraceState);
EXPECT_EQ(fields[2], opentelemetry::trace::propagation::kB3CombinedHeader);
}
43 changes: 32 additions & 11 deletions api/test/trace/noop_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@

#include <gtest/gtest.h>

using opentelemetry::common::SystemTimestamp;
using opentelemetry::trace::NoopTracer;
using opentelemetry::trace::SpanContext;
using opentelemetry::trace::Tracer;
namespace trace_api = opentelemetry::trace;
namespace nonstd = opentelemetry::nostd;
namespace common = opentelemetry::common;

TEST(NoopTest, UseNoopTracers)
{
std::shared_ptr<Tracer> tracer{new NoopTracer{}};
std::shared_ptr<trace_api::Tracer> tracer{new trace_api::NoopTracer{}};
auto s1 = tracer->StartSpan("abc");

std::map<std::string, std::string> attributes1;
Expand All @@ -41,20 +40,42 @@ TEST(NoopTest, UseNoopTracers)

s1->UpdateName("test_name");

SystemTimestamp t1;
common::SystemTimestamp t1;
s1->AddEvent("test_time_stamp", t1);

s1->GetContext();
}

TEST(NoopTest, StartSpan)
{
std::shared_ptr<Tracer> tracer{new NoopTracer{}};
std::shared_ptr<trace_api::Tracer> tracer{new trace_api::NoopTracer{}};

std::map<std::string, std::string> attrs = {{"a", "3"}};
std::vector<std::pair<SpanContext, std::map<std::string, std::string>>> links = {
{SpanContext(false, false), attrs}};
std::map<std::string, std::string> attrs = {{"a", "3"}};
std::vector<std::pair<trace_api::SpanContext, std::map<std::string, std::string>>> links = {
{trace_api::SpanContext(false, false), attrs}};
auto s1 = tracer->StartSpan("abc", attrs, links);

auto s2 = tracer->StartSpan("efg", {{"a", 3}}, {{SpanContext(false, false), {{"b", 4}}}});
auto s2 =
tracer->StartSpan("efg", {{"a", 3}}, {{trace_api::SpanContext(false, false), {{"b", 4}}}});
}

TEST(NoopTest, CreateSpanValidSpanContext)
{
// Create valid spancontext for NoopSpan

constexpr uint8_t buf_span[] = {1, 2, 3, 4, 5, 6, 7, 8};
constexpr uint8_t buf_trace[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
auto trace_id = trace_api::TraceId{buf_trace};
auto span_id = trace_api::SpanId{buf_span};
auto span_context = nonstd::unique_ptr<trace_api::SpanContext>(
new trace_api::SpanContext{trace_id, span_id, trace_api::TraceFlags{true}, false});
std::shared_ptr<trace_api::Tracer> tracer{new trace_api::NoopTracer{}};
auto s1 =
nonstd::shared_ptr<trace_api::Span>(new trace_api::NoopSpan(tracer, std::move(span_context)));
auto stored_span_context = s1->GetContext();
EXPECT_EQ(stored_span_context.span_id(), span_id);
EXPECT_EQ(stored_span_context.trace_id(), trace_id);

s1->AddEvent("even1"); // noop
s1->End(); // noop
}
9 changes: 9 additions & 0 deletions api/test/trace/propagation/http_text_format_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,13 @@ TEST(GlobalPropagator, SetAndGet)
EXPECT_TRUE(carrier.headers_.count("traceparent") > 0);
EXPECT_TRUE(carrier.headers_.count("tracestate") > 0);
EXPECT_EQ(carrier.headers_["tracestate"], trace_state_value);

std::vector<std::string> fields;
propagator->Fields([&fields](nostd::string_view field) {
fields.push_back(field.data());
return true;
});
EXPECT_EQ(fields.size(), 2);
EXPECT_EQ(fields[0], opentelemetry::trace::propagation::kTraceParent);
EXPECT_EQ(fields[1], opentelemetry::trace::propagation::kTraceState);
}
8 changes: 8 additions & 0 deletions api/test/trace/propagation/jaeger_propagation_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ TEST(JaegerPropagatorTest, InjectsContext)
format.Inject(carrier, context::RuntimeContext::GetCurrent());
EXPECT_EQ(carrier.headers_["uber-trace-id"],
"0102030405060708090a0b0c0d0e0f10:0102030405060708:0:01");

std::vector<std::string> fields;
format.Fields([&fields](nostd::string_view field) {
fields.push_back(field.data());
return true;
});
EXPECT_EQ(fields.size(), 1);
EXPECT_EQ(fields[0], opentelemetry::trace::propagation::kJaegerTraceHeader);
}

TEST(JaegerPropagatorTest, DoNotInjectInvalidContext)
Expand Down
3 changes: 3 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ if(WITH_OTLP_GRPC OR WITH_OTLP_HTTP)
add_subdirectory(otlp)
add_subdirectory(grpc)
endif()
if(WITH_ETW)
add_subdirectory(etw_threads)
endif()
if(WITH_JAEGER)
add_subdirectory(jaeger)
endif()
Expand Down
6 changes: 6 additions & 0 deletions examples/etw_threads/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project(etw_threadpool)

add_executable(etw_threadpool main.cc)

target_link_libraries(etw_threadpool ${CMAKE_THREAD_LIBS_INIT}
opentelemetry_api opentelemetry_exporter_etw)
32 changes: 32 additions & 0 deletions examples/etw_threads/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# ETW Exporter multithreaded context propagation example

## Preface

This example shows how to pass context from main dispatcher thread to worker threads.
While this example is convenient to run in Visual Studio with ETW exporter, the same
logic should apply to any other exporter. Only the initial portion that obtains ETW
Tracer is unique to ETW, the rest can be reused.

## How to debug events in Visual Studio 2019 or newer

Specify your component instrumentation name, which should match the destination ETW
Provider Name or GUID. Example uses "OpenTelemetry-ETW-TLD" for the instrument /
instrumentation name.

In Visual Studio IDE:

- navigate to `View -> Other Windows -> Diagnostic Events...`
- click `Configure...` gear on top.
- specify `OpenTelemetry-ETW-TLD` in the list of providers to monitor.
- run example.
- `Diagnostic Events` view shows you the event flow in realtime.

## Explanation of the code flow

`main` function acts as a dispatcher to manage thread pool called `pool`. `beep_bop`
span is started in the `main`. Then in a loop up to `kMaxThreads` get started
concurrently. Each thread executing `beep` function with a parent scope of `main`.
`beep` subsequently calls into `bop` function, with a parent scope of `beep` span.
Entire execution of all threads is grouped under the main span called `beep_bop`.
At the end of execution, the `main` function joins all pending threads and ends
the main span.
Loading

0 comments on commit 019c2b1

Please sign in to comment.