Skip to content
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

Add a minimal Tracer and Span API #25

Merged
merged 16 commits into from
Jan 15, 2020
137 changes: 137 additions & 0 deletions api/include/opentelemetry/nostd/unique_ptr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#pragma once

#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>

namespace opentelemetry
{
namespace nostd
{
/**
* Provide a simplified port of std::unique_ptr that has ABI stability.
*
* Note: This implementation doesn't allow for a custom deleter or array specializations.
*/
template <class T>
class unique_ptr
{
public:
unique_ptr() noexcept : ptr_{nullptr} {}

unique_ptr(std::nullptr_t) noexcept : ptr_{nullptr} {}

explicit unique_ptr(T *ptr) noexcept : ptr_{ptr} {}

unique_ptr(unique_ptr &&other) noexcept : ptr_{other.release()} {}

template <class U,
typename std::enable_if<std::is_convertible<U *, T *>::value>::type * = nullptr>
unique_ptr(unique_ptr<U> &&other) noexcept : ptr_{other.release()}
{}

template <class U,
typename std::enable_if<std::is_convertible<U *, T *>::value>::type * = nullptr>
unique_ptr(std::unique_ptr<U> &&other) noexcept : ptr_{other.release()}
{}

~unique_ptr() { reset(); }

unique_ptr &operator=(unique_ptr &&other) noexcept
{
reset(other.release());
return *this;
}

unique_ptr &operator=(std::nullptr_t) noexcept
{
reset();
return *this;
}

template <class U,
typename std::enable_if<std::is_convertible<U *, T *>::value>::type * = nullptr>
unique_ptr &operator=(unique_ptr<U> &&other) noexcept
{
reset(other.release());
return *this;
}

template <class U,
typename std::enable_if<std::is_convertible<U *, T *>::value>::type * = nullptr>
unique_ptr &operator=(std::unique_ptr<U> &&other) noexcept
{
reset(other.release());
return *this;
}

operator std::unique_ptr<T>() && noexcept { return std::unique_ptr<T>{release()}; }

operator bool() const noexcept { return ptr_ != nullptr; }

T &operator*() const noexcept { return *ptr_; }

T *operator->() const noexcept { return get(); }

T *get() const noexcept { return ptr_; }

void reset(T *ptr = nullptr) noexcept
{
if (ptr_ != nullptr)
{
delete ptr_;
}
ptr_ = ptr;
}

T *release() noexcept
{
auto result = ptr_;
ptr_ = nullptr;
return result;
}

void swap(unique_ptr &other) noexcept { std::swap(ptr_, other.ptr_); }

private:
T *ptr_;
};

template <class T1, class T2>
bool operator==(const unique_ptr<T1> &lhs, const unique_ptr<T2> &rhs) noexcept
{
return lhs.get() == rhs.get();
}

template <class T>
bool operator==(const unique_ptr<T> &lhs, std::nullptr_t) noexcept
{
return lhs.get() == nullptr;
}

template <class T>
bool operator==(std::nullptr_t, const unique_ptr<T> &rhs) noexcept
{
return nullptr == rhs.get();
}

template <class T1, class T2>
bool operator!=(const unique_ptr<T1> &lhs, const unique_ptr<T2> &rhs) noexcept
{
return lhs.get() != rhs.get();
}

template <class T>
bool operator!=(const unique_ptr<T> &lhs, std::nullptr_t) noexcept
{
return lhs.get() != nullptr;
}

template <class T>
bool operator!=(std::nullptr_t, const unique_ptr<T> &rhs) noexcept
{
return nullptr != rhs.get();
}
} // namespace nostd
} // namespace opentelemetry
Empty file.
40 changes: 40 additions & 0 deletions api/include/opentelemetry/trace/noop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include "opentelemetry/trace/tracer.h"

#include <memory>

namespace opentelemetry
{
namespace trace
{
/**
* Noop implementation of Span.
*/
class NoopSpan final : public Span
{
public:
explicit NoopSpan(const std::shared_ptr<Tracer> &tracer) noexcept : tracer_{tracer} {}

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

private:
std::shared_ptr<Tracer> tracer_;
};

/**
* Noop implementation of Tracer
*/
class NoopTracer final : public Tracer, public std::enable_shared_from_this<NoopTracer>
{
public:
// Tracer
nostd::unique_ptr<Span> StartSpan(nostd::string_view /*name*/,
const StartSpanOptions & /*options*/) noexcept override
{
return nostd::unique_ptr<Span>{new (std::nothrow) NoopSpan{this->shared_from_this()}};
}
};
} // namespace trace
} // namespace opentelemetry
26 changes: 26 additions & 0 deletions api/include/opentelemetry/trace/span.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

namespace opentelemetry
{
namespace trace
{
/**
* StartSpanOptions provides options to set properties of span at the time of starting a new span.
*/
struct StartSpanOptions
{};

class Tracer;

/**
* A span represents a single operation within a trace.
*/
class Span
{
public:
virtual ~Span() = default;

virtual Tracer &tracer() const noexcept = 0;
};
} // namespace trace
} // namespace opentelemetry
29 changes: 29 additions & 0 deletions api/include/opentelemetry/trace/tracer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/span.h"

namespace opentelemetry
{
namespace trace
{
/**
* Handles span creation and in-process context propagation.
*
* This class provides methods for manipulating the context, creating spans, and controlling spans'
* lifecycles.
*/
class Tracer
{
public:
virtual ~Tracer() = default;

/**
* Starts a span.
*/
virtual nostd::unique_ptr<Span> StartSpan(nostd::string_view name,
const StartSpanOptions &options = {}) noexcept = 0;
};
} // namespace trace
} // namespace opentelemetry
1 change: 1 addition & 0 deletions api/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
add_subdirectory(nostd)
add_subdirectory(trace)
11 changes: 11 additions & 0 deletions api/test/nostd/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ cc_test(
],
)

cc_test(
name = "unique_ptr_test",
srcs = [
"unique_ptr_test.cc",
],
deps = [
"//api",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "utility_test",
srcs = [
Expand Down
6 changes: 6 additions & 0 deletions api/test/nostd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ target_link_libraries(string_view_test ${GTEST_BOTH_LIBRARIES}
gtest_add_tests(TARGET string_view_test TEST_PREFIX nostd. TEST_LIST
string_view_test)

add_executable(unique_ptr_test unique_ptr_test.cc)
target_link_libraries(unique_ptr_test ${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} opentelemetry_api)
gtest_add_tests(TARGET unique_ptr_test TEST_PREFIX nostd. TEST_LIST
unique_ptr_test)

add_executable(utility_test utility_test.cc)
target_link_libraries(utility_test ${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} opentelemetry_api)
Expand Down
Loading