Skip to content

Commit

Permalink
Span auto add context (#252)
Browse files Browse the repository at this point in the history
  • Loading branch information
satac2 authored Aug 12, 2020
1 parent 175c08f commit a55843f
Show file tree
Hide file tree
Showing 37 changed files with 304 additions and 108 deletions.
9 changes: 7 additions & 2 deletions api/include/opentelemetry/context/context_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
#include "opentelemetry/nostd/span.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/span_context.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{
using ContextValue =
nostd::variant<bool, int64_t, uint64_t, double, nostd::shared_ptr<trace::SpanContext>>;
using ContextValue = nostd::variant<bool,
int64_t,
uint64_t,
double,
nostd::shared_ptr<trace::Span>,
nostd::shared_ptr<trace::SpanContext>>;
} // namespace context
OPENTELEMETRY_END_NAMESPACE
56 changes: 42 additions & 14 deletions api/include/opentelemetry/context/runtime_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,53 @@
OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{
// Provides a wrapper for propagating the context object globally. In order
// to use either the threadlocal_context.h file must be included or another
// implementation which must be derived from the RuntimeContext can be
// provided.
class RuntimeContext
// The Token object provides is returned when attaching objects to the
// RuntimeContext object and is associated with a context object, and
// can be provided to the RuntimeContext Detach method to remove the
// associated context from the RuntimeContext.
class Token
{
public:
class Token
bool operator==(const Context &other) noexcept { return context_ == other; }

private:
friend class RuntimeContext;

// The ContextDetacher object automatically attempts to detach
// the Token when all copies of the Token are out of scope.
class ContextDetacher
{
public:
bool operator==(const Context &other) noexcept { return context_ == other; }
ContextDetacher(Context context) : context_(context) {}

~Token() noexcept { Detach(*this); }
~ContextDetacher();

private:
friend class RuntimeContext;
Context context_;
};

// A constructor that sets the token's Context object to the
// one that was passed in.
Token(Context context) noexcept : context_(context){};
Token() noexcept = default;

Token() noexcept = default;
// A constructor that sets the token's Context object to the
// one that was passed in.
Token(Context context)
{
context_ = context;

Context context_;
detacher_ = nostd::shared_ptr<ContextDetacher>(new ContextDetacher(context_));
};

Context context_;
nostd::shared_ptr<ContextDetacher> detacher_;
};

// Provides a wrapper for propagating the context object globally. In order
// to use either the threadlocal_context.h file must be included or another
// implementation which must be derived from the RuntimeContext can be
// provided.
class RuntimeContext
{
public:
// Return the current context.
static Context GetCurrent() noexcept { return context_handler_->InternalGetCurrent(); }

Expand Down Expand Up @@ -97,5 +118,12 @@ class RuntimeContext

virtual bool InternalDetach(Token &token) noexcept = 0;
};

inline Token::ContextDetacher::~ContextDetacher()
{
context::Token token;
token.context_ = context_;
context::RuntimeContext::Detach(token);
}
} // namespace context
OPENTELEMETRY_END_NAMESPACE
8 changes: 8 additions & 0 deletions api/include/opentelemetry/context/runtime_def.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

//#include "opentelemetry/context/runtime_context.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{}
OPENTELEMETRY_BEGIN_NAMESPACE
15 changes: 8 additions & 7 deletions api/include/opentelemetry/plugin/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ namespace plugin
class Span final : public trace::Span
{
public:
Span(std::shared_ptr<trace::Tracer> &&tracer, std::unique_ptr<trace::Span> &&span) noexcept
: tracer_{std::move(tracer)}, span_{std::move(span)}
Span(std::shared_ptr<trace::Tracer> &&tracer, nostd::shared_ptr<trace::Span> span) noexcept
: tracer_{std::move(tracer)}, span_{span}
{}

// trace::Span
Expand Down Expand Up @@ -50,9 +50,11 @@ class Span final : public trace::Span

trace::Tracer &tracer() const noexcept override { return *tracer_; }

void SetToken(nostd::unique_ptr<context::Token> &&token) noexcept override {}

private:
std::shared_ptr<trace::Tracer> tracer_;
std::unique_ptr<trace::Span> span_;
nostd::shared_ptr<trace::Span> span_;
};

