Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion api/include/opentelemetry/plugin/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ class Tracer final : public trace::Tracer, public std::enable_shared_from_this<T
nostd::shared_ptr<trace::Span> StartSpan(
nostd::string_view name,
const common::KeyValueIterable &attributes,
const trace::SpanContextKeyValueIterable &links,
const trace::StartSpanOptions &options = {}) noexcept override
{
auto span = tracer_handle_->tracer().StartSpan(name, attributes, options);
auto span = tracer_handle_->tracer().StartSpan(name, attributes, links, options);
if (span == nullptr)
{
return nostd::shared_ptr<trace::Span>(nullptr);
Expand Down
2 changes: 2 additions & 0 deletions api/include/opentelemetry/trace/noop.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/span_context.h"
#include "opentelemetry/trace/span_context_kv_iterable.h"
#include "opentelemetry/trace/tracer.h"
#include "opentelemetry/trace/tracer_provider.h"
#include "opentelemetry/version.h"
Expand Down Expand Up @@ -66,6 +67,7 @@ class NoopTracer final : public Tracer, public std::enable_shared_from_this<Noop
// Tracer
nostd::shared_ptr<Span> StartSpan(nostd::string_view /*name*/,
const common::KeyValueIterable & /*attributes*/,
const SpanContextKeyValueIterable & /*links*/,
const StartSpanOptions & /*options*/) noexcept override
{
// Don't allocate a no-op span for every StartSpan call, but use a static
Expand Down
34 changes: 34 additions & 0 deletions api/include/opentelemetry/trace/span_context_kv_iterable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include "opentelemetry/common/attribute_value.h"
#include "opentelemetry/common/key_value_iterable_view.h"
#include "opentelemetry/nostd/function_ref.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace trace
{
/**
* Supports internal iteration over a collection of SpanContext/key-value pairs.
*/
class SpanContextKeyValueIterable
{
public:
virtual ~SpanContextKeyValueIterable() = default;

/**
* Iterate over SpanContext/key-value pairs
* @param callback a callback to invoke for each key-value for each SpanContext.
* If the callback returns false, the iteration is aborted.
* @return true if every SpanContext/key-value pair was iterated over
*/
virtual bool ForEachKeyValue(
nostd::function_ref<bool(SpanContext, const opentelemetry::common::KeyValueIterable &)>
callback) const noexcept = 0;
/**
* @return the number of key-value pairs
*/
virtual size_t size() const noexcept = 0;
};
} // namespace trace
OPENTELEMETRY_END_NAMESPACE
113 changes: 113 additions & 0 deletions api/include/opentelemetry/trace/span_context_kv_iterable_view.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#pragma once

#include <iterator>
#include <type_traits>
#include <utility>

#include "opentelemetry/common/key_value_iterable_view.h"
#include "opentelemetry/nostd/utility.h"
#include "opentelemetry/trace/span_context_kv_iterable.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace trace
{
namespace detail
{
template <class T>
inline void take_span_context_kv(SpanContext, common::KeyValueIterableView<T>)
{}

template <class T, nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
inline void take_span_context_kv(SpanContext, T &)
{}

inline void take_span_context_kv(
SpanContext,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>)
{}

template <class T>
auto is_span_context_kv_iterable_impl(T iterable)
-> decltype(take_span_context_kv(std::begin(iterable)->first, std::begin(iterable)->second),
nostd::size(iterable),
std::true_type{});

std::false_type is_span_context_kv_iterable_impl(...);

template <class T>
struct is_span_context_kv_iterable
{
static const bool value =
decltype(detail::is_span_context_kv_iterable_impl(std::declval<T>()))::value;
};
} // namespace detail

template <class T>
class SpanContextKeyValueIterableView final : public SpanContextKeyValueIterable
{
static_assert(detail::is_span_context_kv_iterable<T>::value,
"Must be a context/key-value iterable");

public:
explicit SpanContextKeyValueIterableView(const T &links) noexcept : container_{&links} {}

bool ForEachKeyValue(
nostd::function_ref<bool(SpanContext, const opentelemetry::common::KeyValueIterable &)>
callback) const noexcept override
Comment thread
lalitb marked this conversation as resolved.
{
auto iter = std::begin(*container_);
auto last = std::end(*container_);
for (; iter != last; ++iter)
{
if (!this->do_callback(iter->first, iter->second, callback))
{
return false;
}
}
return true;
}

size_t size() const noexcept override { return nostd::size(*container_); }

private:
const T *container_;

bool do_callback(
SpanContext span_context,
const common::KeyValueIterable &attributes,
nostd::function_ref<bool(SpanContext, const opentelemetry::common::KeyValueIterable &)>
callback) const noexcept
{
if (!callback(span_context, attributes))
{
return false;
}
return true;
}

template <class U,
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
bool do_callback(
SpanContext span_context,
const U &attributes,
nostd::function_ref<bool(SpanContext, const common::KeyValueIterable &)> callback) const
noexcept
{
return do_callback(span_context, common::KeyValueIterableView<U>(attributes), callback);
}

bool do_callback(
Comment thread
lalitb marked this conversation as resolved.
SpanContext span_context,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
nostd::function_ref<bool(SpanContext, const common::KeyValueIterable &)> callback) const
noexcept
{
return do_callback(span_context,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
callback);
}
};
} // namespace trace
OPENTELEMETRY_END_NAMESPACE
71 changes: 68 additions & 3 deletions api/include/opentelemetry/trace/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "opentelemetry/trace/default_span.h"
#include "opentelemetry/trace/scope.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/span_context_kv_iterable_view.h"
#include "opentelemetry/version.h"

#include <chrono>
Expand Down Expand Up @@ -33,12 +34,13 @@ class Tracer
*/
virtual nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
const common::KeyValueIterable &attributes,
const SpanContextKeyValueIterable &links,
const StartSpanOptions &options = {}) noexcept = 0;

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

template <class T,
Expand All @@ -47,18 +49,81 @@ class Tracer
const T &attributes,
const StartSpanOptions &options = {}) noexcept
{
return this->StartSpan(name, common::KeyValueIterableView<T>(attributes), options);
return this->StartSpan(name, attributes, {}, options);
}

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

nostd::shared_ptr<Span> StartSpan(
nostd::string_view name,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
const StartSpanOptions &options = {}) noexcept
{

return this->StartSpan(name, attributes, {}, options);
}

template <class T,
nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
nostd::shared_ptr<Span> StartSpan(
nostd::string_view name,
const T &attributes,
std::initializer_list<
std::pair<SpanContext,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>>>
links,
const StartSpanOptions &options = {}) noexcept
{
return this->StartSpan(
name, attributes,
nostd::span<const std::pair<SpanContext, std::initializer_list<std::pair<
nostd::string_view, common::AttributeValue>>>>{
links.begin(), links.end()},
options);
}

template <class T,
nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
nostd::shared_ptr<Span> StartSpan(
nostd::string_view name,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
const T &links,
const StartSpanOptions &options = {}) noexcept
{
return this->StartSpan(name,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
options);
links, options);
}

