From b0f27a465e899f79480644ba9afa24b152cbcf2c Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 16 Apr 2021 02:49:40 -0700 Subject: [PATCH 1/6] More vs2019 minor warnings cleanup (#675) --- api/include/opentelemetry/context/context.h | 2 +- api/include/opentelemetry/context/runtime_context.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/api/include/opentelemetry/context/context.h b/api/include/opentelemetry/context/context.h index 59dcd8cb11..4d3384e288 100644 --- a/api/include/opentelemetry/context/context.h +++ b/api/include/opentelemetry/context/context.h @@ -140,7 +140,7 @@ class Context next_ = nostd::shared_ptr{nullptr}; } - DataList &operator=(DataList &&other) + DataList &operator=(DataList &&other) noexcept { key_length_ = other.key_length_; value_ = std::move(other.value_); diff --git a/api/include/opentelemetry/context/runtime_context.h b/api/include/opentelemetry/context/runtime_context.h index 36ed7cc3cc..d9c5b0f7b4 100644 --- a/api/include/opentelemetry/context/runtime_context.h +++ b/api/include/opentelemetry/context/runtime_context.h @@ -58,6 +58,8 @@ class RuntimeContextStorage */ virtual bool Detach(Token &token) noexcept = 0; + virtual ~RuntimeContextStorage(){}; + protected: nostd::unique_ptr CreateToken(const Context &context) noexcept { From 7b0701363937dd87afc1baf1b0cdcaf37a72ca21 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 16 Apr 2021 11:25:22 -0400 Subject: [PATCH 2/6] Create shared context for updating span pipeline from TracerProvider and affecting Tracer. (#650) --- examples/batch/main.cc | 4 +- examples/http/BUILD | 42 ++++++++ examples/http/tracer_common.hpp | 9 +- examples/multithreaded/main.cc | 7 +- examples/otlp/main.cc | 5 +- examples/simple/main.cc | 5 +- exporters/otlp/test/otlp_exporter_test.cc | 6 +- ext/include/opentelemetry/ext/zpages/zpages.h | 5 +- ext/src/http/client/curl/BUILD | 14 +++ ext/test/http/BUILD | 13 --- ext/test/w3c_tracecontext_test/main.cc | 5 +- .../zpages/tracez_data_aggregator_test.cc | 5 +- ext/test/zpages/tracez_processor_test.cc | 6 +- .../sdk/common/atomic_unique_ptr.h | 2 + sdk/include/opentelemetry/sdk/trace/tracer.h | 40 ++------ .../opentelemetry/sdk/trace/tracer_context.h | 84 ++++++++++++++++ .../opentelemetry/sdk/trace/tracer_provider.h | 39 ++++---- sdk/src/trace/CMakeLists.txt | 9 +- sdk/src/trace/span.cc | 12 +-- sdk/src/trace/span.h | 5 +- sdk/src/trace/tracer.cc | 30 ++---- sdk/src/trace/tracer_context.cc | 52 ++++++++++ sdk/src/trace/tracer_provider.cc | 40 +++----- sdk/test/trace/sampler_benchmark.cc | 6 +- sdk/test/trace/tracer_provider_test.cc | 50 +++------- sdk/test/trace/tracer_test.cc | 99 +++++-------------- 26 files changed, 327 insertions(+), 267 deletions(-) create mode 100644 examples/http/BUILD create mode 100644 sdk/include/opentelemetry/sdk/trace/tracer_context.h create mode 100644 sdk/src/trace/tracer_context.cc diff --git a/examples/batch/main.cc b/examples/batch/main.cc index 36372d0eb3..32e285d344 100644 --- a/examples/batch/main.cc +++ b/examples/batch/main.cc @@ -28,11 +28,11 @@ void initTracer() // We export `kNumSpans` after every `schedule_delay_millis` milliseconds. options.max_export_batch_size = kNumSpans; - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdktrace::BatchSpanProcessor(std::move(exporter), options)); auto provider = nostd::shared_ptr( - new sdktrace::TracerProvider(processor)); + new sdktrace::TracerProvider(std::move(processor))); // Set the global trace provider. opentelemetry::trace::Provider::SetTracerProvider(provider); } diff --git a/examples/http/BUILD b/examples/http/BUILD new file mode 100644 index 0000000000..4fce0a2e27 --- /dev/null +++ b/examples/http/BUILD @@ -0,0 +1,42 @@ +cc_binary( + name = "example_http_client", + srcs = [ + "client.cc", + "tracer_common.hpp", + ], + # TODO: Move copts/linkopts for static CURL usage into shared bzl file. + copts = [ + "-DCURL_STATICLIB", + "-DWITH_CURL", + ], + linkopts = select({ + "//bazel:windows": [ + "-DEFAULTLIB:advapi32.lib", + "-DEFAULTLIB:crypt32.lib", + "-DEFAULTLIB:Normaliz.lib", + ], + "//conditions:default": [], + }), + deps = [ + "//api", + "//exporters/ostream:ostream_span_exporter", + "//ext:headers", + "//ext/src/http/client/curl:http_client_curl", + "//sdk/src/trace", + ], +) + +cc_binary( + name = "example_http_server", + srcs = [ + "server.cc", + "server.hpp", + "tracer_common.hpp", + ], + deps = [ + "//api", + "//exporters/ostream:ostream_span_exporter", + "//ext:headers", + "//sdk/src/trace", + ], +) diff --git a/examples/http/tracer_common.hpp b/examples/http/tracer_common.hpp index b45102ac9e..19239890c6 100644 --- a/examples/http/tracer_common.hpp +++ b/examples/http/tracer_common.hpp @@ -11,11 +11,12 @@ namespace { void initTracer() { auto exporter = std::unique_ptr( new opentelemetry::exporter::trace::OStreamSpanExporter); - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); - auto provider = nostd::shared_ptr( - new sdktrace::TracerProvider(processor, opentelemetry::sdk::resource::Resource::Create({}), - std::make_shared())); + // Default is an always-on sampler. + auto context = std::make_shared(std::move(processor)); + auto provider = nostd::shared_ptr( + new sdktrace::TracerProvider(context)); // Set the global trace provider opentelemetry::trace::Provider::SetTracerProvider(provider); } diff --git a/examples/multithreaded/main.cc b/examples/multithreaded/main.cc index 1a756c973b..309d7ff19a 100644 --- a/examples/multithreaded/main.cc +++ b/examples/multithreaded/main.cc @@ -16,10 +16,11 @@ void initTracer() { auto exporter = std::unique_ptr( new opentelemetry::exporter::trace::OStreamSpanExporter); - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); - auto provider = nostd::shared_ptr( - new sdktrace::TracerProvider(processor, opentelemetry::sdk::resource::Resource::Create({}))); + auto provider = + nostd::shared_ptr(new sdktrace::TracerProvider( + std::move(processor), opentelemetry::sdk::resource::Resource::Create({}))); // Set the global trace provider opentelemetry::trace::Provider::SetTracerProvider(provider); } diff --git a/examples/otlp/main.cc b/examples/otlp/main.cc index 00a557c1ff..f2ec3c3edd 100644 --- a/examples/otlp/main.cc +++ b/examples/otlp/main.cc @@ -17,9 +17,10 @@ void InitTracer() { // Create OTLP exporter instance auto exporter = std::unique_ptr(new otlp::OtlpExporter(opts)); - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); - auto provider = nostd::shared_ptr(new sdktrace::TracerProvider(processor)); + auto provider = + nostd::shared_ptr(new sdktrace::TracerProvider(std::move(processor))); // Set the global trace provider trace::Provider::SetTracerProvider(provider); } diff --git a/examples/simple/main.cc b/examples/simple/main.cc index 5d22c6b155..28d9196dd6 100644 --- a/examples/simple/main.cc +++ b/examples/simple/main.cc @@ -12,11 +12,10 @@ void initTracer() { auto exporter = std::unique_ptr( new opentelemetry::exporter::trace::OStreamSpanExporter); - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); auto provider = nostd::shared_ptr( - new sdktrace::TracerProvider(processor, opentelemetry::sdk::resource::Resource::Create({}), - std::make_shared())); + new sdktrace::TracerProvider(std::move(processor))); // Set the global trace provider opentelemetry::trace::Provider::SetTracerProvider(provider); diff --git a/exporters/otlp/test/otlp_exporter_test.cc b/exporters/otlp/test/otlp_exporter_test.cc index 7e419af5a5..c5a6098a02 100644 --- a/exporters/otlp/test/otlp_exporter_test.cc +++ b/exporters/otlp/test/otlp_exporter_test.cc @@ -73,10 +73,10 @@ TEST_F(OtlpExporterTestPeer, ExportIntegrationTest) auto exporter = GetExporter(stub_interface); - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdk::trace::SimpleSpanProcessor(std::move(exporter))); - auto provider = - nostd::shared_ptr(new sdk::trace::TracerProvider(processor)); + auto provider = nostd::shared_ptr( + new sdk::trace::TracerProvider(std::move(processor))); auto tracer = provider->GetTracer("test"); EXPECT_CALL(*mock_stub, Export(_, _, _)) diff --git a/ext/include/opentelemetry/ext/zpages/zpages.h b/ext/include/opentelemetry/ext/zpages/zpages.h index a32b2bf161..b1e3606277 100644 --- a/ext/include/opentelemetry/ext/zpages/zpages.h +++ b/ext/include/opentelemetry/ext/zpages/zpages.h @@ -51,10 +51,11 @@ class ZPages /** Replaces the global tracer provider with an instance that exports to tracez. */ void ReplaceGlobalProvider() { - std::shared_ptr tracez_processor( + // GCC 4.8 can't infer the type coercion. + std::unique_ptr processor( MakeSpanProcessor().release()); auto tracez_provider_ = opentelemetry::nostd::shared_ptr( - new opentelemetry::sdk::trace::TracerProvider(tracez_processor)); + new opentelemetry::sdk::trace::TracerProvider(std::move(processor))); opentelemetry::trace::Provider::SetTracerProvider(tracez_provider_); } diff --git a/ext/src/http/client/curl/BUILD b/ext/src/http/client/curl/BUILD index e01988a388..6d484d3770 100644 --- a/ext/src/http/client/curl/BUILD +++ b/ext/src/http/client/curl/BUILD @@ -6,7 +6,21 @@ cc_library( "http_client_curl.cc", "http_client_factory_curl.cc", ], + # TODO: Move copts/linkopts for static CURL usage into shared bzl file. + copts = [ + "-DCURL_STATICLIB", + "-DWITH_CURL", + ], include_prefix = "src/http/client/curl", + linkopts = select({ + "//bazel:windows": [ + "-DEFAULTLIB:advapi32.lib", + "-DEFAULTLIB:crypt32.lib", + "-DEFAULTLIB:Normaliz.lib", + "-DEFAULTLIB:Ws2_32.lib", + ], + "//conditions:default": [], + }), deps = [ "//api", "//ext:headers", diff --git a/ext/test/http/BUILD b/ext/test/http/BUILD index 7251c0fde6..c2d24c6e77 100644 --- a/ext/test/http/BUILD +++ b/ext/test/http/BUILD @@ -3,19 +3,6 @@ cc_test( srcs = [ "curl_http_test.cc", ], - # TODO: Move copts/linkopts for static CURL usage into shared bzl file. - copts = [ - "-DCURL_STATICLIB", - "-DWITH_CURL", - ], - linkopts = select({ - "//bazel:windows": [ - "-DEFAULTLIB:advapi32.lib", - "-DEFAULTLIB:crypt32.lib", - "-DEFAULTLIB:Normaliz.lib", - ], - "//conditions:default": [], - }), deps = [ "//ext:headers", "//ext/src/http/client/curl:http_client_curl", diff --git a/ext/test/w3c_tracecontext_test/main.cc b/ext/test/w3c_tracecontext_test/main.cc index 7ec727957f..fc26801079 100644 --- a/ext/test/w3c_tracecontext_test/main.cc +++ b/ext/test/w3c_tracecontext_test/main.cc @@ -38,10 +38,11 @@ void initTracer() { auto exporter = std::unique_ptr( new opentelemetry::exporter::trace::OStreamSpanExporter); - auto processor = std::shared_ptr( + auto processor = std::unique_ptr( new sdktrace::SimpleSpanProcessor(std::move(exporter))); + auto context = std::make_shared(std::move(processor)); auto provider = nostd::shared_ptr( - new sdktrace::TracerProvider(processor)); + new sdktrace::TracerProvider(context)); // Set the global trace provider opentelemetry::trace::Provider::SetTracerProvider(provider); } diff --git a/ext/test/zpages/tracez_data_aggregator_test.cc b/ext/test/zpages/tracez_data_aggregator_test.cc index 82af11a274..324cf0c612 100644 --- a/ext/test/zpages/tracez_data_aggregator_test.cc +++ b/ext/test/zpages/tracez_data_aggregator_test.cc @@ -35,9 +35,10 @@ class TracezDataAggregatorTest : public ::testing::Test void SetUp() override { std::shared_ptr shared_data(new TracezSharedData()); - std::shared_ptr processor(new TracezSpanProcessor(shared_data)); auto resource = opentelemetry::sdk::resource::Resource::Create({}); - tracer = std::shared_ptr(new Tracer(processor, resource)); + auto context = std::make_shared( + std::unique_ptr(new TracezSpanProcessor(shared_data)), 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 c0ec2dde39..7ea4063d60 100644 --- a/ext/test/zpages/tracez_processor_test.cc +++ b/ext/test/zpages/tracez_processor_test.cc @@ -178,8 +178,12 @@ class TracezProcessor : public ::testing::Test shared_data = std::shared_ptr(new TracezSharedData()); processor = std::shared_ptr(new TracezSpanProcessor(shared_data)); 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); - tracer = std::shared_ptr(new Tracer(processor, resource)); + tracer = std::shared_ptr(new Tracer(context)); auto spans = shared_data->GetSpanSnapshot(); running = spans.running; completed = std::move(spans.completed); diff --git a/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h b/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h index d93d9b72b2..32217da220 100644 --- a/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h +++ b/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h @@ -20,6 +20,8 @@ class AtomicUniquePtr public: AtomicUniquePtr() noexcept {} + explicit AtomicUniquePtr(std::unique_ptr &&other) noexcept : ptr_(other.release()) {} + ~AtomicUniquePtr() noexcept { Reset(); } T &operator*() const noexcept { return *Get(); } diff --git a/sdk/include/opentelemetry/sdk/trace/tracer.h b/sdk/include/opentelemetry/sdk/trace/tracer.h index 1e52b0e377..f764c48478 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer.h @@ -4,6 +4,7 @@ #include "opentelemetry/sdk/resource/resource.h" #include "opentelemetry/sdk/trace/processor.h" #include "opentelemetry/sdk/trace/samplers/always_on.h" +#include "opentelemetry/sdk/trace/tracer_context.h" #include "opentelemetry/trace/noop.h" #include "opentelemetry/trace/tracer.h" #include "opentelemetry/version.h" @@ -18,33 +19,8 @@ namespace trace class Tracer final : public trace_api::Tracer, public std::enable_shared_from_this { public: - /** - * Initialize a new tracer. - * @param processor The span processor for this tracer. This must not be a - * nullptr. - */ - explicit Tracer(std::shared_ptr processor, - const opentelemetry::sdk::resource::Resource &resource, - std::shared_ptr sampler = std::make_shared()) noexcept; - - /** - * Set the span processor associated with this tracer. - * @param processor The new span processor for this tracer. This must not be - * a nullptr. - */ - void SetProcessor(std::shared_ptr processor) noexcept; - - /** - * Obtain the span processor associated with this tracer. - * @return The span processor for this tracer. - */ - std::shared_ptr GetProcessor() const noexcept; - - /** - * Obtain the sampler associated with this tracer. - * @return The sampler for this tracer. - */ - std::shared_ptr GetSampler() const noexcept; + /** Construct a new Tracer with the given context pipeline. */ + explicit Tracer(std::shared_ptr context) noexcept; nostd::shared_ptr StartSpan( nostd::string_view name, @@ -56,10 +32,14 @@ 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(); } + + // Note: Test only + Sampler &GetSampler() { return context_->GetSampler(); } + private: - opentelemetry::sdk::common::AtomicSharedPtr processor_; - const std::shared_ptr sampler_; - const opentelemetry::sdk::resource::Resource &resource_; + std::shared_ptr context_; }; } // namespace trace } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_context.h b/sdk/include/opentelemetry/sdk/trace/tracer_context.h new file mode 100644 index 0000000000..e5af3a87ba --- /dev/null +++ b/sdk/include/opentelemetry/sdk/trace/tracer_context.h @@ -0,0 +1,84 @@ +#pragma once + +#include "opentelemetry/sdk/common/atomic_unique_ptr.h" +#include "opentelemetry/sdk/resource/resource.h" +#include "opentelemetry/sdk/trace/processor.h" +#include "opentelemetry/sdk/trace/samplers/always_on.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ + +/** + * A class which stores the TracerProvider context. + * + * This class meets the following design criteria: + * - A shared reference between TracerProvider and Tracers instantiated. + * - 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 + * associated pipelines will have been flushed. + */ +class TracerContext +{ +public: + explicit TracerContext(std::unique_ptr 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; + + /** + * Obtain the sampler associated with this tracer. + * @return The sampler for this tracer. + */ + Sampler &GetSampler() const noexcept; + + /** + * Obtain the (conceptual) active processor. + * + * Note: When more than one processor is active, this will + * return an "aggregate" processor + */ + SpanProcessor &GetActiveProcessor() const noexcept; + + /** + * Obtain the resource associated with this tracer context. + * @return The resource for this tracer context. + */ + const opentelemetry::sdk::resource::Resource &GetResource() const noexcept; + + /** + * Force all active SpanProcessors to flush any buffered spans + * within the given timeout. + */ + bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; + + /** + * Shutdown the span processor associated with this tracer provider. + */ + bool Shutdown() noexcept; + +private: + // This is an atomic pointer so we can adapt the processor pipeline dynamically. + opentelemetry::sdk::common::AtomicUniquePtr processor_; + opentelemetry::sdk::resource::Resource resource_; + std::unique_ptr sampler_; +}; + +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index f56a0fdab6..0301aa7e44 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -9,6 +9,7 @@ #include "opentelemetry/sdk/trace/processor.h" #include "opentelemetry/sdk/trace/samplers/always_on.h" #include "opentelemetry/sdk/trace/tracer.h" +#include "opentelemetry/sdk/trace/tracer_context.h" #include "opentelemetry/trace/tracer_provider.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -26,34 +27,30 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider * @param sampler The sampler for this tracer provider. This must * not be a nullptr. */ - explicit TracerProvider( - std::shared_ptr processor, - opentelemetry::sdk::resource::Resource &&resource = - opentelemetry::sdk::resource::Resource::Create({}), - std::shared_ptr sampler = std::make_shared()) noexcept; + explicit TracerProvider(std::unique_ptr processor, + opentelemetry::sdk::resource::Resource resource = + opentelemetry::sdk::resource::Resource::Create({}), + std::unique_ptr sampler = + std::unique_ptr(new AlwaysOnSampler)) noexcept; + + /** + * Initialize a new tracer provider with a specified context + * @param context The shared tracer configuration/pipeline for this provider. + */ + explicit TracerProvider(std::shared_ptr context) noexcept; opentelemetry::nostd::shared_ptr GetTracer( nostd::string_view library_name, nostd::string_view library_version = "") noexcept override; /** - * Set the span processor associated with this tracer provider. + * Attaches a span processor pipeline to this tracer provider. * @param processor The new span processor for this tracer provider. This * must not be a nullptr. + * + * Note: This process may not receive any in-flight spans, but will get newly created spans. */ - void SetProcessor(std::shared_ptr processor) noexcept; - - /** - * Obtain the span processor associated with this tracer provider. - * @return The span processor for this tracer provider. - */ - std::shared_ptr GetProcessor() const noexcept; - - /** - * Obtain the sampler associated with this tracer provider. - * @return The sampler for this tracer provider. - */ - std::shared_ptr GetSampler() const noexcept; + void RegisterPipeline(std::unique_ptr processor) noexcept; /** * Obtain the resource associated with this tracer provider. @@ -72,10 +69,8 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; private: - opentelemetry::sdk::common::AtomicSharedPtr processor_; + std::shared_ptr context_; std::shared_ptr tracer_; - const std::shared_ptr sampler_; - const opentelemetry::sdk::resource::Resource resource_; }; } // namespace trace } // namespace sdk diff --git a/sdk/src/trace/CMakeLists.txt b/sdk/src/trace/CMakeLists.txt index d4ff82f63e..e3d3e0afec 100644 --- a/sdk/src/trace/CMakeLists.txt +++ b/sdk/src/trace/CMakeLists.txt @@ -1,7 +1,12 @@ add_library( opentelemetry_trace - tracer_provider.cc tracer.cc span.cc batch_span_processor.cc - samplers/parent.cc samplers/trace_id_ratio.cc) + tracer_context.cc + tracer_provider.cc + tracer.cc + span.cc + batch_span_processor.cc + samplers/parent.cc + samplers/trace_id_ratio.cc) set_target_properties(opentelemetry_trace PROPERTIES EXPORT_NAME trace) diff --git a/sdk/src/trace/span.cc b/sdk/src/trace/span.cc index f7990c27ea..388d0ab923 100644 --- a/sdk/src/trace/span.cc +++ b/sdk/src/trace/span.cc @@ -58,18 +58,15 @@ trace_api::SpanId GenerateRandomSpanId() } Span::Span(std::shared_ptr &&tracer, - std::shared_ptr processor, nostd::string_view name, const opentelemetry::common::KeyValueIterable &attributes, const trace_api::SpanContextKeyValueIterable &links, const trace_api::StartSpanOptions &options, const trace_api::SpanContext &parent_span_context, - const opentelemetry::sdk::resource::Resource &resource, const nostd::shared_ptr trace_state, const bool sampled) noexcept : tracer_{std::move(tracer)}, - processor_{processor}, - recordable_{processor_->MakeRecordable()}, + recordable_{tracer_->GetActiveProcessor().MakeRecordable()}, start_steady_time{options.start_steady_time}, has_ended_{false} { @@ -120,8 +117,9 @@ Span::Span(std::shared_ptr &&tracer, recordable_->SetSpanKind(options.kind); recordable_->SetStartTime(NowOr(options.start_system_time)); start_steady_time = NowOr(options.start_steady_time); - // recordable_->SetResource(resource_); TODO - processor_->OnStart(*recordable_, parent_span_context); + // recordable_->SetResource(tracer_->GetResoource()); TODO + // recordable_->SetResource(tracer_->GetInstrumentationLibrary()); TODO + tracer_->GetActiveProcessor().OnStart(*recordable_, parent_span_context); } Span::~Span() @@ -208,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)); - processor_->OnEnd(std::move(recordable_)); + tracer_->GetActiveProcessor().OnEnd(std::move(recordable_)); recordable_.reset(); } diff --git a/sdk/src/trace/span.h b/sdk/src/trace/span.h index 01fb995517..efc16d6c59 100644 --- a/sdk/src/trace/span.h +++ b/sdk/src/trace/span.h @@ -16,13 +16,11 @@ class Span final : public trace_api::Span { public: Span(std::shared_ptr &&tracer, - std::shared_ptr processor, nostd::string_view name, const opentelemetry::common::KeyValueIterable &attributes, const trace_api::SpanContextKeyValueIterable &links, const trace_api::StartSpanOptions &options, const trace_api::SpanContext &parent_span_context, - const opentelemetry::sdk::resource::Resource &resource, const nostd::shared_ptr trace_state = trace_api::TraceState::GetDefault(), const bool sampled = false) noexcept; @@ -52,8 +50,7 @@ class Span final : public trace_api::Span trace_api::SpanContext GetContext() const noexcept override { return *span_context_.get(); } private: - std::shared_ptr tracer_; - std::shared_ptr processor_; + std::shared_ptr tracer_; mutable std::mutex mu_; std::unique_ptr recordable_; opentelemetry::core::SteadyTimestamp start_steady_time; diff --git a/sdk/src/trace/tracer.cc b/sdk/src/trace/tracer.cc index 93fdc6f680..2d67321d83 100644 --- a/sdk/src/trace/tracer.cc +++ b/sdk/src/trace/tracer.cc @@ -10,26 +10,8 @@ namespace sdk { namespace trace { -Tracer::Tracer(std::shared_ptr processor, - const opentelemetry::sdk::resource::Resource &resource, - std::shared_ptr sampler) noexcept - : processor_{processor}, sampler_{sampler}, resource_{resource} -{} -void Tracer::SetProcessor(std::shared_ptr processor) noexcept -{ - processor_.store(processor); -} - -std::shared_ptr Tracer::GetProcessor() const noexcept -{ - return processor_.load(); -} - -std::shared_ptr Tracer::GetSampler() const noexcept -{ - return sampler_; -} +Tracer::Tracer(std::shared_ptr context) noexcept : context_{context} {} trace_api::SpanContext GetCurrentSpanContext(const trace_api::SpanContext &explicit_parent) { @@ -60,8 +42,8 @@ nostd::shared_ptr Tracer::StartSpan( { trace_api::SpanContext parent = GetCurrentSpanContext(options.parent); - auto sampling_result = - sampler_->ShouldSample(parent, parent.trace_id(), name, options.kind, attributes, links); + auto sampling_result = context_->GetSampler().ShouldSample(parent, parent.trace_id(), name, + options.kind, attributes, links); if (sampling_result.decision == Decision::DROP) { // Don't allocate a no-op span for every DROP decision, but use a static @@ -73,9 +55,9 @@ nostd::shared_ptr Tracer::StartSpan( } else { - auto span = nostd::shared_ptr{new (std::nothrow) Span{ - this->shared_from_this(), processor_.load(), name, attributes, links, options, parent, - resource_, sampling_result.trace_state, true}}; + auto span = nostd::shared_ptr{ + new (std::nothrow) Span{this->shared_from_this(), name, attributes, links, options, parent, + sampling_result.trace_state, true}}; // if the attributes is not nullptr, add attributes to the span. if (sampling_result.attributes) diff --git a/sdk/src/trace/tracer_context.cc b/sdk/src/trace/tracer_context.cc new file mode 100644 index 0000000000..a463ec81d4 --- /dev/null +++ b/sdk/src/trace/tracer_context.cc @@ -0,0 +1,52 @@ +#include "opentelemetry/sdk/trace/tracer_context.h" +#include "opentelemetry/sdk/trace/processor.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace trace +{ + +TracerContext::TracerContext(std::unique_ptr processor, + opentelemetry::sdk::resource::Resource resource, + std::unique_ptr sampler) noexcept + : processor_(std::move(processor)), resource_(resource), sampler_(std::move(sampler)) +{} + +Sampler &TracerContext::GetSampler() const noexcept +{ + return *sampler_.get(); +} + +const opentelemetry::sdk::resource::Resource &TracerContext::GetResource() const noexcept +{ + return resource_; +} + +void TracerContext::RegisterPipeline(std::unique_ptr processor) noexcept +{ + // 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 + // the other, + // then replace our atomic ptr with the new aggregate. +} + +SpanProcessor &TracerContext::GetActiveProcessor() const noexcept +{ + return *processor_; +} + +bool TracerContext::ForceFlush(std::chrono::microseconds timeout) noexcept +{ + return processor_->ForceFlush(timeout); +} + +bool TracerContext::Shutdown() noexcept +{ + return processor_->Shutdown(); +} + +} // namespace trace +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc index cc236292a2..0eaf6782f2 100644 --- a/sdk/src/trace/tracer_provider.cc +++ b/sdk/src/trace/tracer_provider.cc @@ -5,13 +5,15 @@ namespace sdk { namespace trace { -TracerProvider::TracerProvider(std::shared_ptr processor, - opentelemetry::sdk::resource::Resource &&resource, - std::shared_ptr sampler) noexcept - : processor_{processor}, - tracer_(new Tracer(std::move(processor), resource, sampler)), - sampler_(sampler), - resource_(resource) +TracerProvider::TracerProvider(std::shared_ptr context) noexcept + : context_{context}, tracer_(new Tracer(context)) +{} + +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))) {} opentelemetry::nostd::shared_ptr TracerProvider::GetTracer( @@ -21,38 +23,26 @@ opentelemetry::nostd::shared_ptr TracerProvider::G return opentelemetry::nostd::shared_ptr(tracer_); } -void TracerProvider::SetProcessor(std::shared_ptr processor) noexcept -{ - processor_.store(processor); - - auto sdkTracer = static_cast(tracer_.get()); - sdkTracer->SetProcessor(processor); -} - -std::shared_ptr TracerProvider::GetProcessor() const noexcept +void TracerProvider::RegisterPipeline(std::unique_ptr processor) noexcept { - return processor_.load(); -} - -std::shared_ptr TracerProvider::GetSampler() const noexcept -{ - return sampler_; + return context_->RegisterPipeline(std::move(processor)); } const opentelemetry::sdk::resource::Resource &TracerProvider::GetResource() const noexcept { - return resource_; + return context_->GetResource(); } bool TracerProvider::Shutdown() noexcept { - return GetProcessor()->Shutdown(); + return context_->Shutdown(); } bool TracerProvider::ForceFlush(std::chrono::microseconds timeout) noexcept { - return GetProcessor()->ForceFlush(timeout); + return context_->ForceFlush(timeout); } + } // namespace trace } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/trace/sampler_benchmark.cc b/sdk/test/trace/sampler_benchmark.cc index 5606206ce6..90a07adc77 100644 --- a/sdk/test/trace/sampler_benchmark.cc +++ b/sdk/test/trace/sampler_benchmark.cc @@ -118,10 +118,10 @@ BENCHMARK(BM_TraceIdRatioBasedSamplerShouldSample); void BenchmarkSpanCreation(std::shared_ptr sampler, benchmark::State &state) { std::unique_ptr exporter(new InMemorySpanExporter()); - auto processor = std::make_shared(std::move(exporter)); + 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(processor, resource, sampler)); + 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 7cfe306278..55a5a9be44 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -12,9 +12,9 @@ using namespace opentelemetry::sdk::resource; TEST(TracerProvider, GetTracer) { - std::shared_ptr processor(new SimpleSpanProcessor(nullptr)); + std::unique_ptr processor(new SimpleSpanProcessor(nullptr)); - TracerProvider tp1(processor, Resource::Create({})); + TracerProvider tp1(std::make_shared(std::move(processor), Resource::Create({}))); auto t1 = tp1.GetTracer("test"); auto t2 = tp1.GetTracer("test"); auto t3 = tp1.GetTracer("different", "1.0.0"); @@ -24,58 +24,34 @@ TEST(TracerProvider, GetTracer) // Should return the same instance each time. ASSERT_EQ(t1, t2); + // TODO: t3 should be a different instance. ASSERT_EQ(t1, t3); // Should be an sdk::trace::Tracer with the processor attached. auto sdkTracer1 = dynamic_cast(t1.get()); ASSERT_NE(nullptr, sdkTracer1); - ASSERT_EQ(processor, sdkTracer1->GetProcessor()); - ASSERT_EQ("AlwaysOnSampler", sdkTracer1->GetSampler()->GetDescription()); - - TracerProvider tp2(processor, Resource::Create({}), std::make_shared()); + ASSERT_EQ("AlwaysOnSampler", sdkTracer1->GetSampler().GetDescription()); + TracerProvider tp2(std::make_shared( + std::unique_ptr(new SimpleSpanProcessor(nullptr)), Resource::Create({}), + std::unique_ptr(new AlwaysOffSampler()))); auto sdkTracer2 = dynamic_cast(tp2.GetTracer("test").get()); - ASSERT_EQ("AlwaysOffSampler", sdkTracer2->GetSampler()->GetDescription()); -} - -TEST(TracerProvider, GetSampler) -{ - std::shared_ptr processor1(new SimpleSpanProcessor(nullptr)); - - // Create a TracerProvicer with a default AlwaysOnSampler. - TracerProvider tp1(processor1); - auto t1 = tp1.GetSampler(); - auto t2 = tp1.GetSampler(); - ASSERT_NE(nullptr, t1); - ASSERT_NE(nullptr, t2); - - // Should return the same sampler each time. - ASSERT_EQ(t1, t2); - - // Should be AlwaysOnSampler - ASSERT_EQ("AlwaysOnSampler", t2->GetDescription()); - - // Create a TracerProvicer with a custom AlwaysOffSampler. - std::shared_ptr processor2(new SimpleSpanProcessor(nullptr)); - TracerProvider tp2(processor2, Resource::Create({}), std::make_shared()); - auto t3 = tp2.GetSampler(); - - ASSERT_EQ("AlwaysOffSampler", t3->GetDescription()); + ASSERT_EQ("AlwaysOffSampler", sdkTracer2->GetSampler().GetDescription()); } TEST(TracerProvider, Shutdown) { - std::shared_ptr processor1(new SimpleSpanProcessor(nullptr)); + std::unique_ptr processor1(new SimpleSpanProcessor(nullptr)); - TracerProvider tp1(processor1); + TracerProvider tp1(std::make_shared(std::move(processor1))); EXPECT_TRUE(tp1.Shutdown()); } TEST(TracerProvider, ForceFlush) { - std::shared_ptr processor1(new SimpleSpanProcessor(nullptr)); + std::unique_ptr processor1(new SimpleSpanProcessor(nullptr)); - TracerProvider tp1(processor1); + TracerProvider tp1(std::move(processor1)); EXPECT_TRUE(tp1.ForceFlush()); -} +} \ No newline at end of file diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index 60544f6fdc..176a949670 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -19,7 +19,6 @@ using opentelemetry::common::KeyValueIterableView; using opentelemetry::exporter::memory::InMemorySpanData; using opentelemetry::exporter::memory::InMemorySpanExporter; using opentelemetry::trace::SpanContext; -using opentelemetry::trace::TraceFlags; /** * A mock sampler that returns non-empty sampling results attributes. @@ -48,22 +47,23 @@ class MockSampler final : public Sampler namespace { -std::shared_ptr initTracer( - std::unique_ptr &&exporter) +std::shared_ptr initTracer(std::unique_ptr &&exporter) { - auto processor = std::make_shared(std::move(exporter)); - auto resource = Resource::Create({}); - return std::shared_ptr(new Tracer(processor, resource)); + auto processor = std::unique_ptr(new SimpleSpanProcessor(std::move(exporter))); + auto context = std::make_shared(std::move(processor)); + return std::shared_ptr(new Tracer(context)); } std::shared_ptr initTracer( - std::unique_ptr &&exporter, - std::shared_ptr sampler) + std::unique_ptr &&exporter, + // For testing, just shove a pointer over, we'll take it over. + Sampler *sampler) { - auto processor = std::make_shared(std::move(exporter)); + auto processor = std::unique_ptr(new SimpleSpanProcessor(std::move(exporter))); auto resource = Resource::Create({}); - - return std::shared_ptr(new Tracer(processor, resource, sampler)); + auto context = std::make_shared(std::move(processor), resource, + std::unique_ptr(sampler)); + return std::shared_ptr(new Tracer(context)); } } // namespace @@ -122,7 +122,7 @@ TEST(Tracer, StartSpanSampleOff) { std::unique_ptr exporter(new InMemorySpanExporter()); std::shared_ptr span_data = exporter->GetData(); - auto tracer_off = initTracer(std::move(exporter), std::make_shared()); + auto tracer_off = initTracer(std::move(exporter), new AlwaysOffSampler()); // This span will not be recorded. tracer_off->StartSpan("span 2")->End(); @@ -283,19 +283,16 @@ TEST(Tracer, GetSampler) { auto resource = Resource::Create({}); // Create a Tracer with a default AlwaysOnSampler - std::shared_ptr processor_1(new SimpleSpanProcessor(nullptr)); - std::shared_ptr tracer_on(new Tracer(std::move(processor_1), resource)); + auto tracer_on = initTracer(nullptr); - auto t1 = tracer_on->GetSampler(); - ASSERT_EQ("AlwaysOnSampler", t1->GetDescription()); + auto &t1 = std::dynamic_pointer_cast(tracer_on)->GetSampler(); + ASSERT_EQ("AlwaysOnSampler", t1.GetDescription()); // Create a Tracer with a AlwaysOffSampler - std::shared_ptr processor_2(new SimpleSpanProcessor(nullptr)); - std::shared_ptr tracer_off( - new Tracer(std::move(processor_2), resource, std::make_shared())); + auto tracer_off = initTracer(nullptr, new AlwaysOffSampler()); - auto t2 = tracer_off->GetSampler(); - ASSERT_EQ("AlwaysOffSampler", t2->GetDescription()); + auto &t2 = std::dynamic_pointer_cast(tracer_off)->GetSampler(); + ASSERT_EQ("AlwaysOffSampler", t2.GetDescription()); } TEST(Tracer, SpanSetAttribute) @@ -441,7 +438,7 @@ TEST(Tracer, TestAlwaysOffSampler) { std::unique_ptr exporter(new InMemorySpanExporter()); std::shared_ptr span_data = exporter->GetData(); - auto tracer_off = initTracer(std::move(exporter), std::make_shared()); + auto tracer_off = initTracer(std::move(exporter), new AlwaysOffSampler()); auto span_off_1 = tracer_off->StartSpan("span 1"); auto span_off_2 = tracer_off->StartSpan("span 2"); @@ -461,8 +458,7 @@ TEST(Tracer, TestParentBasedSampler) std::unique_ptr exporter(new InMemorySpanExporter()); std::shared_ptr span_data_parent_on = exporter->GetData(); auto tracer_parent_on = - initTracer(std::move(exporter), - std::make_shared(std::make_shared())); + initTracer(std::move(exporter), new ParentBasedSampler(std::make_shared())); auto span_parent_on_1 = tracer_parent_on->StartSpan("span 1"); auto span_parent_on_2 = tracer_parent_on->StartSpan("span 2"); @@ -481,9 +477,8 @@ TEST(Tracer, TestParentBasedSampler) // so this sampler will work as an AlwaysOnSampler. std::unique_ptr exporter2(new InMemorySpanExporter()); std::shared_ptr span_data_parent_off = exporter2->GetData(); - auto tracer_parent_off = - initTracer(std::move(exporter2), - std::make_shared(std::make_shared())); + auto tracer_parent_off = initTracer(std::move(exporter2), + new ParentBasedSampler(std::make_shared())); auto span_parent_off_1 = tracer_parent_off->StartSpan("span 1"); auto span_parent_off_2 = tracer_parent_off->StartSpan("span 2"); @@ -563,52 +558,4 @@ TEST(Tracer, ExpectParent) EXPECT_EQ(spandata_first->GetSpanId(), spandata_second->GetParentSpanId()); EXPECT_EQ(spandata_second->GetSpanId(), spandata_third->GetParentSpanId()); -} - -TEST(Tracer, ExpectParentWithValidSpanContext) -{ - std::unique_ptr exporter(new InMemorySpanExporter()); - std::shared_ptr span_data = exporter->GetData(); - auto tracer = initTracer(std::move(exporter)); - auto spans = span_data.get()->GetSpans(); - - ASSERT_EQ(0, spans.size()); - - // produce valid SpanContext with pseudo span and trace Id. - uint8_t span_id_buf[trace_api::SpanId::kSize] = { - 1, - }; - trace_api::SpanId span_id{span_id_buf}; - uint8_t trace_id_buf[trace_api::TraceId::kSize] = { - 2, - }; - trace_api::TraceId trace_id{trace_id_buf}; - - trace_api::StartSpanOptions options; - options.parent = SpanContext(trace_id, span_id, TraceFlags{TraceFlags::kIsSampled}, true); - - auto span_first = tracer->StartSpan("span 1", options); - - EXPECT_EQ(span_first->GetContext().trace_flags().IsSampled(), true); - - options.parent = span_first->GetContext(); - auto span_second = tracer->StartSpan("span 2", options); - EXPECT_EQ(span_second->GetContext().trace_flags().IsSampled(), true); - - options.parent = span_second->GetContext(); - auto span_third = tracer->StartSpan("span 3", options); - EXPECT_EQ(span_third->GetContext().trace_flags().IsSampled(), true); - - span_third->End(); - span_second->End(); - span_first->End(); - - spans = span_data->GetSpans(); - ASSERT_EQ(3, spans.size()); - auto spandata_first = std::move(spans.at(2)); - auto spandata_second = std::move(spans.at(1)); - auto spandata_third = std::move(spans.at(0)); - - EXPECT_EQ(spandata_first->GetSpanId(), spandata_second->GetParentSpanId()); - EXPECT_EQ(spandata_second->GetSpanId(), spandata_third->GetParentSpanId()); -} +} \ No newline at end of file From 250253faf32acafcd4a1083a3cfcc7d0929fd2ec Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Sat, 17 Apr 2021 02:01:42 +0530 Subject: [PATCH 3/6] Add reference to getting started doc and api doc (#678) --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index eae8b2177c..3cb0634ce4 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ having C++ compiler with [supported C++ standards](#supported-c-versions). Please refer to [INSTALL.md](./INSTALL.md). -## Quick Start +## Getting Started + +As an application owner or the library author, you can find the getting started guide and reference documentation on [opentelemetry-cpp.readthedocs.io](https://opentelemetry-cpp.readthedocs.io/en/latest/) The `examples/simple` directory contains a minimal program demonstrating how to instrument a small library using a simple `processor` and console `exporter`, From 903765f4f1a7252939689a4ab8107f3d3a5f9376 Mon Sep 17 00:00:00 2001 From: iocumine Date: Tue, 20 Apr 2021 04:13:24 +0200 Subject: [PATCH 4/6] compiler error with gcc 5.4.0 fixed (#682) --- .../opentelemetry/exporters/ostream/span_exporter.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h index e74568814c..eeed9a6fd4 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h @@ -100,7 +100,12 @@ class OStreamSpanExporter final : public sdktrace::SpanExporter #if __cplusplus < 201402L nostd::visit(OwnedAttributeValueVisitor(*this), value); #else - nostd::visit([this](auto &&arg) { print_value(arg); }, value); + nostd::visit( + [this](auto &&arg) { + /* explicit this is needed by some gcc versions (observed with v5.4.0)*/ + this->print_value(arg); + }, + value); #endif } From 14eef5d3611530ce3104a387c07c2e019ef07503 Mon Sep 17 00:00:00 2001 From: Johannes Tax Date: Tue, 20 Apr 2021 02:08:41 -0700 Subject: [PATCH 5/6] Attribute value cleanup (#679) --- api/docs/Doxyfile | 2 +- .../opentelemetry/common/attribute_value.h | 49 +++++++++++++------ .../exporters/etw/etw_properties.h | 19 +++---- .../exporters/etw/etw_provider.h | 6 +-- exporters/otlp/src/recordable.cc | 8 --- exporters/zipkin/src/recordable.cc | 8 --- .../sdk/common/attribute_utils.h | 32 ++++++------ 7 files changed, 59 insertions(+), 65 deletions(-) diff --git a/api/docs/Doxyfile b/api/docs/Doxyfile index a38f30e6c0..9d54b62352 100644 --- a/api/docs/Doxyfile +++ b/api/docs/Doxyfile @@ -867,7 +867,7 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = "AttributeType" # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/api/include/opentelemetry/common/attribute_value.h b/api/include/opentelemetry/common/attribute_value.h index 59a5618316..a83133f13e 100644 --- a/api/include/opentelemetry/common/attribute_value.h +++ b/api/include/opentelemetry/common/attribute_value.h @@ -10,26 +10,49 @@ OPENTELEMETRY_BEGIN_NAMESPACE namespace common { +/// OpenTelemetry signals can be enriched by adding attributes. The +/// \c AttributeValue type is defined as a variant of all attribute value +/// types the OpenTelemetry C++ API supports. +/// +/// The following attribute value types are supported by the OpenTelemetry +/// specification: +/// - Primitive types: string, boolean, double precision floating point +/// (IEEE 754-1985) or signed 64 bit integer. +/// - Homogenous arrays of primitive type values. +/// +/// \warning +/// \parblock The OpenTelemetry C++ API currently supports several attribute +/// value types that are not covered by the OpenTelemetry specification: +/// - \c uint64_t +/// - \c nostd::span +/// - \c nostd::span +/// +/// Those types are reserved for future use and currently should not be +/// used. There are no guarantees around how those values are handled by +/// exporters. +/// \endparblock using AttributeValue = nostd::variant, -#endif nostd::span, nostd::span, nostd::span, nostd::span, - nostd::span, nostd::span, - nostd::span>; + nostd::span, + // Not currently supported by the specification, but reserved for future use. + // Added to provide support for all primitive C++ types. + uint64_t, + // Not currently supported by the specification, but reserved for future use. + // Added to provide support for all primitive C++ types. + nostd::span, + // Not currently supported by the specification, but reserved for future use. + // See https://github.com/open-telemetry/opentelemetry-specification/issues/780 + nostd::span>; enum AttributeType { @@ -37,19 +60,17 @@ enum AttributeType kTypeInt, kTypeInt64, kTypeUInt, - kTypeUInt64, kTypeDouble, kTypeString, -#ifdef HAVE_SPAN_BYTE - kTypeSpanByte, -#endif kTypeSpanBool, kTypeSpanInt, kTypeSpanInt64, kTypeSpanUInt, - kTypeSpanUInt64, kTypeSpanDouble, - kTypeSpanString + kTypeSpanString, + kTypeUInt64, + kTypeSpanUInt64, + kTypeSpanByte }; } // namespace common diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 542951fb6a..a8864c2cb6 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -42,11 +42,9 @@ using PropertyVariant = double, std::string, const char *, -#ifdef HAVE_SPAN_BYTE - // TODO: 8-bit byte arrays / binary blobs are not part of OT spec yet! + // 8-bit byte arrays / binary blobs are not part of OT spec yet! // Ref: https://github.com/open-telemetry/opentelemetry-specification/issues/780 std::vector, -#endif std::vector, std::vector, std::vector, @@ -65,9 +63,7 @@ enum PropertyType kTypeDouble, kTypeString, kTypeCString, -#ifdef HAVE_SPAN_BYTE kTypeSpanByte, -#endif kTypeSpanBool, kTypeSpanInt, kTypeSpanInt64, @@ -229,11 +225,11 @@ class PropertyValue : public PropertyVariant PropertyVariant::operator=(nostd::string_view(nostd::get(v)).data()); break; }; -#ifdef HAVE_SPAN_BYTE + case common::AttributeType::kTypeSpanByte: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; -#endif + case common::AttributeType::kTypeSpanBool: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; @@ -306,13 +302,10 @@ class PropertyValue : public PropertyVariant return nostd::string_view(data, (data) ? strlen(data) : 0); break; } - -#ifdef HAVE_SPAN_BYTE - case common::AttributeType::kTypeSpanByte: - value = to_span(nostd::get>(self)); + case PropertyType::kTypeSpanByte: { + value = to_span(nostd::get>(*this)); break; -#endif - + } case PropertyType::kTypeSpanBool: { const auto &vec = nostd::get>(*this); // FIXME: sort out how to remap from vector to span diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 0493f818c7..ee4e19c2f5 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -352,9 +352,7 @@ class ETWProvider # endif // TODO: arrays are not supported yet -# ifdef HAVE_SPAN_BYTE - case common::AttributeType::TYPE_SPAN_BYTE: -# endif + case PropertyType::kTypeSpanByte: case PropertyType::kTypeSpanBool: case PropertyType::kTypeSpanInt: case PropertyType::kTypeSpanInt64: @@ -531,9 +529,7 @@ class ETWProvider # endif // TODO: arrays are not supported -# ifdef HAVE_SPAN_BYTE case PropertyType::kTypeSpanByte: -# endif case PropertyType::kTypeSpanBool: case PropertyType::kTypeSpanInt: case PropertyType::kTypeSpanInt64: diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index ebc2de090b..b236ef125e 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -8,14 +8,8 @@ namespace otlp // // See `attribute_value.h` for details. -// Expecting to remove the two feature gates for: -// - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). // -#if defined(HAVE_SPAN_BYTE) const int kAttributeValueSize = 15; -#else -const int kAttributeValueSize = 14; -#endif void Recordable::SetIdentity(const opentelemetry::trace::SpanContext &span_context, opentelemetry::trace::SpanId parent_span_id) noexcept @@ -70,7 +64,6 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, attribute->mutable_value()->set_string_value(nostd::get(value).data(), nostd::get(value).size()); } -#ifdef HAVE_SPAN_BYTE else if (nostd::holds_alternative>(value)) { for (const auto &val : nostd::get>(value)) @@ -78,7 +71,6 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); } } -#endif else if (nostd::holds_alternative>(value)) { for (const auto &val : nostd::get>(value)) diff --git a/exporters/zipkin/src/recordable.cc b/exporters/zipkin/src/recordable.cc index dfba118a7f..14d9c1fafc 100644 --- a/exporters/zipkin/src/recordable.cc +++ b/exporters/zipkin/src/recordable.cc @@ -26,14 +26,8 @@ namespace zipkin // // See `attribute_value.h` for details. -// Expecting to remove the two feature gates for: -// - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). // -#if defined(HAVE_SPAN_BYTE) const int kAttributeValueSize = 15; -#else -const int kAttributeValueSize = 14; -#endif void Recordable::SetIdentity(const opentelemetry::trace::SpanContext &span_context, opentelemetry::trace::SpanId parent_span_id) noexcept @@ -88,7 +82,6 @@ void PopulateAttribute(nlohmann::json &attribute, attribute[key.data()] = nostd::string_view(nostd::get(value).data(), nostd::get(value).size()); } -#ifdef HAVE_SPAN_BYTE else if (nostd::holds_alternative>(value)) { attribute[key.data()] = {}; @@ -97,7 +90,6 @@ void PopulateAttribute(nlohmann::json &attribute, attribute[key.data()].push_back(val); } } -#endif else if (nostd::holds_alternative>(value)) { attribute[key.data()] = {}; diff --git a/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/sdk/include/opentelemetry/sdk/common/attribute_utils.h index 3308be3bb4..98521b707b 100644 --- a/sdk/include/opentelemetry/sdk/common/attribute_utils.h +++ b/sdk/include/opentelemetry/sdk/common/attribute_utils.h @@ -30,24 +30,28 @@ namespace common /** * A counterpart to AttributeValue that makes sure a value is owned. This * replaces all non-owning references with owned copies. + * + * The following types are not currently supported by the OpenTelemetry + * specification, but reserved for future use: + * - uint64_t + * - std::vector + * - std::vector */ using OwnedAttributeValue = nostd::variant, -#endif std::vector, std::vector, - std::vector, std::vector, - std::vector, + std::vector, std::vector, - std::vector>; + std::vector, + uint64_t, + std::vector, + std::vector>; enum OwnedAttributeType { @@ -55,19 +59,17 @@ enum OwnedAttributeType kTypeInt, kTypeInt64, kTypeUInt, - kTypeUInt64, kTypeDouble, kTypeString, -#ifdef HAVE_SPAN_BYTE - kTypeSpanByte, -#endif kTypeSpanBool, kTypeSpanInt, kTypeSpanInt64, kTypeSpanUInt, - kTypeSpanUInt64, kTypeSpanDouble, - kTypeSpanString + kTypeSpanString, + kTypeUInt64, + kTypeSpanUInt64, + kTypeSpanByte }; /** @@ -86,9 +88,7 @@ struct AttributeConverter return OwnedAttributeValue(std::string(v)); } OwnedAttributeValue operator()(const char *v) { return OwnedAttributeValue(std::string(v)); } -#ifdef HAVE_SPAN_BYTE OwnedAttributeValue operator()(nostd::span v) { return convertSpan(v); } -#endif OwnedAttributeValue operator()(nostd::span v) { return convertSpan(v); } OwnedAttributeValue operator()(nostd::span v) { return convertSpan(v); } OwnedAttributeValue operator()(nostd::span v) { return convertSpan(v); } From ae060d157bbd7b13c010707e88f5ac18eb53f592 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Tue, 20 Apr 2021 09:36:56 -0700 Subject: [PATCH 6/6] Enable resource detector tests on Windows (#651) --- sdk/test/resource/resource_test.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sdk/test/resource/resource_test.cc b/sdk/test/resource/resource_test.cc index 7cc3c7a9d2..1f58ee2f9c 100644 --- a/sdk/test/resource/resource_test.cc +++ b/sdk/test/resource/resource_test.cc @@ -10,6 +10,10 @@ #include +#if defined(_MSC_VER) +# define putenv _putenv +#endif + class TestResource : public opentelemetry::sdk::resource::Resource { public: @@ -150,9 +154,6 @@ TEST(ResourceTest, MergeEmptyString) EXPECT_EQ(received_attributes.size(), expected_attributes.size()); } -// this test uses putenv to set the env variable - this is not available on windows -#ifdef __linux__ - TEST(ResourceTest, OtelResourceDetector) { std::map expected_attributes = {{"k", "v"}}; @@ -173,13 +174,21 @@ TEST(ResourceTest, OtelResourceDetector) } } EXPECT_EQ(received_attributes.size(), expected_attributes.size()); +#if defined(_MSC_VER) + putenv("OTEL_RESOURCE_ATTRIBUTES="); +#else unsetenv("OTEL_RESOURCE_ATTRIBUTES"); +#endif } TEST(ResourceTest, OtelResourceDetectorEmptyEnv) { std::map expected_attributes = {}; +#if defined(_MSC_VER) + putenv("OTEL_RESOURCE_ATTRIBUTES="); +#else unsetenv("OTEL_RESOURCE_ATTRIBUTES"); +#endif opentelemetry::sdk::resource::OTELResourceDetector detector; auto resource = detector.Detect(); auto received_attributes = resource.GetAttributes(); @@ -194,4 +203,3 @@ TEST(ResourceTest, OtelResourceDetectorEmptyEnv) } EXPECT_EQ(received_attributes.size(), expected_attributes.size()); } -#endif // __linux__ \ No newline at end of file