From 1078d634aa23c4c280a1bf5a50dba1c991985c52 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 17:42:28 +0530 Subject: [PATCH 01/16] draft --- examples/http/tracer_common.hpp | 6 +- ext/test/w3c_tracecontext_test/main.cc | 4 +- .../zpages/tracez_data_aggregator_test.cc | 7 +- ext/test/zpages/tracez_processor_test.cc | 11 +- .../sdk/trace/multi_recordable.h | 147 ++++++++++++++++++ .../sdk/trace/multi_span_processor.h | 114 ++++++++++++++ sdk/include/opentelemetry/sdk/trace/tracer.h | 4 +- .../opentelemetry/sdk/trace/tracer_context.h | 7 +- .../opentelemetry/sdk/trace/tracer_provider.h | 8 +- sdk/src/trace/span.cc | 6 +- sdk/src/trace/tracer_context.cc | 15 +- sdk/src/trace/tracer_provider.cc | 13 +- sdk/test/trace/sampler_benchmark.cc | 10 +- sdk/test/trace/tracer_provider_test.cc | 21 ++- sdk/test/trace/tracer_test.cc | 11 +- 15 files changed, 342 insertions(+), 42 deletions(-) create mode 100644 sdk/include/opentelemetry/sdk/trace/multi_recordable.h create mode 100644 sdk/include/opentelemetry/sdk/trace/multi_span_processor.h diff --git a/examples/http/tracer_common.hpp b/examples/http/tracer_common.hpp index 19239890c6..472d6bf80c 100644 --- a/examples/http/tracer_common.hpp +++ b/examples/http/tracer_common.hpp @@ -4,7 +4,7 @@ #include "opentelemetry/sdk/trace/tracer_provider.h" #include "opentelemetry/trace/provider.h" -#include +#include namespace { @@ -13,8 +13,10 @@ void initTracer() { new opentelemetry::exporter::trace::OStreamSpanExporter); auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); + std::vector> processors; + processors.push_back(std::move(processor)); // Default is an always-on sampler. - auto context = std::make_shared(std::move(processor)); + auto context = std::make_shared(std::move(processors)); auto provider = nostd::shared_ptr( new sdktrace::TracerProvider(context)); // Set the global trace provider diff --git a/ext/test/w3c_tracecontext_test/main.cc b/ext/test/w3c_tracecontext_test/main.cc index fc26801079..cd9554106e 100644 --- a/ext/test/w3c_tracecontext_test/main.cc +++ b/ext/test/w3c_tracecontext_test/main.cc @@ -40,7 +40,9 @@ void initTracer() new opentelemetry::exporter::trace::OStreamSpanExporter); auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); - auto context = std::make_shared(std::move(processor)); + std::vector> processors; + processors.push_back(std::move(processor)); + auto context = std::make_shared(std::move(processors)); auto provider = nostd::shared_ptr( new sdktrace::TracerProvider(context)); // Set the global trace provider diff --git a/ext/test/zpages/tracez_data_aggregator_test.cc b/ext/test/zpages/tracez_data_aggregator_test.cc index 324cf0c612..cf64a266c2 100644 --- a/ext/test/zpages/tracez_data_aggregator_test.cc +++ b/ext/test/zpages/tracez_data_aggregator_test.cc @@ -36,8 +36,11 @@ class TracezDataAggregatorTest : public ::testing::Test { std::shared_ptr shared_data(new TracezSharedData()); auto resource = opentelemetry::sdk::resource::Resource::Create({}); - auto context = std::make_shared( - std::unique_ptr(new TracezSpanProcessor(shared_data)), resource); + std::unique_ptr processor(new TracezSpanProcessor(shared_data)); + std::vector> processors; + processors.push_back(std::move(processor)); + + auto context = std::make_shared(std::move(processors), resource); tracer = std::shared_ptr(new Tracer(context)); tracez_data_aggregator = std::unique_ptr( new TracezDataAggregator(shared_data, milliseconds(10))); diff --git a/ext/test/zpages/tracez_processor_test.cc b/ext/test/zpages/tracez_processor_test.cc index 7ea4063d60..208b67c96a 100644 --- a/ext/test/zpages/tracez_processor_test.cc +++ b/ext/test/zpages/tracez_processor_test.cc @@ -175,13 +175,16 @@ class TracezProcessor : public ::testing::Test protected: void SetUp() override { - shared_data = std::shared_ptr(new TracezSharedData()); - processor = std::shared_ptr(new TracezSpanProcessor(shared_data)); + shared_data = std::shared_ptr(new TracezSharedData()); + processor = std::shared_ptr(new TracezSpanProcessor(shared_data)); + std::unique_ptr processor2(new TracezSpanProcessor(shared_data)); + std::vector> processors; + processors.push_back(std::move(processor2)); auto resource = opentelemetry::sdk::resource::Resource::Create({}); + // Note: we make a *different* processor for the tracercontext. THis is because // all the tests use shared data, and we want to make sure this works correctly. - auto context = std::make_shared( - std::unique_ptr(new TracezSpanProcessor(shared_data)), resource); + auto context = std::make_shared(std::move(processors), resource); tracer = std::shared_ptr(new Tracer(context)); auto spans = shared_data->GetSpanSnapshot(); diff --git a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h new file mode 100644 index 0000000000..a5b7313df3 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h @@ -0,0 +1,147 @@ +#pragma once + +#include "opentelemetry/sdk/trace/processor.h" +#include "opentelemetry/sdk/trace/recordable.h" +#include "opentelemetry/version.h" + +#include + +// TODO: Create generic short pattern for opentelemetry::common and opentelemetry::trace + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ +namespace +{ +std::size_t MakeKey(const SpanProcessor &processor) +{ + return reinterpret_cast(&processor); +} + +} // namespace + +/** + * Maintains a representation of a span in a format that can be processed by a recorder. + * + * This class is thread-compatible. + */ +class MultiRecordable : public Recordable +{ +public: + void AddRecordable(const SpanProcessor &processor, + std::unique_ptr recordable) noexcept + { + recordables_[MakeKey(processor)] = std::move(recordable); + } + + const std::unique_ptr &GetRecordable(const SpanProcessor &processor) const noexcept + { + // TODO - return nullptr ref on failed lookup? + static std::unique_ptr empty(nullptr); + auto i = recordables_.find(MakeKey(processor)); + if (i != recordables_.end()) + { + return i->second; + } + return empty; + } + + std::unique_ptr ReleaseRecordable(const SpanProcessor &processor) noexcept + { + auto i = recordables_.find(MakeKey(processor)); + if (i != recordables_.end()) + { + std::unique_ptr result(i->second.release()); + recordables_.erase(MakeKey(processor)); + return result; + } + return std::unique_ptr(nullptr); + } + + void SetIdentity(const opentelemetry::trace::SpanContext &span_context, + opentelemetry::trace::SpanId parent_span_id) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetIdentity(span_context, parent_span_id); + } + } + + virtual void SetAttribute(nostd::string_view key, + const opentelemetry::common::AttributeValue &value) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetAttribute(key, value); + } + } + + virtual void AddEvent(nostd::string_view name, + core::SystemTimestamp timestamp, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override + { + + for (auto &recordable : recordables_) + { + recordable.second->AddEvent(name, timestamp, attributes); + } + } + + virtual void AddLink(const opentelemetry::trace::SpanContext &span_context, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->AddLink(span_context, attributes); + } + } + + virtual void SetStatus(opentelemetry::trace::StatusCode code, + nostd::string_view description) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetStatus(code, description); + } + } + + virtual void SetName(nostd::string_view name) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetName(name); + } + } + + virtual void SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetSpanKind(span_kind); + } + } + + virtual void SetStartTime(opentelemetry::core::SystemTimestamp start_time) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetStartTime(start_time); + } + } + + virtual void SetDuration(std::chrono::nanoseconds duration) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetDuration(duration); + } + } + +private: + std::map> recordables_; +}; +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h new file mode 100644 index 0000000000..dbd4cc2090 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h @@ -0,0 +1,114 @@ +#pragma once + +#include +#include + +#include "opentelemetry/sdk/trace/multi_recordable.h" +#include "opentelemetry/sdk/trace/processor.h" + +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ + +/** Instantiation options. */ +struct MultiSpanProcessorOptions +{}; + +/** + * Span processor allow hooks for span start and end method invocations. + * + * Built-in span processors are responsible for batching and conversion of + * spans to exportable representation and passing batches to exporters. + */ +class MultiSpanProcessor : public SpanProcessor +{ +public: + MultiSpanProcessor(std::vector> &&processors) + { + for (auto &processor : processors) + { + std::cout << " \nAdding processor..."; + if (processor) + processors_.push_back(std::move(processor)); + } + } + + void AddProcessor(std::unique_ptr &&processor) + { + processors_.push_back(std::move(processor)); + } + + std::unique_ptr MakeRecordable() noexcept override + { + std::cout << " Make recordable"; + auto recordable = std::unique_ptr(new MultiRecordable); + auto multi_recordable = static_cast(recordable.get()); + for (auto &processor : processors_) + { + multi_recordable->AddRecordable(*processor, processor->MakeRecordable()); + } + return recordable; + } + + virtual void OnStart(Recordable &span, + const opentelemetry::trace::SpanContext &parent_context) noexcept override + { + auto multi_recordable = static_cast(&span); + + for (auto &processor : processors_) + { + auto &recordable = multi_recordable->GetRecordable(*processor); + if (recordable != nullptr) + { + processor->OnStart(*recordable, parent_context); + } + } + } + + virtual void OnEnd(std::unique_ptr &&span) noexcept override + { + auto multi_recordable = static_cast(span.release()); + for (auto &processor : processors_) + { + auto recordable = multi_recordable->ReleaseRecordable(*processor); + if (recordable != nullptr) + { + processor->OnEnd(std::move(recordable)); + } + } + } + + bool ForceFlush( + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override + { + bool result = true; + for (auto &processor : processors_) + { + result |= processor->ForceFlush(timeout); + } + return result; + } + + bool Shutdown( + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override + { + bool result = true; + for (auto &processor : processors_) + { + result |= processor->Shutdown(timeout); + } + return result; + } + + ~MultiSpanProcessor() { Shutdown(); } + +private: + std::vector> processors_; +}; +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/trace/tracer.h b/sdk/include/opentelemetry/sdk/trace/tracer.h index f764c48478..a25c517d81 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer.h @@ -32,8 +32,8 @@ class Tracer final : public trace_api::Tracer, public std::enable_shared_from_th void CloseWithMicroseconds(uint64_t timeout) noexcept override; - /** Returns the currently active span processor. */ - SpanProcessor &GetActiveProcessor() noexcept { return context_->GetActiveProcessor(); } + /** Returns the configured span processor. */ + SpanProcessor &GetProcessor() noexcept { return context_->GetProcessor(); } // Note: Test only Sampler &GetSampler() { return context_->GetSampler(); } diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/sdk/include/opentelemetry/sdk/trace/tracer_context.h index e5af3a87ba..218df6e09c 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_context.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_context.h @@ -28,18 +28,19 @@ namespace trace class TracerContext { public: - explicit TracerContext(std::unique_ptr processor, + explicit TracerContext(std::vector> &&processor, opentelemetry::sdk::resource::Resource resource = opentelemetry::sdk::resource::Resource::Create({}), std::unique_ptr sampler = std::unique_ptr(new AlwaysOnSampler)) noexcept; + /** * Attaches a span processor to this tracer context. * * @param processor The new span processor for this tracer. This must not be * a nullptr. Ownership is given to the `TracerContext`. */ - void RegisterPipeline(std::unique_ptr processor) noexcept; + void AddProcessor(std::unique_ptr processor) noexcept; /** * Obtain the sampler associated with this tracer. @@ -53,7 +54,7 @@ class TracerContext * Note: When more than one processor is active, this will * return an "aggregate" processor */ - SpanProcessor &GetActiveProcessor() const noexcept; + SpanProcessor &GetProcessor() const noexcept; /** * Obtain the resource associated with this tracer context. diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 0301aa7e44..6584d61c8c 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -50,7 +50,7 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider * * Note: This process may not receive any in-flight spans, but will get newly created spans. */ - void RegisterPipeline(std::unique_ptr processor) noexcept; + void AddProcessor(std::unique_ptr processor) noexcept; /** * Obtain the resource associated with this tracer provider. @@ -58,6 +58,12 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider */ const opentelemetry::sdk::resource::Resource &GetResource() const noexcept; + /** + * Obtain the span processor associated with this tracer provider. + * @return The span processor for this tracer provider. + */ + std::shared_ptr GetProcessor() const noexcept; + /** * Shutdown the span processor associated with this tracer provider. */ diff --git a/sdk/src/trace/span.cc b/sdk/src/trace/span.cc index 388d0ab923..331f97685b 100644 --- a/sdk/src/trace/span.cc +++ b/sdk/src/trace/span.cc @@ -66,7 +66,7 @@ Span::Span(std::shared_ptr &&tracer, const nostd::shared_ptr trace_state, const bool sampled) noexcept : tracer_{std::move(tracer)}, - recordable_{tracer_->GetActiveProcessor().MakeRecordable()}, + recordable_{tracer_->GetProcessor().MakeRecordable()}, start_steady_time{options.start_steady_time}, has_ended_{false} { @@ -119,7 +119,7 @@ Span::Span(std::shared_ptr &&tracer, start_steady_time = NowOr(options.start_steady_time); // recordable_->SetResource(tracer_->GetResoource()); TODO // recordable_->SetResource(tracer_->GetInstrumentationLibrary()); TODO - tracer_->GetActiveProcessor().OnStart(*recordable_, parent_span_context); + tracer_->GetProcessor().OnStart(*recordable_, parent_span_context); } Span::~Span() @@ -206,7 +206,7 @@ void Span::End(const trace_api::EndSpanOptions &options) noexcept recordable_->SetDuration(std::chrono::steady_clock::time_point(end_steady_time) - std::chrono::steady_clock::time_point(start_steady_time)); - tracer_->GetActiveProcessor().OnEnd(std::move(recordable_)); + tracer_->GetProcessor().OnEnd(std::move(recordable_)); recordable_.reset(); } diff --git a/sdk/src/trace/tracer_context.cc b/sdk/src/trace/tracer_context.cc index a463ec81d4..f0910f699f 100644 --- a/sdk/src/trace/tracer_context.cc +++ b/sdk/src/trace/tracer_context.cc @@ -1,5 +1,5 @@ #include "opentelemetry/sdk/trace/tracer_context.h" -#include "opentelemetry/sdk/trace/processor.h" +#include "opentelemetry/sdk/trace/multi_span_processor.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -7,10 +7,12 @@ namespace sdk namespace trace { -TracerContext::TracerContext(std::unique_ptr processor, +TracerContext::TracerContext(std::vector> &&processors, opentelemetry::sdk::resource::Resource resource, std::unique_ptr sampler) noexcept - : processor_(std::move(processor)), resource_(resource), sampler_(std::move(sampler)) + : resource_(resource), + sampler_(std::move(sampler)), + processor_(std::unique_ptr(new MultiSpanProcessor(std::move(processors)))) {} Sampler &TracerContext::GetSampler() const noexcept @@ -23,8 +25,11 @@ const opentelemetry::sdk::resource::Resource &TracerContext::GetResource() const return resource_; } -void TracerContext::RegisterPipeline(std::unique_ptr processor) noexcept +void TracerContext::AddProcessor(std::unique_ptr processor) noexcept { + + auto multi_processor = static_cast(processor_.Get()); + multi_processor->AddProcessor(std::move(processor)); // TODO(jsuereth): Implement // 1. If existing processor is an "AggregateProcessor" append the new processor to it. // 2. If the existing processor is NOT an "AggregateProcessor", create a new Aggregate of this and @@ -32,7 +37,7 @@ void TracerContext::RegisterPipeline(std::unique_ptr processor) n // then replace our atomic ptr with the new aggregate. } -SpanProcessor &TracerContext::GetActiveProcessor() const noexcept +SpanProcessor &TracerContext::GetProcessor() const noexcept { return *processor_; } diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 0eaf6782f2..00b2b65ae0 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -12,9 +12,12 @@ TracerProvider::TracerProvider(std::shared_ptr contex TracerProvider::TracerProvider(std::unique_ptr processor, opentelemetry::sdk::resource::Resource resource, std::unique_ptr sampler) noexcept - : TracerProvider( - std::make_shared(std::move(processor), resource, std::move(sampler))) -{} +{ + std::vector> processors; + processors.push_back(std::move(processor)); + *this = TracerProvider( + std::make_shared(std::move(processors), resource, std::move(sampler))); +} opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( nostd::string_view library_name, @@ -23,9 +26,9 @@ opentelemetry::nostd::shared_ptr TracerProvider::G return opentelemetry::nostd::shared_ptr(tracer_); } -void TracerProvider::RegisterPipeline(std::unique_ptr processor) noexcept +void TracerProvider::AddProcessor(std::unique_ptr processor) noexcept { - return context_->RegisterPipeline(std::move(processor)); + context_->AddProcessor(std::move(processor)); } const opentelemetry::sdk::resource::Resource &TracerProvider::GetResource() const noexcept diff --git a/sdk/test/trace/sampler_benchmark.cc b/sdk/test/trace/sampler_benchmark.cc index 90a07adc77..6cfe67d1f7 100644 --- a/sdk/test/trace/sampler_benchmark.cc +++ b/sdk/test/trace/sampler_benchmark.cc @@ -118,10 +118,12 @@ BENCHMARK(BM_TraceIdRatioBasedSamplerShouldSample); void BenchmarkSpanCreation(std::shared_ptr sampler, benchmark::State &state) { std::unique_ptr exporter(new InMemorySpanExporter()); - auto processor = std::unique_ptr(new SimpleSpanProcessor(std::move(exporter))); - auto context = std::make_shared(std::move(processor)); - auto resource = opentelemetry::sdk::resource::Resource::Create({}); - auto tracer = std::shared_ptr(new Tracer(context)); + std::unique_ptr processor(new SimpleSpanProcessor(std::move(exporter))); + std::vector> processors; + processors.push_back(std::move(processor)); + auto context = std::make_shared(std::move(processors)); + auto resource = opentelemetry::sdk::resource::Resource::Create({}); + auto tracer = std::shared_ptr(new Tracer(context)); while (state.KeepRunning()) { diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index 55a5a9be44..b371d192a5 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -13,8 +13,9 @@ using namespace opentelemetry::sdk::resource; TEST(TracerProvider, GetTracer) { std::unique_ptr processor(new SimpleSpanProcessor(nullptr)); - - TracerProvider tp1(std::make_shared(std::move(processor), Resource::Create({}))); + std::vector> processors; + processors.push_back(std::move(processor)); + TracerProvider tp1(std::make_shared(std::move(processors), Resource::Create({}))); auto t1 = tp1.GetTracer("test"); auto t2 = tp1.GetTracer("test"); auto t3 = tp1.GetTracer("different", "1.0.0"); @@ -31,18 +32,24 @@ TEST(TracerProvider, GetTracer) auto sdkTracer1 = dynamic_cast(t1.get()); ASSERT_NE(nullptr, sdkTracer1); ASSERT_EQ("AlwaysOnSampler", sdkTracer1->GetSampler().GetDescription()); - TracerProvider tp2(std::make_shared( - std::unique_ptr(new SimpleSpanProcessor(nullptr)), Resource::Create({}), - std::unique_ptr(new AlwaysOffSampler()))); + + std::unique_ptr processor2(new SimpleSpanProcessor(nullptr)); + std::vector> processors2; + processors2.push_back(std::move(processor2)); + TracerProvider tp2( + std::make_shared(std::move(processors2), Resource::Create({}), + std::unique_ptr(new AlwaysOffSampler()))); auto sdkTracer2 = dynamic_cast(tp2.GetTracer("test").get()); ASSERT_EQ("AlwaysOffSampler", sdkTracer2->GetSampler().GetDescription()); } TEST(TracerProvider, Shutdown) { - std::unique_ptr processor1(new SimpleSpanProcessor(nullptr)); + std::unique_ptr processor(new SimpleSpanProcessor(nullptr)); + std::vector> processors; + processors.push_back(std::move(processor)); - TracerProvider tp1(std::make_shared(std::move(processor1))); + TracerProvider tp1(std::make_shared(std::move(processors))); EXPECT_TRUE(tp1.Shutdown()); } diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index 176a949670..30e2a44380 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -50,7 +50,9 @@ namespace std::shared_ptr initTracer(std::unique_ptr &&exporter) { auto processor = std::unique_ptr(new SimpleSpanProcessor(std::move(exporter))); - auto context = std::make_shared(std::move(processor)); + std::vector> processors; + processors.push_back(std::move(processor)); + auto context = std::make_shared(std::move(processors)); return std::shared_ptr(new Tracer(context)); } @@ -60,11 +62,14 @@ std::shared_ptr initTracer( Sampler *sampler) { auto processor = std::unique_ptr(new SimpleSpanProcessor(std::move(exporter))); - auto resource = Resource::Create({}); - auto context = std::make_shared(std::move(processor), resource, + std::vector> processors; + processors.push_back(std::move(processor)); + auto resource = Resource::Create({}); + auto context = std::make_shared(std::move(processors), resource, std::unique_ptr(sampler)); return std::shared_ptr(new Tracer(context)); } + } // namespace TEST(Tracer, ToInMemorySpanExporter) From 78740ebf992aecff5e4f76a8e58e8d498cd60ec5 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 18:56:14 +0530 Subject: [PATCH 02/16] memory leak --- examples/CMakeLists.txt | 1 + examples/multi_processor/BUILD | 25 +++++++++++ examples/multi_processor/CMakeLists.txt | 10 +++++ examples/multi_processor/README.md | 12 +++++ .../foo_library/foo_library.cc | 42 +++++++++++++++++ .../multi_processor/foo_library/foo_library.h | 3 ++ examples/multi_processor/main.cc | 45 +++++++++++++++++++ .../sdk/trace/multi_span_processor.h | 1 + 8 files changed, 139 insertions(+) create mode 100644 examples/multi_processor/BUILD create mode 100644 examples/multi_processor/CMakeLists.txt create mode 100644 examples/multi_processor/README.md create mode 100644 examples/multi_processor/foo_library/foo_library.cc create mode 100644 examples/multi_processor/foo_library/foo_library.h create mode 100644 examples/multi_processor/main.cc diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3d5299a444..8aec6526a6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(simple) add_subdirectory(batch) add_subdirectory(metrics_simple) add_subdirectory(multithreaded) +add_subdirectory(multi_processor) add_subdirectory(http) diff --git a/examples/multi_processor/BUILD b/examples/multi_processor/BUILD new file mode 100644 index 0000000000..a8e843e29d --- /dev/null +++ b/examples/multi_processor/BUILD @@ -0,0 +1,25 @@ +cc_library( + name = "foo_library", + srcs = [ + "foo_library/foo_library.cc", + ], + hdrs = [ + "foo_library/foo_library.h", + ], + deps = [ + "//api", + ], +) + +cc_binary( + name = "example_simple", + srcs = [ + "main.cc", + ], + deps = [ + ":foo_library", + "//api", + "//exporters/ostream:ostream_span_exporter", + "//sdk/src/trace", + ], +) diff --git a/examples/multi_processor/CMakeLists.txt b/examples/multi_processor/CMakeLists.txt new file mode 100644 index 0000000000..65c7c2e510 --- /dev/null +++ b/examples/multi_processor/CMakeLists.txt @@ -0,0 +1,10 @@ +include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include + ${CMAKE_SOURCE_DIR}/exporters/memory/include) + +add_library(foo_multi_library foo_library/foo_library.cc) +target_link_libraries(foo_multi_library opentelemetry_exporter_ostream_span + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) + +add_executable(example_multi_processor main.cc) +target_link_libraries(example_multi_processor ${CMAKE_THREAD_LIBS_INIT} + foo_multi_library opentelemetry_trace) diff --git a/examples/multi_processor/README.md b/examples/multi_processor/README.md new file mode 100644 index 0000000000..b3c449c539 --- /dev/null +++ b/examples/multi_processor/README.md @@ -0,0 +1,12 @@ + +# Simple Trace Example + +In this example, the application in `main.cc` initializes and registers a tracer +provider from the [OpenTelemetry +SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then +calls a `foo_library` which has been instrumented using the [OpenTelemetry +API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api). +Resulting telemetry is directed to stdout through the StdoutSpanExporter. + +See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and +running the example. diff --git a/examples/multi_processor/foo_library/foo_library.cc b/examples/multi_processor/foo_library/foo_library.cc new file mode 100644 index 0000000000..73077f135e --- /dev/null +++ b/examples/multi_processor/foo_library/foo_library.cc @@ -0,0 +1,42 @@ +#include "opentelemetry/trace/provider.h" + +namespace trace = opentelemetry::trace; +namespace nostd = opentelemetry::nostd; + +namespace +{ +nostd::shared_ptr get_tracer() +{ + auto provider = trace::Provider::GetTracerProvider(); + return provider->GetTracer("foo_library"); +} + +void f1() +{ + auto span = get_tracer()->StartSpan("f1"); + auto scope = get_tracer()->WithActiveSpan(span); + + span->End(); +} + +void f2() +{ + auto span = get_tracer()->StartSpan("f2"); + auto scope = get_tracer()->WithActiveSpan(span); + + f1(); + f1(); + + span->End(); +} +} // namespace + +void foo_library() +{ + auto span = get_tracer()->StartSpan("library"); + auto scope = get_tracer()->WithActiveSpan(span); + + f2(); + + span->End(); +} diff --git a/examples/multi_processor/foo_library/foo_library.h b/examples/multi_processor/foo_library/foo_library.h new file mode 100644 index 0000000000..7ac75c0e50 --- /dev/null +++ b/examples/multi_processor/foo_library/foo_library.h @@ -0,0 +1,3 @@ +#pragma once + +void foo_library(); diff --git a/examples/multi_processor/main.cc b/examples/multi_processor/main.cc new file mode 100644 index 0000000000..047cb4e790 --- /dev/null +++ b/examples/multi_processor/main.cc @@ -0,0 +1,45 @@ +#include "opentelemetry/sdk/trace/simple_processor.h" +#include "opentelemetry/sdk/trace/tracer_context.h" +#include "opentelemetry/sdk/trace/tracer_provider.h" +#include "opentelemetry/trace/provider.h" + +// Using an exporter that simply dumps span data to stdout. +#include "foo_library/foo_library.h" +#include "opentelemetry/exporters/memory/in_memory_span_exporter.h" +#include "opentelemetry/exporters/ostream/span_exporter.h" + +namespace +{ +void initTracer() +{ + auto exporter1 = std::unique_ptr( + new opentelemetry::exporter::trace::OStreamSpanExporter); + auto processor1 = std::unique_ptr( + new sdktrace::SimpleSpanProcessor(std::move(exporter1))); + + auto exporter2 = std::unique_ptr( + new opentelemetry::exporter::memory::InMemorySpanExporter()); + auto processor2 = std::unique_ptr( + new sdktrace::SimpleSpanProcessor(std::move(exporter2))); + + std::vector> processors; + processors.push_back(std::move(processor1)); + processors.push_back(std::move(processor2)); + // Default is an always-on sampler. + auto context = std::make_shared(std::move(processors)); + + auto provider = nostd::shared_ptr( + new sdktrace::TracerProvider(context)); + + // Set the global trace provider + opentelemetry::trace::Provider::SetTracerProvider(provider); +} +} // namespace + +int main() +{ + // Removing this line will leave the default noop TracerProvider in place. + initTracer(); + + foo_library(); +} diff --git a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h index dbd4cc2090..7bb11e6bf4 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h @@ -80,6 +80,7 @@ class MultiSpanProcessor : public SpanProcessor processor->OnEnd(std::move(recordable)); } } + delete multi_recordable; } bool ForceFlush( From ac1384b14d1a81af06c588973e78601bc6d108fb Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 19:01:46 +0530 Subject: [PATCH 03/16] remove example --- examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8aec6526a6..3d5299a444 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,5 +6,4 @@ add_subdirectory(simple) add_subdirectory(batch) add_subdirectory(metrics_simple) add_subdirectory(multithreaded) -add_subdirectory(multi_processor) add_subdirectory(http) From 74df87ad0ddb5baa9deadde2a4382c569c2f73c3 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 19:12:20 +0530 Subject: [PATCH 04/16] add example back --- examples/CMakeLists.txt | 1 + examples/multi_processor/BUILD | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3d5299a444..8aec6526a6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(simple) add_subdirectory(batch) add_subdirectory(metrics_simple) add_subdirectory(multithreaded) +add_subdirectory(multi_processor) add_subdirectory(http) diff --git a/examples/multi_processor/BUILD b/examples/multi_processor/BUILD index a8e843e29d..91045a6f95 100644 --- a/examples/multi_processor/BUILD +++ b/examples/multi_processor/BUILD @@ -1,5 +1,5 @@ cc_library( - name = "foo_library", + name = "foo_multi_library", srcs = [ "foo_library/foo_library.cc", ], @@ -12,12 +12,12 @@ cc_library( ) cc_binary( - name = "example_simple", + name = "example_multi_processor", srcs = [ "main.cc", ], deps = [ - ":foo_library", + ":foo_multi_library", "//api", "//exporters/ostream:ostream_span_exporter", "//sdk/src/trace", From 544f51148e8e51d65cc3e88e935ec842289ab1db Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 19:21:12 +0530 Subject: [PATCH 05/16] fix example --- examples/multi_processor/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/multi_processor/BUILD b/examples/multi_processor/BUILD index 91045a6f95..a5464bdfc2 100644 --- a/examples/multi_processor/BUILD +++ b/examples/multi_processor/BUILD @@ -19,6 +19,7 @@ cc_binary( deps = [ ":foo_multi_library", "//api", + "//exporters/memory:in_memory_span_exporter", "//exporters/ostream:ostream_span_exporter", "//sdk/src/trace", ], From 95966a9efcb4966a49c9d0388b355136bb0e3491 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 20:34:06 +0530 Subject: [PATCH 06/16] resolve merge conflict --- sdk/src/trace/tracer_context.cc | 9 ++++----- sdk/src/trace/tracer_provider.cc | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/sdk/src/trace/tracer_context.cc b/sdk/src/trace/tracer_context.cc index 02e702a154..5ad733e8c8 100644 --- a/sdk/src/trace/tracer_context.cc +++ b/sdk/src/trace/tracer_context.cc @@ -10,11 +10,10 @@ namespace trace TracerContext::TracerContext(std::vector> &&processors, opentelemetry::sdk::resource::Resource resource, std::unique_ptr sampler) noexcept - : - processor_(std::unique_ptr(new MultiSpanProcessor(std::move(processors))), - resource_(resource), - sampler_(std::move(sampler)), - id_generator_(std::move(id_generator))) + : processor_(std::unique_ptr(new MultiSpanProcessor(std::move(processors))), + resource_(resource), + sampler_(std::move(sampler)), + id_generator_(std::move(id_generator))) {} Sampler &TracerContext::GetSampler() const noexcept diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index 1ee6cc09b1..e832ce55b5 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -12,12 +12,12 @@ TracerProvider::TracerProvider(std::shared_ptr contex TracerProvider::TracerProvider(std::unique_ptr processor, opentelemetry::sdk::resource::Resource resource, std::unique_ptr sampler, - std::unique_ptr id_generator) noexcept + std::unique_ptr id_generator) noexcept { std::vector> processors; processors.push_back(std::move(processor)); - *this = TracerProvider( - std::make_shared(std::move(processors), resource, std::move(sampler), std::move(id_generator))); + *this = TracerProvider(std::make_shared( + std::move(processors), resource, std::move(sampler), std::move(id_generator))); } opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( From 341dbcfc28bb5842eb07b0c5cacbceb93aac4140 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 22 Apr 2021 21:25:58 +0530 Subject: [PATCH 07/16] fix conflict --- .../opentelemetry/sdk/trace/multi_recordable.h | 5 +++-- .../opentelemetry/sdk/trace/tracer_context.h | 14 +++++++------- sdk/src/trace/tracer_context.cc | 11 ++++++----- sdk/test/trace/tracer_provider_test.cc | 2 +- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h index a5b7313df3..4513c84d8f 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h @@ -1,5 +1,6 @@ #pragma once +#include "opentelemetry/common/timestamp.h" #include "opentelemetry/sdk/trace/processor.h" #include "opentelemetry/sdk/trace/recordable.h" #include "opentelemetry/version.h" @@ -79,7 +80,7 @@ class MultiRecordable : public Recordable } virtual void AddEvent(nostd::string_view name, - core::SystemTimestamp timestamp, + opentelemetry::common::SystemTimestamp timestamp, const opentelemetry::common::KeyValueIterable &attributes) noexcept override { @@ -123,7 +124,7 @@ class MultiRecordable : public Recordable } } - virtual void SetStartTime(opentelemetry::core::SystemTimestamp start_time) noexcept override + virtual void SetStartTime(opentelemetry::common::SystemTimestamp start_time) noexcept override { for (auto &recordable : recordables_) { diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/sdk/include/opentelemetry/sdk/trace/tracer_context.h index 0657994b9e..1e703d8b3f 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_context.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_context.h @@ -29,13 +29,13 @@ namespace trace class TracerContext { public: - explicit TracerContext(std::vector> &&processor, - opentelemetry::sdk::resource::Resource resource = - opentelemetry::sdk::resource::Resource::Create({}), - std::unique_ptr sampler = - std::unique_ptr(new AlwaysOnSampler), - std::unique_ptr id_generator = - std::unique_ptr(new RandomIdGenerator()) noexcept; + explicit TracerContext( + std::vector> &&processor, + opentelemetry::sdk::resource::Resource resource = + opentelemetry::sdk::resource::Resource::Create({}), + std::unique_ptr sampler = std::unique_ptr(new AlwaysOnSampler), + std::unique_ptr id_generator = + std::unique_ptr(new RandomIdGenerator())) noexcept; /** * Attaches a span processor to this tracer context. * diff --git a/sdk/src/trace/tracer_context.cc b/sdk/src/trace/tracer_context.cc index 5ad733e8c8..2dbc3c2ccd 100644 --- a/sdk/src/trace/tracer_context.cc +++ b/sdk/src/trace/tracer_context.cc @@ -9,11 +9,12 @@ namespace trace TracerContext::TracerContext(std::vector> &&processors, opentelemetry::sdk::resource::Resource resource, - std::unique_ptr sampler) noexcept - : processor_(std::unique_ptr(new MultiSpanProcessor(std::move(processors))), - resource_(resource), - sampler_(std::move(sampler)), - id_generator_(std::move(id_generator))) + std::unique_ptr sampler, + std::unique_ptr id_generator) noexcept + : processor_(std::unique_ptr(new MultiSpanProcessor(std::move(processors)))), + resource_(resource), + sampler_(std::move(sampler)), + id_generator_(std::move(id_generator)) {} Sampler &TracerContext::GetSampler() const noexcept diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index 53579a833f..f6509186a1 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -38,7 +38,7 @@ TEST(TracerProvider, GetTracer) TracerProvider tp2( std::make_shared(std::move(processors2), Resource::Create({}), std::unique_ptr(new AlwaysOffSampler()), - std::unique_ptr(new RandomIdGenerator)));)); + std::unique_ptr(new RandomIdGenerator))); auto sdkTracer2 = dynamic_cast(tp2.GetTracer("test").get()); ASSERT_EQ("AlwaysOffSampler", sdkTracer2->GetSampler().GetDescription()); } From 031048720a8c1d6c260c51e747eccda924d51b34 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Fri, 23 Apr 2021 18:59:26 +0530 Subject: [PATCH 08/16] fix example --- examples/multi_processor/main.cc | 44 ++++++++++++++++++- .../sdk/trace/multi_recordable.h | 7 --- .../sdk/trace/multi_span_processor.h | 11 ++--- .../opentelemetry/sdk/trace/tracer_context.h | 13 +++--- .../opentelemetry/sdk/trace/tracer_provider.h | 5 ++- 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/examples/multi_processor/main.cc b/examples/multi_processor/main.cc index 047cb4e790..8775c69208 100644 --- a/examples/multi_processor/main.cc +++ b/examples/multi_processor/main.cc @@ -8,6 +8,10 @@ #include "opentelemetry/exporters/memory/in_memory_span_exporter.h" #include "opentelemetry/exporters/ostream/span_exporter.h" +using opentelemetry::exporter::memory::InMemorySpanExporter; + +InMemorySpanExporter *memory_span_exporter; + namespace { void initTracer() @@ -17,8 +21,11 @@ void initTracer() auto processor1 = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter1))); - auto exporter2 = std::unique_ptr( - new opentelemetry::exporter::memory::InMemorySpanExporter()); + auto exporter2 = std::unique_ptr(new InMemorySpanExporter()); + + // fetch the exporter for dumping data later + memory_span_exporter = dynamic_cast(exporter2.get()); + auto processor2 = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter2))); @@ -34,6 +41,37 @@ void initTracer() // Set the global trace provider opentelemetry::trace::Provider::SetTracerProvider(provider); } + +void dumpSpans(std::vector> &spans) +{ + char span_buf[opentelemetry::trace::SpanId::kSize * 2]; + char trace_buf[opentelemetry::trace::TraceId::kSize * 2]; + char parent_span_buf[opentelemetry::trace::SpanId::kSize * 2]; + std::cout << "\nSpans from memory :" << std::endl; + + for (auto &span : spans) + { + std::cout << "\n\tSpan: " << std::endl; + std::cout << "\t\tName: " << span->GetName() << std::endl; + span->GetSpanId().ToLowerBase16(span_buf); + span->GetTraceId().ToLowerBase16(trace_buf); + span->GetParentSpanId().ToLowerBase16(parent_span_buf); + std::cout << "\t\tTraceId: " << std::string(trace_buf, sizeof(trace_buf)) << std::endl; + std::cout << "\t\tSpanId: " << std::string(span_buf, sizeof(span_buf)) << std::endl; + std::cout << "\t\tParentSpanId: " << std::string(parent_span_buf, sizeof(parent_span_buf)) + << std::endl; + + std::cout << "\t\tDescription: " << span->GetDescription() << std::endl; + std::cout << "\t\tSpan kind:" + << static_cast::type>( + span->GetSpanKind()) + << std::endl; + std::cout << "\t\tSpan Status: " + << static_cast::type>( + span->GetStatus()) + << std::endl; + } +} } // namespace int main() @@ -42,4 +80,6 @@ int main() initTracer(); foo_library(); + auto memory_spans = memory_span_exporter->GetData()->GetSpans(); + dumpSpans(memory_spans); } diff --git a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h index 4513c84d8f..e131fc676f 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h @@ -7,8 +7,6 @@ #include -// TODO: Create generic short pattern for opentelemetry::common and opentelemetry::trace - OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -23,11 +21,6 @@ std::size_t MakeKey(const SpanProcessor &processor) } // namespace -/** - * Maintains a representation of a span in a format that can be processed by a recorder. - * - * This class is thread-compatible. - */ class MultiRecordable : public Recordable { public: diff --git a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h index 7bb11e6bf4..43c0beeb8f 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h @@ -6,8 +6,6 @@ #include "opentelemetry/sdk/trace/multi_recordable.h" #include "opentelemetry/sdk/trace/processor.h" -#include - OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -31,20 +29,23 @@ class MultiSpanProcessor : public SpanProcessor { for (auto &processor : processors) { - std::cout << " \nAdding processor..."; if (processor) + { processors_.push_back(std::move(processor)); + } } } void AddProcessor(std::unique_ptr &&processor) { - processors_.push_back(std::move(processor)); + if (processor) + { + processors_.push_back(std::move(processor)); + } } std::unique_ptr MakeRecordable() noexcept override { - std::cout << " Make recordable"; auto recordable = std::unique_ptr(new MultiRecordable); auto multi_recordable = static_cast(recordable.get()); for (auto &processor : processors_) diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/sdk/include/opentelemetry/sdk/trace/tracer_context.h index 1e703d8b3f..570ba661a7 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_context.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_context.h @@ -21,9 +21,9 @@ namespace trace * - A thread-safe class that allows updating/altering processor/exporter pipelines * and sampling config. * - The owner/destroyer of Processors/Exporters. These will remain active until - * this class is destroyed. I.e. Sampling, Exporting, flushing etc. are all ok if this - * object is alive, and they will work together. If this object is destroyed, then - * no shared references to Processor, Exporter, Recordable etc. should exist, and all + * this class is destroyed. I.e. Sampling, Exporting, flushing, Custom Iterator etc. are all ok + * if this object is alive, and they will work together. If this object is destroyed, then no shared + * references to Processor, Exporter, Recordable, Custom Iterator etc. should exist, and all * associated pipelines will have been flushed. */ class TracerContext @@ -36,9 +36,10 @@ class TracerContext std::unique_ptr sampler = std::unique_ptr(new AlwaysOnSampler), std::unique_ptr id_generator = std::unique_ptr(new RandomIdGenerator())) noexcept; + /** - * Attaches a span processor to this tracer context. - * + * Attaches a span processor to list of configured processors to this tracer context. + * Processor once attached can't be removed. * @param processor The new span processor for this tracer. This must not be * a nullptr. Ownership is given to the `TracerContext`. */ @@ -51,7 +52,7 @@ class TracerContext Sampler &GetSampler() const noexcept; /** - * Obtain the (conceptual) active processor. + * Obtain the configured (composite) processor. * * Note: When more than one processor is active, this will * return an "aggregate" processor diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 8ebafeee17..669ebc6aa9 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -24,8 +24,11 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider * Initialize a new tracer provider with a specified sampler * @param processor The span processor for this tracer provider. This must * not be a nullptr. + * @param resource The resources for this tracer provider. * @param sampler The sampler for this tracer provider. This must * not be a nullptr. + * @param id_generator The custom id generator for this tracer provider. This must + * not be a nullptr */ explicit TracerProvider( std::unique_ptr processor, @@ -47,7 +50,7 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider nostd::string_view library_version = "") noexcept override; /** - * Attaches a span processor pipeline to this tracer provider. + * Attaches a span processor to list of configured processors for this tracer provider. * @param processor The new span processor for this tracer provider. This * must not be a nullptr. * From 3e457669475e69b3ed431a3fc4287829efeb36d3 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Fri, 23 Apr 2021 23:13:45 +0530 Subject: [PATCH 09/16] Update examples/http/tracer_common.hpp Co-authored-by: Reiley Yang --- examples/http/tracer_common.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/http/tracer_common.hpp b/examples/http/tracer_common.hpp index 472d6bf80c..0b0723a61a 100644 --- a/examples/http/tracer_common.hpp +++ b/examples/http/tracer_common.hpp @@ -4,7 +4,7 @@ #include "opentelemetry/sdk/trace/tracer_provider.h" #include "opentelemetry/trace/provider.h" -#include +#include namespace { @@ -29,4 +29,4 @@ nostd::shared_ptr get_tracer(std::string tracer_na return provider->GetTracer(tracer_name); } -} \ No newline at end of file +} From 33168d62b329535129b207d71f1f47e7891c54d3 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 26 Apr 2021 00:29:59 +0530 Subject: [PATCH 10/16] review comments --- examples/multi_processor/README.md | 2 +- examples/multi_processor/main.cc | 14 +-- .../sdk/trace/multi_span_processor.h | 85 +++++++++++++++---- .../opentelemetry/sdk/trace/tracer_context.h | 4 +- .../opentelemetry/sdk/trace/tracer_provider.h | 6 ++ sdk/src/trace/tracer_context.cc | 2 +- sdk/test/trace/tracer_provider_test.cc | 2 + 7 files changed, 86 insertions(+), 29 deletions(-) diff --git a/examples/multi_processor/README.md b/examples/multi_processor/README.md index b3c449c539..749bf4561b 100644 --- a/examples/multi_processor/README.md +++ b/examples/multi_processor/README.md @@ -1,5 +1,5 @@ -# Simple Trace Example +# Simple Multi Processor Trace Example In this example, the application in `main.cc` initializes and registers a tracer provider from the [OpenTelemetry diff --git a/examples/multi_processor/main.cc b/examples/multi_processor/main.cc index 8775c69208..64e9098f9f 100644 --- a/examples/multi_processor/main.cc +++ b/examples/multi_processor/main.cc @@ -29,17 +29,11 @@ void initTracer() auto processor2 = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter2))); - std::vector> processors; - processors.push_back(std::move(processor1)); - processors.push_back(std::move(processor2)); - // Default is an always-on sampler. - auto context = std::make_shared(std::move(processors)); - - auto provider = nostd::shared_ptr( - new sdktrace::TracerProvider(context)); - + auto provider = nostd::shared_ptr( + new sdktrace::TracerProvider(std::move(processor1))); + provider->AddProcessor(std::move(processor2)); // Set the global trace provider - opentelemetry::trace::Provider::SetTracerProvider(provider); + opentelemetry::trace::Provider::SetTracerProvider(std::move(provider)); } void dumpSpans(std::vector> &spans) diff --git a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h index 43c0beeb8f..ee4613a968 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h @@ -6,6 +6,8 @@ #include "opentelemetry/sdk/trace/multi_recordable.h" #include "opentelemetry/sdk/trace/processor.h" +#include + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -25,22 +27,27 @@ struct MultiSpanProcessorOptions class MultiSpanProcessor : public SpanProcessor { public: - MultiSpanProcessor(std::vector> &&processors) + MultiSpanProcessor(std::vector> &&processors):head_(nullptr), tail_(nullptr), count_(0) { for (auto &processor : processors) { - if (processor) - { - processors_.push_back(std::move(processor)); - } + AddProcessor(std::move(processor)); } } void AddProcessor(std::unique_ptr &&processor) { + // Add preocessor to end of the list. if (processor) { - processors_.push_back(std::move(processor)); + ProcessorNode *pNode = new ProcessorNode(std::move(processor), tail_); + if (count_ > 0){ + tail_->next_ = pNode; + tail_ = pNode; + } else { + head_ = tail_ = pNode; + } + count_++; } } @@ -48,9 +55,11 @@ class MultiSpanProcessor : public SpanProcessor { auto recordable = std::unique_ptr(new MultiRecordable); auto multi_recordable = static_cast(recordable.get()); - for (auto &processor : processors_) - { + ProcessorNode *node = head_; + while (node != nullptr) { + auto processor = node->value_.get(); multi_recordable->AddRecordable(*processor, processor->MakeRecordable()); + node = node->next_; } return recordable; } @@ -59,27 +68,32 @@ class MultiSpanProcessor : public SpanProcessor const opentelemetry::trace::SpanContext &parent_context) noexcept override { auto multi_recordable = static_cast(&span); - - for (auto &processor : processors_) + ProcessorNode *node = head_; + while (node != nullptr) { + auto processor = node->value_.get(); auto &recordable = multi_recordable->GetRecordable(*processor); if (recordable != nullptr) { processor->OnStart(*recordable, parent_context); } + node = node->next_; } } virtual void OnEnd(std::unique_ptr &&span) noexcept override { auto multi_recordable = static_cast(span.release()); - for (auto &processor : processors_) + ProcessorNode *node = head_; + while (node != nullptr) { - auto recordable = multi_recordable->ReleaseRecordable(*processor); + auto processor = node->value_.get(); + auto recordable = multi_recordable->ReleaseRecordable(*processor); if (recordable != nullptr) { processor->OnEnd(std::move(recordable)); } + node = node->next_; } delete multi_recordable; } @@ -88,9 +102,12 @@ class MultiSpanProcessor : public SpanProcessor std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override { bool result = true; - for (auto &processor : processors_) + ProcessorNode *node = head_; + while (node != nullptr) { + auto processor = node->value_.get(); result |= processor->ForceFlush(timeout); + node = node->next_; } return result; } @@ -99,17 +116,53 @@ class MultiSpanProcessor : public SpanProcessor std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override { bool result = true; - for (auto &processor : processors_) + ProcessorNode *node = head_; + while (node != nullptr) { + auto processor = node->value_.get(); result |= processor->Shutdown(timeout); + node = node->next_; } return result; } - ~MultiSpanProcessor() { Shutdown(); } + ~MultiSpanProcessor() + { + Shutdown(); + Cleanup(); + + } private: - std::vector> processors_; +struct ProcessorNode { + std::unique_ptr value_; + ProcessorNode *next_, *prev_; + ProcessorNode(std::unique_ptr &&value, ProcessorNode *prev = nullptr, ProcessorNode *next=nullptr):value_(std::move(value)), prev_(prev), next_(next) {} +}; + + void Cleanup() { + if(count_) { + ProcessorNode *node = tail_; + while(node != nullptr){ + if (node->next_ != nullptr) { + delete node->next_; + node->next_ = nullptr; + } + if (node->prev_ != nullptr){ + node = node->prev_; + } else { + delete node; + node = nullptr; + } + } + head_ = tail_ = nullptr; + count_ = 0; + } + } + + ProcessorNode *head_, *tail_; + size_t count_; + }; } // namespace trace } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/sdk/include/opentelemetry/sdk/trace/tracer_context.h index 570ba661a7..60e2314be1 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_context.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_context.h @@ -42,6 +42,8 @@ class TracerContext * Processor once attached can't be removed. * @param processor The new span processor for this tracer. This must not be * a nullptr. Ownership is given to the `TracerContext`. + * + * Note: This method is not thread safe. */ void AddProcessor(std::unique_ptr processor) noexcept; @@ -84,7 +86,7 @@ class TracerContext private: // This is an atomic pointer so we can adapt the processor pipeline dynamically. - opentelemetry::sdk::common::AtomicUniquePtr processor_; + std::unique_ptr processor_; opentelemetry::sdk::resource::Resource resource_; std::unique_ptr sampler_; std::unique_ptr id_generator_; diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 669ebc6aa9..42c312c689 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -38,6 +38,11 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider std::unique_ptr id_generator = std::unique_ptr( new RandomIdGenerator())) noexcept; + + explicit TracerProvider(std::vector> &&processors, + opentelemetry::sdk::resource::Resource resource, + std::unique_ptr sampler, + std::unique_ptr id_generator) noexcept; /** * Initialize a new tracer provider with a specified context @@ -55,6 +60,7 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider * must not be a nullptr. * * Note: This process may not receive any in-flight spans, but will get newly created spans. + * Note: This method is not thread safe, and should ideally be called from main thread. */ void AddProcessor(std::unique_ptr processor) noexcept; diff --git a/sdk/src/trace/tracer_context.cc b/sdk/src/trace/tracer_context.cc index 2dbc3c2ccd..ef8946c2a2 100644 --- a/sdk/src/trace/tracer_context.cc +++ b/sdk/src/trace/tracer_context.cc @@ -35,7 +35,7 @@ opentelemetry::sdk::trace::IdGenerator &TracerContext::GetIdGenerator() const no void TracerContext::AddProcessor(std::unique_ptr processor) noexcept { - auto multi_processor = static_cast(processor_.Get()); + auto multi_processor = static_cast(processor_.get()); multi_processor->AddProcessor(std::move(processor)); } diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index f6509186a1..7576001fc2 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -10,6 +10,8 @@ using namespace opentelemetry::sdk::trace; using namespace opentelemetry::sdk::resource; +#include + TEST(TracerProvider, GetTracer) { std::unique_ptr processor(new SimpleSpanProcessor(nullptr)); From 42933bad0f6b1ed5e0087cc15d1a4ee889a6bd30 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 26 Apr 2021 00:30:34 +0530 Subject: [PATCH 11/16] and format --- .../sdk/trace/multi_span_processor.h | 105 ++++++++++-------- .../opentelemetry/sdk/trace/tracer_context.h | 2 +- .../opentelemetry/sdk/trace/tracer_provider.h | 8 +- sdk/test/trace/tracer_provider_test.cc | 2 +- 4 files changed, 66 insertions(+), 51 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h index ee4613a968..2e32657bfc 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h @@ -6,7 +6,7 @@ #include "opentelemetry/sdk/trace/multi_recordable.h" #include "opentelemetry/sdk/trace/processor.h" -#include +#include OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -27,7 +27,8 @@ struct MultiSpanProcessorOptions class MultiSpanProcessor : public SpanProcessor { public: - MultiSpanProcessor(std::vector> &&processors):head_(nullptr), tail_(nullptr), count_(0) + MultiSpanProcessor(std::vector> &&processors) + : head_(nullptr), tail_(nullptr), count_(0) { for (auto &processor : processors) { @@ -41,10 +42,13 @@ class MultiSpanProcessor : public SpanProcessor if (processor) { ProcessorNode *pNode = new ProcessorNode(std::move(processor), tail_); - if (count_ > 0){ + if (count_ > 0) + { tail_->next_ = pNode; - tail_ = pNode; - } else { + tail_ = pNode; + } + else + { head_ = tail_ = pNode; } count_++; @@ -55,8 +59,9 @@ class MultiSpanProcessor : public SpanProcessor { auto recordable = std::unique_ptr(new MultiRecordable); auto multi_recordable = static_cast(recordable.get()); - ProcessorNode *node = head_; - while (node != nullptr) { + ProcessorNode *node = head_; + while (node != nullptr) + { auto processor = node->value_.get(); multi_recordable->AddRecordable(*processor, processor->MakeRecordable()); node = node->next_; @@ -68,10 +73,10 @@ class MultiSpanProcessor : public SpanProcessor const opentelemetry::trace::SpanContext &parent_context) noexcept override { auto multi_recordable = static_cast(&span); - ProcessorNode *node = head_; + ProcessorNode *node = head_; while (node != nullptr) { - auto processor = node->value_.get(); + auto processor = node->value_.get(); auto &recordable = multi_recordable->GetRecordable(*processor); if (recordable != nullptr) { @@ -84,11 +89,11 @@ class MultiSpanProcessor : public SpanProcessor virtual void OnEnd(std::unique_ptr &&span) noexcept override { auto multi_recordable = static_cast(span.release()); - ProcessorNode *node = head_; - while (node != nullptr) + ProcessorNode *node = head_; + while (node != nullptr) { - auto processor = node->value_.get(); - auto recordable = multi_recordable->ReleaseRecordable(*processor); + auto processor = node->value_.get(); + auto recordable = multi_recordable->ReleaseRecordable(*processor); if (recordable != nullptr) { processor->OnEnd(std::move(recordable)); @@ -101,9 +106,9 @@ class MultiSpanProcessor : public SpanProcessor bool ForceFlush( std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override { - bool result = true; + bool result = true; ProcessorNode *node = head_; - while (node != nullptr) + while (node != nullptr) { auto processor = node->value_.get(); result |= processor->ForceFlush(timeout); @@ -115,7 +120,7 @@ class MultiSpanProcessor : public SpanProcessor bool Shutdown( std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override { - bool result = true; + bool result = true; ProcessorNode *node = head_; while (node != nullptr) { @@ -126,43 +131,53 @@ class MultiSpanProcessor : public SpanProcessor return result; } - ~MultiSpanProcessor() - { + ~MultiSpanProcessor() + { Shutdown(); Cleanup(); - } private: -struct ProcessorNode { - std::unique_ptr value_; - ProcessorNode *next_, *prev_; - ProcessorNode(std::unique_ptr &&value, ProcessorNode *prev = nullptr, ProcessorNode *next=nullptr):value_(std::move(value)), prev_(prev), next_(next) {} -}; - - void Cleanup() { - if(count_) { - ProcessorNode *node = tail_; - while(node != nullptr){ - if (node->next_ != nullptr) { - delete node->next_; - node->next_ = nullptr; - } - if (node->prev_ != nullptr){ - node = node->prev_; - } else { - delete node; - node = nullptr; - } - } - head_ = tail_ = nullptr; - count_ = 0; - } - } + struct ProcessorNode + { + std::unique_ptr value_; + ProcessorNode *next_, *prev_; + ProcessorNode(std::unique_ptr &&value, + ProcessorNode *prev = nullptr, + ProcessorNode *next = nullptr) + : value_(std::move(value)), prev_(prev), next_(next) + {} + }; + + void Cleanup() + { + if (count_) + { + ProcessorNode *node = tail_; + while (node != nullptr) + { + if (node->next_ != nullptr) + { + delete node->next_; + node->next_ = nullptr; + } + if (node->prev_ != nullptr) + { + node = node->prev_; + } + else + { + delete node; + node = nullptr; + } + } + head_ = tail_ = nullptr; + count_ = 0; + } + } ProcessorNode *head_, *tail_; size_t count_; - }; } // namespace trace } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/sdk/include/opentelemetry/sdk/trace/tracer_context.h index 60e2314be1..0a953b8aa4 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_context.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_context.h @@ -42,7 +42,7 @@ class TracerContext * Processor once attached can't be removed. * @param processor The new span processor for this tracer. This must not be * a nullptr. Ownership is given to the `TracerContext`. - * + * * Note: This method is not thread safe. */ void AddProcessor(std::unique_ptr processor) noexcept; diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index 42c312c689..e587aa3f73 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -38,11 +38,11 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider std::unique_ptr id_generator = std::unique_ptr( new RandomIdGenerator())) noexcept; - + explicit TracerProvider(std::vector> &&processors, - opentelemetry::sdk::resource::Resource resource, - std::unique_ptr sampler, - std::unique_ptr id_generator) noexcept; + opentelemetry::sdk::resource::Resource resource, + std::unique_ptr sampler, + std::unique_ptr id_generator) noexcept; /** * Initialize a new tracer provider with a specified context diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index 7576001fc2..1dcf16f401 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -10,7 +10,7 @@ using namespace opentelemetry::sdk::trace; using namespace opentelemetry::sdk::resource; -#include +#include TEST(TracerProvider, GetTracer) { From ddd45073e70e360a75523fe05fb3d374c27dead7 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 26 Apr 2021 01:55:19 +0530 Subject: [PATCH 12/16] fix review comments --- examples/multi_processor/README.md | 10 ++++++---- .../opentelemetry/sdk/trace/tracer_provider.h | 12 ++++++++---- sdk/src/trace/tracer_provider.cc | 9 +++++++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/examples/multi_processor/README.md b/examples/multi_processor/README.md index 749bf4561b..d63416d698 100644 --- a/examples/multi_processor/README.md +++ b/examples/multi_processor/README.md @@ -1,12 +1,14 @@ - -# Simple Multi Processor Trace Example +# Multi Processor Trace Example In this example, the application in `main.cc` initializes and registers a tracer provider from the [OpenTelemetry -SDK](https://github.com/open-telemetry/opentelemetry-cpp). The application then +SDK](https://github.com/open-telemetry/opentelemetry-cpp). The TraceProvider is conneected +to two `processor-exporter` pipelines - for exporting simultaneously to `StdoutSpanExporter` +and `InMemorySpanExporter`. The application then calls a `foo_library` which has been instrumented using the [OpenTelemetry API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api). -Resulting telemetry is directed to stdout through the StdoutSpanExporter. +Resulting telemetry is directed to stdout through the StdoutSpanExporter, and saved as a +variable (vector of spans) through `InMemorySpanExporter`. See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and running the example. diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index e587aa3f73..ece3c53bfd 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -39,10 +39,14 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider std::unique_ptr( new RandomIdGenerator())) noexcept; - explicit TracerProvider(std::vector> &&processors, - opentelemetry::sdk::resource::Resource resource, - std::unique_ptr sampler, - std::unique_ptr id_generator) noexcept; + explicit TracerProvider( + std::vector> &&processors, + opentelemetry::sdk::resource::Resource resource = + opentelemetry::sdk::resource::Resource::Create({}), + std::unique_ptr sampler = std::unique_ptr(new AlwaysOnSampler), + std::unique_ptr id_generator = + std::unique_ptr( + new RandomIdGenerator())) noexcept; /** * Initialize a new tracer provider with a specified context diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index e832ce55b5..6ab8f8ede5 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -20,6 +20,15 @@ TracerProvider::TracerProvider(std::unique_ptr processor, std::move(processors), resource, std::move(sampler), std::move(id_generator))); } +TracerProvider::TracerProvider(std::vector> &&processors, + opentelemetry::sdk::resource::Resource resource, + std::unique_ptr sampler, + std::unique_ptr id_generator) noexcept +{ + *this = TracerProvider(std::make_shared( + std::move(processors), resource, std::move(sampler), std::move(id_generator))); +} + opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( nostd::string_view library_name, nostd::string_view library_version) noexcept From fe19cb2ae6789235a0a79b55c083c95f45535a60 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 27 Apr 2021 12:29:55 +0530 Subject: [PATCH 13/16] Update examples/multi_processor/README.md Co-authored-by: Tom Tan --- examples/multi_processor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/multi_processor/README.md b/examples/multi_processor/README.md index d63416d698..3efbfa6ef1 100644 --- a/examples/multi_processor/README.md +++ b/examples/multi_processor/README.md @@ -2,7 +2,7 @@ In this example, the application in `main.cc` initializes and registers a tracer provider from the [OpenTelemetry -SDK](https://github.com/open-telemetry/opentelemetry-cpp). The TraceProvider is conneected +SDK](https://github.com/open-telemetry/opentelemetry-cpp). The `TracerProvider` is connected to two `processor-exporter` pipelines - for exporting simultaneously to `StdoutSpanExporter` and `InMemorySpanExporter`. The application then calls a `foo_library` which has been instrumented using the [OpenTelemetry From e2b640f028579d1a70512ef1bcc7881982b92f50 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 26 Apr 2021 23:41:26 +0530 Subject: [PATCH 14/16] review comment --- sdk/include/opentelemetry/sdk/trace/multi_recordable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h index e131fc676f..197816b814 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h @@ -33,12 +33,12 @@ class MultiRecordable : public Recordable const std::unique_ptr &GetRecordable(const SpanProcessor &processor) const noexcept { // TODO - return nullptr ref on failed lookup? - static std::unique_ptr empty(nullptr); auto i = recordables_.find(MakeKey(processor)); if (i != recordables_.end()) { return i->second; } + static std::unique_ptr empty(nullptr); return empty; } From 4c9e26922713eaaacb70704ff60650256122c123 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 27 Apr 2021 01:09:07 +0530 Subject: [PATCH 15/16] fix compile issue after merge --- sdk/src/trace/tracer_provider.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index fe99a6225b..a210555f35 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -16,8 +16,8 @@ TracerProvider::TracerProvider(std::unique_ptr processor, { std::vector> processors; processors.push_back(std::move(processor)); - *this = TracerProvider(std::make_shared( - std::move(processors), resource, std::move(sampler), std::move(id_generator))); + context_ = std::make_shared(std::move(processors), resource, std::move(sampler), + std::move(id_generator)); } TracerProvider::TracerProvider(std::vector> &&processors, @@ -25,8 +25,8 @@ TracerProvider::TracerProvider(std::vector> &&pro std::unique_ptr sampler, std::unique_ptr id_generator) noexcept { - *this = TracerProvider(std::make_shared( - std::move(processors), resource, std::move(sampler), std::move(id_generator))); + context_ = std::make_shared(std::move(processors), resource, std::move(sampler), + std::move(id_generator)); } nostd::shared_ptr TracerProvider::GetTracer( From 74fbeade619ffd9e56989220f91e8f9f11b02b3d Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 28 Apr 2021 22:41:47 +0530 Subject: [PATCH 16/16] fix merge conflict --- sdk/include/opentelemetry/sdk/trace/multi_recordable.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h index 197816b814..925685a14f 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h @@ -133,6 +133,15 @@ class MultiRecordable : public Recordable } } + void SetInstrumentationLibrary( + const InstrumentationLibrary &instrumentation_library) noexcept override + { + for (auto &recordable : recordables_) + { + recordable.second->SetInstrumentationLibrary(instrumentation_library); + } + } + private: std::map> recordables_; };