nostd::shared_ptr<Span> StartSpan(
nostd::string_view name,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
std::initializer_list<
std::pair<SpanContext,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>>>
links,
const StartSpanOptions &options = {}) noexcept
{
return this->StartSpan(
name,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{attributes.begin(),
attributes.end()},
nostd::span<const std::pair<SpanContext, std::initializer_list<std::pair<
nostd::string_view, common::AttributeValue>>>>{
links.begin(), links.end()},
options);
}

/**
Expand Down
12 changes: 12 additions & 0 deletions api/test/trace/noop_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,15 @@ TEST(NoopTest, UseNoopTracers)

s1->GetContext();
}

TEST(NoopTest, StartSpan)
{
std::shared_ptr<Tracer> tracer{new 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}};
auto s1 = tracer->StartSpan("abc", attrs, links);

auto s2 = tracer->StartSpan("efg", {{"a", 3}}, {{SpanContext(false, false), {{"b", 4}}}});
Comment thread
lalitb marked this conversation as resolved.
}
4 changes: 3 additions & 1 deletion examples/plugin/plugin/tracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Span final : public trace::Span
Span(std::shared_ptr<Tracer> &&tracer,
nostd::string_view name,
const opentelemetry::common::KeyValueIterable & /*attributes*/,
const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/,
const trace::StartSpanOptions & /*options*/) noexcept
: tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()}
{
Expand Down Expand Up @@ -66,8 +67,9 @@ Tracer::Tracer(nostd::string_view /*output*/) {}
nostd::shared_ptr<trace::Span> Tracer::StartSpan(
nostd::string_view name,
const opentelemetry::common::KeyValueIterable &attributes,
const opentelemetry::trace::SpanContextKeyValueIterable &links,
const trace::StartSpanOptions &options) noexcept
{
return nostd::shared_ptr<opentelemetry::trace::Span>{
new (std::nothrow) Span{this->shared_from_this(), name, attributes, options}};
new (std::nothrow) Span{this->shared_from_this(), name, attributes, links, options}};
}
1 change: 1 addition & 0 deletions examples/plugin/plugin/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Tracer final : public opentelemetry::trace::Tracer,
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> StartSpan(
opentelemetry::nostd::string_view name,
const opentelemetry::common::KeyValueIterable & /*attributes*/,
const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/,
const opentelemetry::trace::StartSpanOptions & /*options */) noexcept override;