class Tracer final : public trace::Tracer, public std::enable_shared_from_this<Tracer>
Expand All @@ -64,18 +66,17 @@ class Tracer final : public trace::Tracer, public std::enable_shared_from_this<T
{}

// trace::Tracer
nostd::unique_ptr<trace::Span> StartSpan(
nostd::shared_ptr<trace::Span> StartSpan(
nostd::string_view name,
const trace::KeyValueIterable &attributes,
const trace::StartSpanOptions &options = {}) noexcept override
{
auto span = tracer_handle_->tracer().StartSpan(name, attributes, options);
if (span == nullptr)
{
return nullptr;
return nostd::shared_ptr<trace::Span>(nullptr);
}
return nostd::unique_ptr<trace::Span>{new (std::nothrow)
Span{this->shared_from_this(), std::move(span)}};
return nostd::shared_ptr<trace::Span>{new (std::nothrow) Span{this->shared_from_this(), span}};
}

void ForceFlushWithMicroseconds(uint64_t timeout) noexcept override
Expand Down
7 changes: 5 additions & 2 deletions api/include/opentelemetry/trace/noop.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// This file is part of the internal implementation of OpenTelemetry. Nothing in this file should be
// used directly. Please refer to span.h and tracer.h for documentation on these interfaces.

#include "opentelemetry/context/runtime_context.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/span.h"
Expand Down Expand Up @@ -48,6 +49,8 @@ class NoopSpan final : public Span

Tracer &tracer() const noexcept override { return *tracer_; }

void SetToken(nostd::unique_ptr<context::Token> && /* token */) noexcept override {}

private:
std::shared_ptr<Tracer> tracer_;
};
Expand All @@ -59,11 +62,11 @@ class NoopTracer final : public Tracer, public std::enable_shared_from_this<Noop
{
public:
// Tracer
nostd::unique_ptr<Span> StartSpan(nostd::string_view /*name*/,
nostd::shared_ptr<Span> StartSpan(nostd::string_view /*name*/,
const KeyValueIterable & /*attributes*/,
const StartSpanOptions & /*options*/) noexcept override
{
return nostd::unique_ptr<Span>{new (std::nothrow) NoopSpan{this->shared_from_this()}};
return nostd::shared_ptr<Span>{new (std::nothrow) NoopSpan{this->shared_from_this()}};
}

void ForceFlushWithMicroseconds(uint64_t /*timeout*/) noexcept override {}
Expand Down
27 changes: 20 additions & 7 deletions api/include/opentelemetry/trace/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@
#include "opentelemetry/core/timestamp.h"
#include "opentelemetry/nostd/span.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/canonical_code.h"
#include "opentelemetry/trace/key_value_iterable_view.h"
#include "opentelemetry/version.h"

constexpr char SpanKey[] = "span_key";

OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{
class Token;
}
namespace trace
{
enum class SpanKind
Expand All @@ -22,17 +29,19 @@ enum class SpanKind
kConsumer,
};
/**
* StartSpanOptions provides options to set properties of a Span at the time of its creation
* StartSpanOptions provides options to set properties of a Span at the time of
* its creation
*/
struct StartSpanOptions
{
// Optionally sets the start time of a Span.
//
// If the start time of a Span is set, timestamps from both the system clock and steady clock
// must be provided.
// If the start time of a Span is set, timestamps from both the system clock
// and steady clock must be provided.
//
// Timestamps from the steady clock can be used to most accurately measure a Span's
// duration, while timestamps from the system clock can be used to most accurately place a Span's
// Timestamps from the steady clock can be used to most accurately measure a
// Span's duration, while timestamps from the system clock can be used to most
// accurately place a Span's
// time point relative to other Spans collected across a distributed system.
core::SystemTimestamp start_system_time;
core::SteadyTimestamp start_steady_time;
Expand Down Expand Up @@ -74,7 +83,8 @@ class Span
Span &operator=(const Span &) = delete;
Span &operator=(Span &&) = delete;

// Sets an attribute on the Span. If the Span previously contained a mapping for
// Sets an attribute on the Span. If the Span previously contained a mapping
// for
// the key, the old value is replaced.
virtual void SetAttribute(nostd::string_view key,
const common::AttributeValue &value) noexcept = 0;
Expand Down Expand Up @@ -128,7 +138,8 @@ class Span
attributes.begin(), attributes.end()});
}

