Support adding links to span (#351)
This commit is contained in:
parent
c504cfb51e
commit
2bab26e249
|
@ -68,9 +68,10 @@ public:
|
||||||
nostd::shared_ptr<trace::Span> StartSpan(
|
nostd::shared_ptr<trace::Span> StartSpan(
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const common::KeyValueIterable &attributes,
|
const common::KeyValueIterable &attributes,
|
||||||
|
const trace::SpanContextKeyValueIterable &links,
|
||||||
const trace::StartSpanOptions &options = {}) noexcept override
|
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)
|
if (span == nullptr)
|
||||||
{
|
{
|
||||||
return nostd::shared_ptr<trace::Span>(nullptr);
|
return nostd::shared_ptr<trace::Span>(nullptr);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "opentelemetry/nostd/unique_ptr.h"
|
#include "opentelemetry/nostd/unique_ptr.h"
|
||||||
#include "opentelemetry/trace/span.h"
|
#include "opentelemetry/trace/span.h"
|
||||||
#include "opentelemetry/trace/span_context.h"
|
#include "opentelemetry/trace/span_context.h"
|
||||||
|
#include "opentelemetry/trace/span_context_kv_iterable.h"
|
||||||
#include "opentelemetry/trace/tracer.h"
|
#include "opentelemetry/trace/tracer.h"
|
||||||
#include "opentelemetry/trace/tracer_provider.h"
|
#include "opentelemetry/trace/tracer_provider.h"
|
||||||
#include "opentelemetry/version.h"
|
#include "opentelemetry/version.h"
|
||||||
|
@ -66,6 +67,7 @@ public:
|
||||||
// Tracer
|
// Tracer
|
||||||
nostd::shared_ptr<Span> StartSpan(nostd::string_view /*name*/,
|
nostd::shared_ptr<Span> StartSpan(nostd::string_view /*name*/,
|
||||||
const common::KeyValueIterable & /*attributes*/,
|
const common::KeyValueIterable & /*attributes*/,
|
||||||
|
const SpanContextKeyValueIterable & /*links*/,
|
||||||
const StartSpanOptions & /*options*/) noexcept override
|
const StartSpanOptions & /*options*/) noexcept override
|
||||||
{
|
{
|
||||||
// Don't allocate a no-op span for every StartSpan call, but use a static
|
// Don't allocate a no-op span for every StartSpan call, but use a static
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
{
|
||||||
|
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(
|
||||||
|
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
|
|
@ -6,6 +6,7 @@
|
||||||
#include "opentelemetry/trace/default_span.h"
|
#include "opentelemetry/trace/default_span.h"
|
||||||
#include "opentelemetry/trace/scope.h"
|
#include "opentelemetry/trace/scope.h"
|
||||||
#include "opentelemetry/trace/span.h"
|
#include "opentelemetry/trace/span.h"
|
||||||
|
#include "opentelemetry/trace/span_context_kv_iterable_view.h"
|
||||||
#include "opentelemetry/version.h"
|
#include "opentelemetry/version.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
@ -33,12 +34,13 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
|
virtual nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
|
||||||
const common::KeyValueIterable &attributes,
|
const common::KeyValueIterable &attributes,
|
||||||
|
const SpanContextKeyValueIterable &links,
|
||||||
const StartSpanOptions &options = {}) noexcept = 0;
|
const StartSpanOptions &options = {}) noexcept = 0;
|
||||||
|
|
||||||
nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
|
nostd::shared_ptr<Span> StartSpan(nostd::string_view name,
|
||||||
const StartSpanOptions &options = {}) noexcept
|
const StartSpanOptions &options = {}) noexcept
|
||||||
{
|
{
|
||||||
return this->StartSpan(name, {}, options);
|
return this->StartSpan(name, {}, {}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
|
@ -47,7 +49,20 @@ public:
|
||||||
const T &attributes,
|
const T &attributes,
|
||||||
const StartSpanOptions &options = {}) noexcept
|
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::shared_ptr<Span> StartSpan(
|
||||||
|
@ -55,10 +70,60 @@ public:
|
||||||
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
|
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
|
||||||
const StartSpanOptions &options = {}) noexcept
|
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,
|
return this->StartSpan(name,
|
||||||
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
|
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
|
||||||
attributes.begin(), attributes.end()},
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -43,3 +43,15 @@ TEST(NoopTest, UseNoopTracers)
|
||||||
|
|
||||||
s1->GetContext();
|
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}}}});
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
Span(std::shared_ptr<Tracer> &&tracer,
|
Span(std::shared_ptr<Tracer> &&tracer,
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable & /*attributes*/,
|
const opentelemetry::common::KeyValueIterable & /*attributes*/,
|
||||||
|
const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/,
|
||||||
const trace::StartSpanOptions & /*options*/) noexcept
|
const trace::StartSpanOptions & /*options*/) noexcept
|
||||||
: tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()}
|
: tracer_{std::move(tracer)}, name_{name}, span_context_{trace::SpanContext::GetInvalid()}
|
||||||
{
|
{
|
||||||
|
@ -66,8 +67,9 @@ Tracer::Tracer(nostd::string_view /*output*/) {}
|
||||||
nostd::shared_ptr<trace::Span> Tracer::StartSpan(
|
nostd::shared_ptr<trace::Span> Tracer::StartSpan(
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable &attributes,
|
const opentelemetry::common::KeyValueIterable &attributes,
|
||||||
|
const opentelemetry::trace::SpanContextKeyValueIterable &links,
|
||||||
const trace::StartSpanOptions &options) noexcept
|
const trace::StartSpanOptions &options) noexcept
|
||||||
{
|
{
|
||||||
return nostd::shared_ptr<opentelemetry::trace::Span>{
|
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}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> StartSpan(
|
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> StartSpan(
|
||||||
opentelemetry::nostd::string_view name,
|
opentelemetry::nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable & /*attributes*/,
|
const opentelemetry::common::KeyValueIterable & /*attributes*/,
|
||||||
|
const opentelemetry::trace::SpanContextKeyValueIterable & /*links*/,
|
||||||
const opentelemetry::trace::StartSpanOptions & /*options */) noexcept override;
|
const opentelemetry::trace::StartSpanOptions & /*options */) noexcept override;
|
||||||
|
|
||||||
void ForceFlushWithMicroseconds(uint64_t /*timeout*/) noexcept override {}
|
void ForceFlushWithMicroseconds(uint64_t /*timeout*/) noexcept override {}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
nostd::shared_ptr<trace_api::Span> StartSpan(
|
nostd::shared_ptr<trace_api::Span> StartSpan(
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable &attributes,
|
const opentelemetry::common::KeyValueIterable &attributes,
|
||||||
|
const trace_api::SpanContextKeyValueIterable &links,
|
||||||
const trace_api::StartSpanOptions &options = {}) noexcept override;
|
const trace_api::StartSpanOptions &options = {}) noexcept override;
|
||||||
|
|
||||||
void ForceFlushWithMicroseconds(uint64_t timeout) noexcept override;
|
void ForceFlushWithMicroseconds(uint64_t timeout) noexcept override;
|
||||||
|
|
|
@ -61,6 +61,7 @@ Span::Span(std::shared_ptr<Tracer> &&tracer,
|
||||||
std::shared_ptr<SpanProcessor> processor,
|
std::shared_ptr<SpanProcessor> processor,
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable &attributes,
|
const opentelemetry::common::KeyValueIterable &attributes,
|
||||||
|
const trace_api::SpanContextKeyValueIterable &links,
|
||||||
const trace_api::StartSpanOptions &options,
|
const trace_api::StartSpanOptions &options,
|
||||||
const trace_api::SpanContext &parent_span_context) noexcept
|
const trace_api::SpanContext &parent_span_context) noexcept
|
||||||
: tracer_{std::move(tracer)},
|
: tracer_{std::move(tracer)},
|
||||||
|
@ -98,6 +99,12 @@ Span::Span(std::shared_ptr<Tracer> &&tracer,
|
||||||
return true;
|
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));
|
recordable_->SetStartTime(NowOr(options.start_system_time));
|
||||||
start_steady_time = NowOr(options.start_steady_time);
|
start_steady_time = NowOr(options.start_steady_time);
|
||||||
processor_->OnStart(*recordable_);
|
processor_->OnStart(*recordable_);
|
||||||
|
|
|
@ -19,6 +19,7 @@ public:
|
||||||
std::shared_ptr<SpanProcessor> processor,
|
std::shared_ptr<SpanProcessor> processor,
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable &attributes,
|
const opentelemetry::common::KeyValueIterable &attributes,
|
||||||
|
const trace_api::SpanContextKeyValueIterable &links,
|
||||||
const trace_api::StartSpanOptions &options,
|
const trace_api::StartSpanOptions &options,
|
||||||
const trace_api::SpanContext &parent_span_context) noexcept;
|
const trace_api::SpanContext &parent_span_context) noexcept;
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ trace_api::SpanContext GetCurrentSpanContext(const trace_api::SpanContext &expli
|
||||||
nostd::shared_ptr<trace_api::Span> Tracer::StartSpan(
|
nostd::shared_ptr<trace_api::Span> Tracer::StartSpan(
|
||||||
nostd::string_view name,
|
nostd::string_view name,
|
||||||
const opentelemetry::common::KeyValueIterable &attributes,
|
const opentelemetry::common::KeyValueIterable &attributes,
|
||||||
|
const trace_api::SpanContextKeyValueIterable &links,
|
||||||
const trace_api::StartSpanOptions &options) noexcept
|
const trace_api::StartSpanOptions &options) noexcept
|
||||||
{
|
{
|
||||||
trace_api::SpanContext parent = GetCurrentSpanContext(options.parent);
|
trace_api::SpanContext parent = GetCurrentSpanContext(options.parent);
|
||||||
|
@ -72,7 +73,7 @@ nostd::shared_ptr<trace_api::Span> Tracer::StartSpan(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto span = nostd::shared_ptr<trace_api::Span>{new (std::nothrow) Span{
|
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 the attributes is not nullptr, add attributes to the span.
|
||||||
if (sampling_result.attributes)
|
if (sampling_result.attributes)
|
||||||
|
|
|
@ -13,6 +13,7 @@ using opentelemetry::core::SteadyTimestamp;
|
||||||
using opentelemetry::core::SystemTimestamp;
|
using opentelemetry::core::SystemTimestamp;
|
||||||
namespace nostd = opentelemetry::nostd;
|
namespace nostd = opentelemetry::nostd;
|
||||||
namespace common = opentelemetry::common;
|
namespace common = opentelemetry::common;
|
||||||
|
using opentelemetry::common::KeyValueIterableView;
|
||||||
using opentelemetry::exporter::memory::InMemorySpanData;
|
using opentelemetry::exporter::memory::InMemorySpanData;
|
||||||
using opentelemetry::exporter::memory::InMemorySpanExporter;
|
using opentelemetry::exporter::memory::InMemorySpanExporter;
|
||||||
using opentelemetry::trace::SpanContext;
|
using opentelemetry::trace::SpanContext;
|
||||||
|
@ -332,6 +333,83 @@ TEST(Tracer, SpanSetEvents)
|
||||||
ASSERT_EQ(1, span_data_events[2].GetAttributes().size());
|
ASSERT_EQ(1, span_data_events[2].GetAttributes().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Tracer, SpanSetLinks)
|
||||||
|
{
|
||||||
|
std::unique_ptr<InMemorySpanExporter> exporter(new InMemorySpanExporter());
|
||||||
|
std::shared_ptr<InMemorySpanData> span_data = exporter->GetData();
|
||||||
|
auto tracer = initTracer(std::move(exporter));
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// Single span link passed through Initialization list
|
||||||
|
tracer->StartSpan("efg", {{"attr1", 1}}, {{SpanContext(false, false), {{"attr2", 2}}}})->End();
|
||||||
|
auto spans = span_data->GetSpans();
|
||||||
|
ASSERT_EQ(1, spans.size());
|
||||||
|
|
||||||
|
auto &span_data_links = spans.at(0)->GetLinks();
|
||||||
|
ASSERT_EQ(1, span_data_links.size());
|
||||||
|
auto link = span_data_links.at(0);
|
||||||
|
ASSERT_EQ(nostd::get<int>(link.GetAttributes().at("attr2")), 2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
|
||||||
|
// Multiple span links passed through Initialization list
|
||||||
|
tracer
|
||||||
|
->StartSpan("efg", {{"attr1", 1}},
|
||||||
|
{{SpanContext(false, false), {{"attr2", 2}}},
|
||||||
|
{SpanContext(false, false), {{"attr3", 3}}}})
|
||||||
|
->End();
|
||||||
|
auto spans = span_data->GetSpans();
|
||||||
|
ASSERT_EQ(1, spans.size());
|
||||||
|
|
||||||
|
auto &span_data_links = spans.at(0)->GetLinks();
|
||||||
|
ASSERT_EQ(2, span_data_links.size());
|
||||||
|
auto link1 = span_data_links.at(0);
|
||||||
|
ASSERT_EQ(nostd::get<int>(link1.GetAttributes().at("attr2")), 2);
|
||||||
|
auto link2 = span_data_links.at(1);
|
||||||
|
ASSERT_EQ(nostd::get<int>(link2.GetAttributes().at("attr3")), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// Multiple links, each with multiple attributes passed through Initialization list
|
||||||
|
tracer
|
||||||
|
->StartSpan("efg", {{"attr1", 1}},
|
||||||
|
{{SpanContext(false, false), {{"attr2", 2}, {"attr3", 3}}},
|
||||||
|
{SpanContext(false, false), {{"attr4", 4}}}})
|
||||||
|
->End();
|
||||||
|
auto spans = span_data->GetSpans();
|
||||||
|
ASSERT_EQ(1, spans.size());
|
||||||
|
|
||||||
|
auto &span_data_links = spans.at(0)->GetLinks();
|
||||||
|
ASSERT_EQ(2, span_data_links.size());
|
||||||
|
auto link1 = span_data_links.at(0);
|
||||||
|
ASSERT_EQ(nostd::get<int>(link1.GetAttributes().at("attr2")), 2);
|
||||||
|
ASSERT_EQ(nostd::get<int>(link1.GetAttributes().at("attr3")), 3);
|
||||||
|
auto link2 = span_data_links.at(1);
|
||||||
|
ASSERT_EQ(nostd::get<int>(link2.GetAttributes().at("attr4")), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> attrs1 = {{"attr1", "1"}, {"attr2", "2"}};
|
||||||
|
std::map<std::string, std::string> attrs2 = {{"attr3", "3"}, {"attr4", "4"}};
|
||||||
|
|
||||||
|
std::vector<std::pair<SpanContext, std::map<std::string, std::string>>> links = {
|
||||||
|
{SpanContext(false, false), attrs1}, {SpanContext(false, false), attrs2}};
|
||||||
|
tracer->StartSpan("efg", attrs1, links)->End();
|
||||||
|
auto spans = span_data->GetSpans();
|
||||||
|
|
||||||
|
auto &span_data_links = spans.at(0)->GetLinks();
|
||||||
|
ASSERT_EQ(2, span_data_links.size());
|
||||||
|
auto link1 = span_data_links.at(0);
|
||||||
|
ASSERT_EQ(nostd::get<std::string>(link1.GetAttributes().at("attr1")), "1");
|
||||||
|
ASSERT_EQ(nostd::get<std::string>(link1.GetAttributes().at("attr2")), "2");
|
||||||
|
auto link2 = span_data_links.at(1);
|
||||||
|
ASSERT_EQ(nostd::get<std::string>(link2.GetAttributes().at("attr3")), "3");
|
||||||
|
ASSERT_EQ(nostd::get<std::string>(link2.GetAttributes().at("attr4")), "4");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Tracer, TestAlwaysOnSampler)
|
TEST(Tracer, TestAlwaysOnSampler)
|
||||||
{
|
{
|
||||||
std::unique_ptr<InMemorySpanExporter> exporter(new InMemorySpanExporter());
|
std::unique_ptr<InMemorySpanExporter> exporter(new InMemorySpanExporter());
|
||||||
|
|
Loading…
Reference in New Issue