void ForceFlushWithMicroseconds(uint64_t /*timeout*/) noexcept override {}
Expand Down
1 change: 1 addition & 0 deletions sdk/include/opentelemetry/sdk/trace/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Tracer final : public trace_api::Tracer, public std::enable_shared_from_th
nostd::shared_ptr<trace_api::Span> StartSpan(
nostd::string_view name,
const opentelemetry::common::KeyValueIterable &attributes,
const trace_api::SpanContextKeyValueIterable &links,
const trace_api::StartSpanOptions &options = {}) noexcept override;

void ForceFlushWithMicroseconds(uint64_t timeout) noexcept override;
Expand Down
7 changes: 7 additions & 0 deletions sdk/src/trace/span.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Span::Span(std::shared_ptr<Tracer> &&tracer,
std::shared_ptr<SpanProcessor> processor,
nostd::string_view name,
const opentelemetry::common::KeyValueIterable &attributes,
const trace_api::SpanContextKeyValueIterable &links,
const trace_api::StartSpanOptions &options,
const trace_api::SpanContext &parent_span_context) noexcept
: tracer_{std::move(tracer)},
Expand Down Expand Up @@ -98,6 +99,12 @@ Span::Span(std::shared_ptr<Tracer> &&tracer,
return true;
});

links.ForEachKeyValue([&](opentelemetry::trace::SpanContext span_context,
const opentelemetry::common::KeyValueIterable &attributes) {
recordable_->AddLink(span_context, attributes);
return true;
});

recordable_->SetStartTime(NowOr(options.start_system_time));
start_steady_time = NowOr(options.start_steady_time);
processor_->OnStart(*recordable_);
Expand Down
1 change: 1 addition & 0 deletions sdk/src/trace/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class Span final : public trace_api::Span
std::shared_ptr<SpanProcessor> processor,
nostd::string_view name,
const opentelemetry::common::KeyValueIterable &attributes,
const trace_api::SpanContextKeyValueIterable &links,
const trace_api::StartSpanOptions &options,
const trace_api::SpanContext &parent_span_context) noexcept;

Expand Down
3 changes: 2 additions & 1 deletion sdk/src/trace/tracer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ trace_api::SpanContext GetCurrentSpanContext(const trace_api::SpanContext &expli
nostd::shared_ptr<trace_api::Span> Tracer::StartSpan(
nostd::string_view name,
const opentelemetry::common::KeyValueIterable &attributes,
const trace_api::SpanContextKeyValueIterable &links,
const trace_api::StartSpanOptions &options) noexcept
{
trace_api::SpanContext parent = GetCurrentSpanContext(options.parent);
Expand All @@ -72,7 +73,7 @@ nostd::shared_ptr<trace_api::Span> Tracer::StartSpan(
else
{
auto span = nostd::shared_ptr<trace_api::Span>{new (std::nothrow) Span{
this->shared_from_this(), processor_.load(), name, attributes, options, parent}};
this->shared_from_this(), processor_.load(), name, attributes, links, options, parent}};

// if the attributes is not nullptr, add attributes to the span.
if (sampling_result.attributes)
Expand Down
Loading