// Sets the status of the span. The default status is OK. Only the value of the last call will be
// Sets the status of the span. The default status is OK. Only the value of
// the last call will be
// recorded, and implementations are free to ignore previous calls.
virtual void SetStatus(CanonicalCode code, nostd::string_view description) noexcept = 0;

Expand All @@ -153,6 +164,8 @@ class Span
virtual bool IsRecording() const noexcept = 0;

virtual Tracer &tracer() const noexcept = 0;

virtual void SetToken(nostd::unique_ptr<context::Token> &&token) noexcept = 0;
};
} // namespace trace
OPENTELEMETRY_END_NAMESPACE
9 changes: 5 additions & 4 deletions api/include/opentelemetry/trace/tracer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/span.h"
Expand Down Expand Up @@ -28,25 +29,25 @@ class Tracer
* Attributes will be processed in order, previous attributes with the same
* key will be overwritten.
*/
virtual nostd::unique_ptr<Span> StartSpan(nostd::string_view name,
virtual nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
const KeyValueIterable &attributes,
const StartSpanOptions &options = {}) noexcept = 0;

nostd::unique_ptr<Span> StartSpan(nostd::string_view name,
nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
const StartSpanOptions &options = {}) noexcept
{
return this->StartSpan(name, {}, options);
}

template <class T, nostd::enable_if_t<detail::is_key_value_iterable<T>::value> * = nullptr>
nostd::unique_ptr<Span> StartSpan(nostd::string_view name,
nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
const T &attributes,
const StartSpanOptions &options = {}) noexcept
{
return this->StartSpan(name, KeyValueIterableView<T>(attributes), options);
}

nostd::unique_ptr<Span> StartSpan(
nostd::shared_ptr<Span> StartSpan(
nostd::string_view name,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
const StartSpanOptions &options = {}) noexcept
Expand Down
27 changes: 13 additions & 14 deletions api/test/context/runtime_context_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ TEST(RuntimeContextTest, GetCurrent)
{
std::map<std::string, context::ContextValue> map_test = {{"test_key", (int64_t)123}};
context::Context test_context = context::Context(map_test);
context::RuntimeContext::Token old_context = context::RuntimeContext::Attach(test_context);
context::Token old_context = context::RuntimeContext::Attach(test_context);
EXPECT_TRUE(context::RuntimeContext::GetCurrent() == test_context);
context::RuntimeContext::Detach(old_context);
}
Expand All @@ -22,8 +22,8 @@ TEST(RuntimeContextTest, Detach)
context::Context test_context = context::Context(map_test);
context::Context foo_context = context::Context(map_test);

context::RuntimeContext::Token test_context_token = context::RuntimeContext::Attach(test_context);
context::RuntimeContext::Token foo_context_token = context::RuntimeContext::Attach(foo_context);
context::Token test_context_token = context::RuntimeContext::Attach(test_context);
context::Token foo_context_token = context::RuntimeContext::Attach(foo_context);

context::RuntimeContext::Detach(foo_context_token);
EXPECT_TRUE(context::RuntimeContext::GetCurrent() == test_context);
Expand All @@ -36,8 +36,8 @@ TEST(RuntimeContextTest, DetachWrongContext)
std::map<std::string, context::ContextValue> map_test = {{"test_key", (int64_t)123}};
context::Context test_context = context::Context(map_test);
context::Context foo_context = context::Context(map_test);
context::RuntimeContext::Token test_context_token = context::RuntimeContext::Attach(test_context);
context::RuntimeContext::Token foo_context_token = context::RuntimeContext::Attach(foo_context);
context::Token test_context_token = context::RuntimeContext::Attach(test_context);
context::Token foo_context_token = context::RuntimeContext::Attach(foo_context);
EXPECT_FALSE(context::RuntimeContext::Detach(test_context_token));
context::RuntimeContext::Detach(foo_context_token);
context::RuntimeContext::Detach(test_context_token);
Expand All @@ -50,10 +50,9 @@ TEST(RuntimeContextTest, ThreeAttachDetach)
context::Context test_context = context::Context(map_test);
context::Context foo_context = context::Context(map_test);
context::Context other_context = context::Context(map_test);
context::RuntimeContext::Token test_context_token = context::RuntimeContext::Attach(test_context);
context::RuntimeContext::Token foo_context_token = context::RuntimeContext::Attach(foo_context);
context::RuntimeContext::Token other_context_token =
context::RuntimeContext::Attach(other_context);
context::Token test_context_token = context::RuntimeContext::Attach(test_context);
context::Token foo_context_token = context::RuntimeContext::Attach(foo_context);
context::Token other_context_token = context::RuntimeContext::Attach(other_context);

EXPECT_TRUE(context::RuntimeContext::Detach(other_context_token));
EXPECT_TRUE(context::RuntimeContext::Detach(foo_context_token));
Expand All @@ -65,9 +64,9 @@ TEST(RuntimeContextTest, ThreeAttachDetach)
// RuntimeContext::SetValue method.
TEST(RuntimeContextTest, SetValueRuntimeContext)
{
context::Context foo_context = context::Context("foo_key", (int64_t)596);
context::RuntimeContext::Token old_context_token = context::RuntimeContext::Attach(foo_context);
context::Context test_context = context::RuntimeContext::SetValue("test_key", (int64_t)123);
context::Context foo_context = context::Context("foo_key", (int64_t)596);
context::Token old_context_token = context::RuntimeContext::Attach(foo_context);
context::Context test_context = context::RuntimeContext::SetValue("test_key", (int64_t)123);
EXPECT_EQ(nostd::get<int64_t>(test_context.GetValue("test_key")), 123);
EXPECT_EQ(nostd::get<int64_t>(test_context.GetValue("foo_key")), 596);
}
Expand All @@ -88,8 +87,8 @@ TEST(RuntimeContextTest, SetValueOtherContext)
// passed in string and the current Runtime Context
TEST(RuntimeContextTest, GetValueRuntimeContext)
{
context::Context foo_context = context::Context("foo_key", (int64_t)596);
context::RuntimeContext::Token old_context_token = context::RuntimeContext::Attach(foo_context);
context::Context foo_context = context::Context("foo_key", (int64_t)596);
context::Token old_context_token = context::RuntimeContext::Attach(foo_context);
EXPECT_EQ(nostd::get<int64_t>(context::RuntimeContext::GetValue("foo_key")), 596);
}

Expand Down
1 change: 1 addition & 0 deletions api/test/plugin/dynamic_load_test.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "opentelemetry/plugin/dynamic_load.h"
#include "opentelemetry/context/threadlocal_context.h"

#include <gtest/gtest.h>

Expand Down
2 changes: 2 additions & 0 deletions examples/batch/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "opentelemetry/exporters/ostream/span_exporter.h"
#include "opentelemetry/sdk/trace/batch_span_processor.h"

#include "opentelemetry/context/threadlocal_context.h"

#include <chrono>
#include <thread>

Expand Down
1 change: 1 addition & 0 deletions examples/plugin/load/main.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "opentelemetry/context/threadlocal_context.h"
#include "opentelemetry/plugin/dynamic_load.h"

#include <cstring>
Expand Down
Loading

0 comments on commit a55843f

Please sign in to comment.