From e072daa229f72431b1c50986645d51180a586d09 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 21 Mar 2022 15:02:15 +0100 Subject: [PATCH 01/69] install sdk config (#1273) --- sdk/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index 9aa45883e5..6421e3ad15 100644 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -13,6 +13,12 @@ install( LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install( + DIRECTORY include/opentelemetry/ + DESTINATION include/opentelemetry/ + FILES_MATCHING + PATTERN "*config.h") + set(LOGS_EXCLUDE_PATTERN "") if(NOT WITH_LOGS_PREVIEW) set(LOGS_EXCLUDE_PATTERN "logs") From 6ec1b596fde0a2d443f5d730bcd14384b68c68e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 22 Mar 2022 18:27:20 +0100 Subject: [PATCH 02/69] Bump actions/cache from 2 to 3 (#1277) --- .github/workflows/benchmark.yml | 2 +- .github/workflows/ci.yml | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index c11e0c564a..cc685faffd 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -17,7 +17,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fd8f80838..a851728a2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -136,7 +136,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -158,7 +158,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -180,7 +180,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -202,7 +202,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -224,7 +224,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -246,7 +246,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -268,7 +268,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: @@ -285,7 +285,7 @@ jobs: with: submodules: 'recursive' - name: Mount Bazel Cache - uses: actions/cache@v2 + uses: actions/cache@v3 env: cache-name: bazel_cache with: From b5155a5dea3a8816d1d0aa3f513d6a5c13245d9b Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 23 Mar 2022 08:06:46 -0700 Subject: [PATCH 03/69] Add owent as an Approver (#1276) * add owent as reviewer * fix order --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 18b9aafd14..7dc77fc940 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ For edit access, get in touch on * [Josh Suereth](https://github.com/jsuereth), Google * [Reiley Yang](https://github.com/reyang), Microsoft +* [WenTao Ou](https://github.com/owent), Tencent [Emeritus Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/main/community-membership.md#emeritus-maintainerapprovertriager): From 0c9aecea7af2f3f835f79397feb1436f8d51cc25 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Thu, 24 Mar 2022 16:45:38 +0100 Subject: [PATCH 04/69] Disable benchmark action failure (#1284) --- .github/workflows/benchmark.yml | 2 +- docs/{ => public}/performance/benchmarks.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docs/{ => public}/performance/benchmarks.rst (69%) diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index cc685faffd..d6b12b82d0 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -67,6 +67,6 @@ jobs: # Show alert with commit comment on detecting possible performance regression alert-threshold: '200%' comment-on-alert: true - fail-on-alert: true + fail-on-alert: false gh-pages-branch: gh-pages benchmark-data-dir-path: benchmarks diff --git a/docs/performance/benchmarks.rst b/docs/public/performance/benchmarks.rst similarity index 69% rename from docs/performance/benchmarks.rst rename to docs/public/performance/benchmarks.rst index 0f1044be42..39b13571dc 100644 --- a/docs/performance/benchmarks.rst +++ b/docs/public/performance/benchmarks.rst @@ -3,4 +3,4 @@ Performance Tests - Benchmarks Click `here `_ to view the latest performance benchmarks for packages in this repo. -Please note that the flutation in the results are mainly because [machines with different CPUs](https://github.com/benchmark-action/github-action-benchmark/issues/79) are used for tests. +Please note that the flutation in the results are mainly because `machines with different CPUs `_ are used for tests. From 3c7b44bf4f7a615364b78d4449eaa5f7ac121249 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Thu, 24 Mar 2022 22:31:41 +0100 Subject: [PATCH 05/69] metrics exemplar round 1 (#1264) --- api/include/opentelemetry/metrics/noop.h | 17 +++- .../opentelemetry/metrics/sync_instruments.h | 90 +++++++++++++++---- api/test/metrics/BUILD | 31 +++++++ api/test/metrics/noop_sync_instrument_test.cc | 13 ++- .../metrics/exemplar/always_sample_filter.h | 43 +++++++++ .../opentelemetry/sdk/metrics/exemplar/data.h | 45 ++++++++++ .../sdk/metrics/exemplar/filter.h | 39 ++++++++ .../metrics/exemplar/never_sample_filter.h | 43 +++++++++ .../metrics/exemplar/no_exemplar_reservoir.h | 55 ++++++++++++ .../sdk/metrics/exemplar/reservoir.h | 55 ++++++++++++ .../sdk/metrics/measurement_processor.h | 42 +++++---- .../sdk/metrics/state/metric_storage.h | 24 +++-- .../sdk/metrics/state/multi_metric_storage.h | 26 +++--- .../sdk/metrics/state/sync_metric_storage.h | 26 ++++-- .../sdk/metrics/sync_instruments.h | 26 +++++- .../sdk/metrics/view/attributes_processor.h | 2 - sdk/src/metrics/meter.cc | 4 +- sdk/src/metrics/sync_instruments.cc | 90 +++++++++++++++---- sdk/test/metrics/BUILD | 16 ++++ sdk/test/metrics/CMakeLists.txt | 2 + sdk/test/metrics/exemplar/BUILD | 47 ++++++++++ sdk/test/metrics/exemplar/CMakeLists.txt | 10 +++ .../exemplar/always_sample_filter_test.cc | 19 ++++ .../exemplar/never_sample_filter_test.cc | 20 +++++ .../exemplar/no_exemplar_reservoir_test.cc | 22 +++++ sdk/test/metrics/multi_metric_storage_test.cc | 27 ++++-- sdk/test/metrics/sync_instruments_test.cc | 50 ++++++++--- sdk/test/metrics/sync_metric_storage_test.cc | 16 ++-- 28 files changed, 787 insertions(+), 113 deletions(-) create mode 100644 api/test/metrics/BUILD create mode 100644 sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h create mode 100644 sdk/include/opentelemetry/sdk/metrics/exemplar/data.h create mode 100644 sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h create mode 100644 sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h create mode 100644 sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h create mode 100644 sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h create mode 100644 sdk/test/metrics/exemplar/BUILD create mode 100644 sdk/test/metrics/exemplar/CMakeLists.txt create mode 100644 sdk/test/metrics/exemplar/always_sample_filter_test.cc create mode 100644 sdk/test/metrics/exemplar/never_sample_filter_test.cc create mode 100644 sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index 19b9443a7d..3332384ee2 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -24,7 +24,12 @@ class NoopCounter : public Counter nostd::string_view unit) noexcept {} void Add(T value) noexcept override {} + void Add(T value, const opentelemetry::context::Context &context) noexcept override {} void Add(T value, const common::KeyValueIterable &attributes) noexcept override {} + void Add(T value, + const common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override + {} }; template @@ -35,8 +40,11 @@ class NoopHistogram : public Histogram nostd::string_view description, nostd::string_view unit) noexcept {} - void Record(T value) noexcept override {} - void Record(T value, const common::KeyValueIterable &attributes) noexcept override {} + void Record(T value, const opentelemetry::context::Context &context) noexcept override {} + void Record(T value, + const common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override + {} }; template @@ -48,7 +56,12 @@ class NoopUpDownCounter : public UpDownCounter nostd::string_view unit) noexcept {} void Add(T value) noexcept override {} + void Add(T value, const opentelemetry::context::Context &context) noexcept override {} void Add(T value, const common::KeyValueIterable &attributes) noexcept override {} + void Add(T value, + const common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override + {} }; template diff --git a/api/include/opentelemetry/metrics/sync_instruments.h b/api/include/opentelemetry/metrics/sync_instruments.h index 35cb8621ab..e8239743a1 100644 --- a/api/include/opentelemetry/metrics/sync_instruments.h +++ b/api/include/opentelemetry/metrics/sync_instruments.h @@ -6,6 +6,7 @@ # include "opentelemetry/common/attribute_value.h" # include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/context/context.h" # include "opentelemetry/nostd/span.h" # include "opentelemetry/nostd/string_view.h" # include "opentelemetry/nostd/type_traits.h" @@ -29,6 +30,8 @@ class Counter : public SynchronousInstrument */ virtual void Add(T value) noexcept = 0; + virtual void Add(T value, const opentelemetry::context::Context &context) noexcept = 0; + /** * Add adds the value to the counter's sum. The attributes should contain * the keys and values to be associated with this value. Counters only @@ -40,19 +43,44 @@ class Counter : public SynchronousInstrument virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; + virtual void Add(T value, + const common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; + template ::value> * = nullptr> void Add(T value, const U &attributes) noexcept { - this->Add(value, common::KeyValueIterableView{attributes}); + auto context = opentelemetry::context::Context{}; + this->Add(value, common::KeyValueIterableView{attributes}, context); + } + + template ::value> * = nullptr> + void Add(T value, const U &attributes, const opentelemetry::context::Context &context) noexcept + { + this->Add(value, common::KeyValueIterableView{attributes}, context); } void Add(T value, std::initializer_list> attributes) noexcept { - this->Add(value, nostd::span>{ - attributes.begin(), attributes.end()}); + auto context = opentelemetry::context::Context{}; + this->Add(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); + } + + void Add(T value, + std::initializer_list> attributes, + const opentelemetry::context::Context &context) noexcept + { + this->Add(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); } }; @@ -67,7 +95,7 @@ class Histogram : public SynchronousInstrument * * @param value The increment amount. May be positive, negative or zero. */ - virtual void Record(T value) noexcept = 0; + virtual void Record(T value, const opentelemetry::context::Context &context) noexcept = 0; /** * Records a value with a set of attributes. @@ -75,21 +103,26 @@ class Histogram : public SynchronousInstrument * @param value The increment amount. May be positive, negative or zero. * @param attributes A set of attributes to associate with the count. */ - virtual void Record(T value, const common::KeyValueIterable &attributes) noexcept = 0; + virtual void Record(T value, + const common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; template ::value> * = nullptr> - void Record(T value, const U &attributes) noexcept + void Record(T value, const U &attributes, const opentelemetry::context::Context &context) noexcept { - this->Record(value, common::KeyValueIterableView{attributes}); + this->Record(value, common::KeyValueIterableView{attributes}, context); } - void Record(T value, - std::initializer_list> - attributes) noexcept + void Record( + T value, + std::initializer_list> attributes, + const opentelemetry::context::Context &context) noexcept { - this->Record(value, nostd::span>{ - attributes.begin(), attributes.end()}); + this->Record(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); } }; @@ -106,6 +139,8 @@ class UpDownCounter : public SynchronousInstrument */ virtual void Add(T value) noexcept = 0; + virtual void Add(T value, const opentelemetry::context::Context &context) noexcept = 0; + /** * Add a value with a set of attributes. * @@ -114,19 +149,44 @@ class UpDownCounter : public SynchronousInstrument */ virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; + virtual void Add(T value, + const common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; + template ::value> * = nullptr> void Add(T value, const U &attributes) noexcept { - this->Add(value, common::KeyValueIterableView{attributes}); + auto context = opentelemetry::context::Context{}; + this->Add(value, common::KeyValueIterableView{attributes}, context); + } + + template ::value> * = nullptr> + void Add(T value, const U &attributes, const opentelemetry::context::Context &context) noexcept + { + this->Add(value, common::KeyValueIterableView{attributes}, context); } void Add(T value, std::initializer_list> attributes) noexcept { - this->Add(value, nostd::span>{ - attributes.begin(), attributes.end()}); + auto context = opentelemetry::context::Context{}; + this->Add(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); + } + + void Add(T value, + std::initializer_list> attributes, + const opentelemetry::context::Context &context) noexcept + { + this->Add(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); } }; diff --git a/api/test/metrics/BUILD b/api/test/metrics/BUILD new file mode 100644 index 0000000000..d15d7511f4 --- /dev/null +++ b/api/test/metrics/BUILD @@ -0,0 +1,31 @@ +load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark") + +cc_test( + name = "noop_sync_instrument_test", + srcs = [ + "noop_sync_instrument_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "meter_provider_test", + srcs = [ + "meter_provider_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/api/test/metrics/noop_sync_instrument_test.cc b/api/test/metrics/noop_sync_instrument_test.cc index 4597e79e8b..62be4f34ab 100644 --- a/api/test/metrics/noop_sync_instrument_test.cc +++ b/api/test/metrics/noop_sync_instrument_test.cc @@ -14,8 +14,11 @@ TEST(Counter, Add) std::map labels = {{"k1", "v1"}}; EXPECT_NO_THROW(counter->Add(10l, labels)); + EXPECT_NO_THROW(counter->Add(10l, labels, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter->Add(2l)); + EXPECT_NO_THROW(counter->Add(2l, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}})); + EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{})); } TEST(histogram, Record) @@ -24,9 +27,10 @@ TEST(histogram, Record) new opentelemetry::metrics::NoopHistogram("test", "none", "unitless")}; std::map labels = {{"k1", "v1"}}; - EXPECT_NO_THROW(counter->Record(10l, labels)); - EXPECT_NO_THROW(counter->Record(2l)); - EXPECT_NO_THROW(counter->Record(10l, {{"k1", "1"}, {"k2", 2}})); + EXPECT_NO_THROW(counter->Record(10l, labels, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter->Record(2l, opentelemetry::context::Context{})); + EXPECT_NO_THROW( + counter->Record(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{})); } TEST(UpDownCountr, Record) @@ -36,8 +40,11 @@ TEST(UpDownCountr, Record) std::map labels = {{"k1", "v1"}}; EXPECT_NO_THROW(counter->Add(10l, labels)); + EXPECT_NO_THROW(counter->Add(10l, labels, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter->Add(2l)); + EXPECT_NO_THROW(counter->Add(2l, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}})); + EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{})); } #endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h new file mode 100644 index 0000000000..5e7f0436eb --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h @@ -0,0 +1,43 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/filter.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class AlwaysSampleFilter final : public ExemplarFilter +{ +public: + static nostd::shared_ptr GetAlwaysSampleFilter() + { + static nostd::shared_ptr alwaysSampleFilter{new AlwaysSampleFilter{}}; + return alwaysSampleFilter; + } + + bool ShouldSampleMeasurement(long value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) noexcept override + { + return true; + } + + bool ShouldSampleMeasurement(double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) noexcept override + { + return true; + } + +private: + explicit AlwaysSampleFilter() = default; +}; +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h new file mode 100644 index 0000000000..14eac62499 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h @@ -0,0 +1,45 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/timestamp.h" +# include "opentelemetry/context/context.h" +# include "opentelemetry/sdk/common/attribute_utils.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; +/** + * A sample input measurement. + * + * Exemplars also hold information about the environment when the measurement was recorded, for + * example the span and trace ID of the active span when the exemplar was recorded. + */ +class ExemplarData +{ +public: + /** + * The set of key/value pairs that were filtered out by the aggregator, but recorded alongside the + * original measurement. Only key/value pairs that were filtered out by the aggregator should be + * included + */ + MetricAttributes GetFilteredAttributes(); + + /** Returns the timestamp in nanos when measurement was collected. */ + opentelemetry::common::SystemTimestamp GetEpochNanos(); + + /** + * Returns the SpanContext associated with this exemplar. If the exemplar was not recorded + * inside a sampled trace, the Context will be invalid. + */ + opentelemetry::context::Context GetSpanContext(); +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h new file mode 100644 index 0000000000..4b512e1317 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h @@ -0,0 +1,39 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/context/context.h" +# include "opentelemetry/sdk/common/attribute_utils.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; + +/** + * Exemplar filters are used to pre-filter measurements before attempting to store them in a + * reservoir. + */ +class ExemplarFilter +{ +public: + // Returns whether or not a reservoir should attempt to filter a measurement. + virtual bool ShouldSampleMeasurement(long value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) noexcept = 0; + + // Returns whether or not a reservoir should attempt to filter a measurement. + virtual bool ShouldSampleMeasurement(double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) noexcept = 0; + + virtual ~ExemplarFilter() = default; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h new file mode 100644 index 0000000000..38f51778ce --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h @@ -0,0 +1,43 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/filter.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class NeverSampleFilter final : public ExemplarFilter +{ +public: + static nostd::shared_ptr GetNeverSampleFilter() + { + nostd::shared_ptr neverSampleFilter{new NeverSampleFilter{}}; + return neverSampleFilter; + } + + bool ShouldSampleMeasurement(long value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) noexcept override + { + return false; + } + + bool ShouldSampleMeasurement(double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) noexcept override + { + return false; + } + +private: + explicit NeverSampleFilter() = default; +}; +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h new file mode 100644 index 0000000000..1fe0586d28 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class NoExemplarReservoir final : public ExemplarReservoir +{ + +public: + static nostd::shared_ptr GetNoExemplarReservoir() + { + return nostd::shared_ptr{new NoExemplarReservoir{}}; + } + + void OfferMeasurement(long value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp ×tamp) noexcept override + { + // Stores nothing + } + + void OfferMeasurement(double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp ×tamp) noexcept override + { + // Stores nothing. + } + + std::vector CollectAndReset( + const MetricAttributes &pointAttributes) noexcept override + { + return std::vector{}; + } + +private: + explicit NoExemplarReservoir() = default; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h new file mode 100644 index 0000000000..25e8421d6b --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h @@ -0,0 +1,55 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/sdk/metrics/exemplar/data.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +/** + * An interface for an exemplar reservoir of samples. + * + *

This represents a reservoir for a specific "point" of metric data. + */ +class ExemplarReservoir +{ +public: + virtual ~ExemplarReservoir() = default; + + /** Offers a long measurement to be sampled. */ + virtual void OfferMeasurement( + long value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp ×tamp) noexcept = 0; + + /** Offers a double measurement to be sampled. */ + virtual void OfferMeasurement( + double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp ×tamp) noexcept = 0; + + /** + * Builds vector of Exemplars for exporting from the current reservoir. + * + *

Additionally, clears the reservoir for the next sampling period. + * + * @param pointAttributes the Attributes associated with the metric point. + * ExemplarDatas should filter these out of their final data state. + * @return A vector of sampled exemplars for this point. Implementers are expected to + * filter out pointAttributes from the original recorded attributes. + */ + virtual std::vector CollectAndReset( + const MetricAttributes &pointAttributes) noexcept = 0; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h b/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h index ffd47c5c92..f3b998451b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h @@ -2,10 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once +#include #ifndef ENABLE_METRICS_PREVIEW # include # include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/metric_reader.h" # include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" @@ -25,15 +27,18 @@ static std::size_t MakeKey(const MetricReader &metric_reader) class MeasurementProcessor { public: - virtual void RecordLong(long value) noexcept = 0; + virtual void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0; virtual void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0; + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; - virtual void RecordDouble(double value) noexcept = 0; + virtual void RecordDouble(double value, + const opentelemetry::context::Context &context) noexcept = 0; virtual void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0; + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; virtual bool Collect(MetricReader &reader, AggregationTemporarily aggregation_temporarily, @@ -50,43 +55,46 @@ class DefaultMeasurementProcessor : public MeasurementProcessor InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, InstrumentValueType::kLong}; metric_storages_[MakeKey(reader)] = std::unique_ptr( - new SyncMetricStorage(instr_desc, AggregationType::kSum, new DefaultAttributesProcessor())); + new SyncMetricStorage(instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), + NoExemplarReservoir::GetNoExemplarReservoir())); return true; } - virtual void RecordLong(long value) noexcept override + virtual void RecordLong(long value, + const opentelemetry::context::Context &context) noexcept override { for (const auto &kv : metric_storages_) { - kv.second->RecordLong(value); + kv.second->RecordLong(value, context); } } - virtual void RecordLong( - long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + virtual void RecordLong(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { for (const auto &kv : metric_storages_) { - kv.second->RecordLong(value, attributes); + kv.second->RecordLong(value, attributes, context); } } - virtual void RecordDouble(double value) noexcept override + virtual void RecordDouble(double value, + const opentelemetry::context::Context &context) noexcept override { for (const auto &kv : metric_storages_) { - kv.second->RecordDouble(value); + kv.second->RecordDouble(value, context); } } - virtual void RecordDouble( - double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + virtual void RecordDouble(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { for (const auto &kv : metric_storages_) { - kv.second->RecordDouble(value, attributes); + kv.second->RecordDouble(value, attributes, context); } } diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h index 8ae50554f1..20f7d56140 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h @@ -5,6 +5,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/common/key_value_iterable_view.h" # include "opentelemetry/common/timestamp.h" +# include "opentelemetry/context/context.h" # include "opentelemetry/sdk/metrics/data/metric_data.h" # include "opentelemetry/sdk/metrics/instruments.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -30,15 +31,19 @@ class MetricStorage class WritableMetricStorage { public: - virtual void RecordLong(long value) noexcept = 0; + virtual void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0; virtual void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0; + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; - virtual void RecordDouble(double value) noexcept = 0; + virtual void RecordDouble(double value, + const opentelemetry::context::Context &context) noexcept = 0; virtual void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept = 0; + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept = 0; + virtual ~WritableMetricStorage() = default; }; @@ -63,16 +68,19 @@ class NoopMetricStorage : public MetricStorage class NoopWritableMetricStorage : public WritableMetricStorage { public: - void RecordLong(long value) noexcept = 0; + void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0; void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override {} - void RecordDouble(double value) noexcept override {} + void RecordDouble(double value, const opentelemetry::context::Context &context) noexcept override + {} void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override {} }; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h index d9a66f732a..ceeafa0406 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h @@ -20,39 +20,41 @@ class MultiMetricStorage : public WritableMetricStorage public: void AddStorage(std::shared_ptr storage) { storages_.push_back(storage); } - virtual void RecordLong(long value) noexcept override + virtual void RecordLong(long value, + const opentelemetry::context::Context &context) noexcept override { for (auto &s : storages_) { - s->RecordLong(value); + s->RecordLong(value, context); } } - virtual void RecordLong( - long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + virtual void RecordLong(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { for (auto &s : storages_) { - s->RecordLong(value, attributes); + s->RecordLong(value, attributes, context); } } - virtual void RecordDouble(double value) noexcept override + virtual void RecordDouble(double value, + const opentelemetry::context::Context &context) noexcept override { for (auto &s : storages_) { - s->RecordDouble(value); + s->RecordDouble(value, context); } } - virtual void RecordDouble( - double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + virtual void RecordDouble(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { for (auto &s : storages_) { - s->RecordDouble(value, attributes); + s->RecordDouble(value, attributes, context); } } diff --git a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h index f8c2a86aa4..bfe50b152d 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -7,6 +7,7 @@ # include "opentelemetry/sdk/common/attributemap_hash.h" # include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" # include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" @@ -27,11 +28,13 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage public: SyncMetricStorage(InstrumentDescriptor instrument_descriptor, const AggregationType aggregation_type, - const AttributesProcessor *attributes_processor) + const AttributesProcessor *attributes_processor, + nostd::shared_ptr &&exemplar_reservoir) : instrument_descriptor_(instrument_descriptor), aggregation_type_{aggregation_type}, attributes_hashmap_(new AttributesHashMap()), - attributes_processor_{attributes_processor} + attributes_processor_{attributes_processor}, + exemplar_reservoir_(exemplar_reservoir) { create_default_aggregation_ = [&]() -> std::unique_ptr { return std::move( @@ -39,45 +42,55 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage }; } - void RecordLong(long value) noexcept override + void RecordLong(long value, const opentelemetry::context::Context &context) noexcept override { if (instrument_descriptor_.value_type_ != InstrumentValueType::kLong) { return; } + exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value); } void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { if (instrument_descriptor_.value_type_ != InstrumentValueType::kLong) { return; } + exemplar_reservoir_->OfferMeasurement(value, attributes, context, + std::chrono::system_clock::now()); auto attr = attributes_processor_->process(attributes); attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value); } - void RecordDouble(double value) noexcept override + void RecordDouble(double value, const opentelemetry::context::Context &context) noexcept override { if (instrument_descriptor_.value_type_ != InstrumentValueType::kDouble) { return; } + exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value); } void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { + exemplar_reservoir_->OfferMeasurement(value, attributes, context, + std::chrono::system_clock::now()); if (instrument_descriptor_.value_type_ != InstrumentValueType::kDouble) { return; } + exemplar_reservoir_->OfferMeasurement(value, attributes, context, + std::chrono::system_clock::now()); auto attr = attributes_processor_->process(attributes); attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value); } @@ -102,6 +115,7 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage std::unique_ptr attributes_hashmap_; const AttributesProcessor *attributes_processor_; std::function()> create_default_aggregation_; + nostd::shared_ptr exemplar_reservoir_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h b/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h index 3e8c5c8623..f4c9bae323 100644 --- a/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h @@ -39,8 +39,12 @@ class LongCounter : public Synchronous, public opentelemetry::metrics::Counter storage); void Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + void Add(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override; void Add(long value) noexcept override; + void Add(long value, const opentelemetry::context::Context &context) noexcept override; }; class DoubleCounter : public Synchronous, public opentelemetry::metrics::Counter @@ -52,8 +56,12 @@ class DoubleCounter : public Synchronous, public opentelemetry::metrics::Counter void Add(double value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + void Add(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override; void Add(double value) noexcept override; + void Add(double value, const opentelemetry::context::Context &context) noexcept override; }; class LongUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter @@ -63,8 +71,12 @@ class LongUpDownCounter : public Synchronous, public opentelemetry::metrics::UpD std::unique_ptr storage); void Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + void Add(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override; void Add(long value) noexcept override; + void Add(long value, const opentelemetry::context::Context &context) noexcept override; }; class DoubleUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter @@ -75,8 +87,12 @@ class DoubleUpDownCounter : public Synchronous, public opentelemetry::metrics::U void Add(double value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + void Add(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override; void Add(double value) noexcept override; + void Add(double value, const opentelemetry::context::Context &context) noexcept override; }; class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogram @@ -86,9 +102,10 @@ class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogr std::unique_ptr storage); void Record(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override; - void Record(long value) noexcept override; + void Record(long value, const opentelemetry::context::Context &context) noexcept override; }; class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histogram @@ -98,9 +115,10 @@ class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histo std::unique_ptr storage); void Record(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override; - void Record(double value) noexcept override; + void Record(double value, const opentelemetry::context::Context &context) noexcept override; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index d82607357f..fdc4e35c53 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -23,8 +23,6 @@ class AttributesProcessor // @returns The processed attributes virtual MetricAttributes process( const opentelemetry::common::KeyValueIterable &attributes) const noexcept = 0; - - virtual ~AttributesProcessor() = default; }; /** diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index 360630e786..20e3b02768 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -6,6 +6,7 @@ # include "opentelemetry/metrics/noop.h" # include "opentelemetry/nostd/shared_ptr.h" # include "opentelemetry/sdk/metrics/async_instruments.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" # include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" # include "opentelemetry/sdk/metrics/sync_instruments.h" @@ -192,7 +193,8 @@ std::unique_ptr Meter::RegisterMetricStorage( view_instr_desc.name_ = view.GetName(); view_instr_desc.description_ = view.GetDescription(); auto storage = std::shared_ptr(new SyncMetricStorage( - view_instr_desc, view.GetAggregationType(), &view.GetAttributesProcessor())); + view_instr_desc, view.GetAggregationType(), &view.GetAttributesProcessor(), + NoExemplarReservoir::GetNoExemplarReservoir())); storage_registry_[instrument_descriptor.name_] = storage; auto multi_storage = static_cast(storages.get()); multi_storage->AddStorage(storage); diff --git a/sdk/src/metrics/sync_instruments.cc b/sdk/src/metrics/sync_instruments.cc index 863e5b6323..5c94ae6f24 100644 --- a/sdk/src/metrics/sync_instruments.cc +++ b/sdk/src/metrics/sync_instruments.cc @@ -18,12 +18,26 @@ LongCounter::LongCounter(InstrumentDescriptor instrument_descriptor, void LongCounter::Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { - return storage_->RecordLong(value, attributes); + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, attributes, context); +} + +void LongCounter::Add(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordLong(value, attributes, context); } void LongCounter::Add(long value) noexcept { - return storage_->RecordLong(value); + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, context); +} + +void LongCounter::Add(long value, const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordLong(value, context); } DoubleCounter::DoubleCounter(InstrumentDescriptor instrument_descriptor, @@ -34,12 +48,26 @@ DoubleCounter::DoubleCounter(InstrumentDescriptor instrument_descriptor, void DoubleCounter::Add(double value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { - return storage_->RecordDouble(value, attributes); + auto context = opentelemetry::context::Context{}; + return storage_->RecordDouble(value, attributes, context); +} + +void DoubleCounter::Add(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordDouble(value, attributes, context); } void DoubleCounter::Add(double value) noexcept { - return storage_->RecordDouble(value); + auto context = opentelemetry::context::Context{}; + return storage_->RecordDouble(value, context); +} + +void DoubleCounter::Add(double value, const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordDouble(value, context); } LongUpDownCounter::LongUpDownCounter(InstrumentDescriptor instrument_descriptor, @@ -50,12 +78,26 @@ LongUpDownCounter::LongUpDownCounter(InstrumentDescriptor instrument_descriptor, void LongUpDownCounter::Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { - return storage_->RecordLong(value, attributes); + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, attributes, context); +} + +void LongUpDownCounter::Add(long value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordLong(value, attributes, context); } void LongUpDownCounter::Add(long value) noexcept { - return storage_->RecordLong(value); + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, context); +} + +void LongUpDownCounter::Add(long value, const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordLong(value, context); } DoubleUpDownCounter::DoubleUpDownCounter(InstrumentDescriptor instrument_descriptor, @@ -66,12 +108,26 @@ DoubleUpDownCounter::DoubleUpDownCounter(InstrumentDescriptor instrument_descrip void DoubleUpDownCounter::Add(double value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { - return storage_->RecordDouble(value, attributes); + auto context = opentelemetry::context::Context{}; + return storage_->RecordDouble(value, attributes, context); +} + +void DoubleUpDownCounter::Add(double value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordDouble(value, attributes, context); } void DoubleUpDownCounter::Add(double value) noexcept { - return storage_->RecordDouble(value); + auto context = opentelemetry::context::Context{}; + return storage_->RecordDouble(value, context); +} + +void DoubleUpDownCounter::Add(double value, const opentelemetry::context::Context &context) noexcept +{ + return storage_->RecordDouble(value, context); } LongHistogram::LongHistogram(InstrumentDescriptor instrument_descriptor, @@ -80,14 +136,15 @@ LongHistogram::LongHistogram(InstrumentDescriptor instrument_descriptor, {} void LongHistogram::Record(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept { - return storage_->RecordLong(value, attributes); + return storage_->RecordLong(value, attributes, context); } -void LongHistogram::Record(long value) noexcept +void LongHistogram::Record(long value, const opentelemetry::context::Context &context) noexcept { - return storage_->RecordLong(value); + return storage_->RecordLong(value, context); } DoubleHistogram::DoubleHistogram(InstrumentDescriptor instrument_descriptor, @@ -96,14 +153,15 @@ DoubleHistogram::DoubleHistogram(InstrumentDescriptor instrument_descriptor, {} void DoubleHistogram::Record(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept { - return storage_->RecordDouble(value, attributes); + return storage_->RecordDouble(value, attributes, context); } -void DoubleHistogram::Record(double value) noexcept +void DoubleHistogram::Record(double value, const opentelemetry::context::Context &context) noexcept { - return storage_->RecordDouble(value); + return storage_->RecordDouble(value, context); } } // namespace metrics diff --git a/sdk/test/metrics/BUILD b/sdk/test/metrics/BUILD index 9ca191574f..819a8d225f 100644 --- a/sdk/test/metrics/BUILD +++ b/sdk/test/metrics/BUILD @@ -80,6 +80,22 @@ cc_test( ], ) +cc_test( + name = "sync_instruments_test", + srcs = [ + "sync_instruments_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "async_metric_storage_test", srcs = [ diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index 3ee2be6552..fa1f22c73a 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -29,3 +29,5 @@ target_link_libraries(attributes_processor_benchmark benchmark::benchmark add_executable(attributes_hashmap_benchmark attributes_hashmap_benchmark.cc) target_link_libraries(attributes_hashmap_benchmark benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) + +add_subdirectory(exemplar) diff --git a/sdk/test/metrics/exemplar/BUILD b/sdk/test/metrics/exemplar/BUILD new file mode 100644 index 0000000000..6481f679d2 --- /dev/null +++ b/sdk/test/metrics/exemplar/BUILD @@ -0,0 +1,47 @@ +cc_test( + name = "no_exemplar_reservoir_test", + srcs = [ + "no_exemplar_reservoir_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "never_sample_filter_test", + srcs = [ + "never_sample_filter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "always_sample_filter_test", + srcs = [ + "always_sample_filter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/sdk/test/metrics/exemplar/CMakeLists.txt b/sdk/test/metrics/exemplar/CMakeLists.txt new file mode 100644 index 0000000000..303294761a --- /dev/null +++ b/sdk/test/metrics/exemplar/CMakeLists.txt @@ -0,0 +1,10 @@ +foreach(testname no_exemplar_reservoir_test never_sample_filter_test + always_sample_filter_test) + add_executable(${testname} "${testname}.cc") + target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) +endforeach() diff --git a/sdk/test/metrics/exemplar/always_sample_filter_test.cc b/sdk/test/metrics/exemplar/always_sample_filter_test.cc new file mode 100644 index 0000000000..cf4e449957 --- /dev/null +++ b/sdk/test/metrics/exemplar/always_sample_filter_test.cc @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/always_sample_filter.h" +# include + +using namespace opentelemetry::sdk::metrics; + +TEST(AlwaysSampleFilter, SampleMeasurement) +{ + auto filter = opentelemetry::sdk::metrics::AlwaysSampleFilter::GetAlwaysSampleFilter(); + ASSERT_TRUE( + filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_TRUE( + filter->ShouldSampleMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{})); +} + +#endif diff --git a/sdk/test/metrics/exemplar/never_sample_filter_test.cc b/sdk/test/metrics/exemplar/never_sample_filter_test.cc new file mode 100644 index 0000000000..930c572205 --- /dev/null +++ b/sdk/test/metrics/exemplar/never_sample_filter_test.cc @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "opentelemetry/context/context.h" +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/sdk/metrics/exemplar/never_sample_filter.h" + +using namespace opentelemetry::sdk::metrics; + +TEST(NeverSampleFilter, SampleMeasurement) +{ + auto filter = opentelemetry::sdk::metrics::NeverSampleFilter::GetNeverSampleFilter(); + ASSERT_FALSE( + filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_FALSE( + filter->ShouldSampleMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{})); +} + +#endif diff --git a/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc b/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc new file mode 100644 index 0000000000..3e16940ff4 --- /dev/null +++ b/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include + +using namespace opentelemetry::sdk::metrics; + +TEST(NoExemplarReservoir, OfferMeasurement) +{ + auto reservoir = opentelemetry::sdk::metrics::NoExemplarReservoir::GetNoExemplarReservoir(); + EXPECT_NO_THROW(reservoir->OfferMeasurement(1.0, MetricAttributes{}, + opentelemetry::context::Context{}, + std::chrono::system_clock::now())); + EXPECT_NO_THROW(reservoir->OfferMeasurement( + 1l, MetricAttributes{}, opentelemetry::context::Context{}, std::chrono::system_clock::now())); + auto exemplar_data = reservoir->CollectAndReset(MetricAttributes{}); + ASSERT_TRUE(exemplar_data.empty()); +} + +#endif diff --git a/sdk/test/metrics/multi_metric_storage_test.cc b/sdk/test/metrics/multi_metric_storage_test.cc index 6696c7bb0a..d88946485c 100644 --- a/sdk/test/metrics/multi_metric_storage_test.cc +++ b/sdk/test/metrics/multi_metric_storage_test.cc @@ -4,6 +4,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" # include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/instruments.h" # include @@ -15,18 +16,26 @@ using namespace opentelemetry::sdk::metrics; class TestMetricStorage : public WritableMetricStorage { public: - void RecordLong(long value) noexcept override { num_calls_long++; } + void RecordLong(long value, const opentelemetry::context::Context &context) noexcept override + { + num_calls_long++; + } void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { num_calls_long++; } - void RecordDouble(double value) noexcept override { num_calls_double++; } + void RecordDouble(double value, const opentelemetry::context::Context &context) noexcept override + { + num_calls_double++; + } void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept override { num_calls_double++; } @@ -39,13 +48,13 @@ TEST(MultiMetricStorageTest, BasicTests) { std::shared_ptr storage( new TestMetricStorage()); - MultiMetricStorage storages; + MultiMetricStorage storages{}; storages.AddStorage(storage); - EXPECT_NO_THROW(storages.RecordLong(10l)); - EXPECT_NO_THROW(storages.RecordLong(20l)); + EXPECT_NO_THROW(storages.RecordLong(10l, opentelemetry::context::Context{})); + EXPECT_NO_THROW(storages.RecordLong(20l, opentelemetry::context::Context{})); - EXPECT_NO_THROW(storages.RecordDouble(10.0)); - EXPECT_NO_THROW(storages.RecordLong(30l)); + EXPECT_NO_THROW(storages.RecordDouble(10.0, opentelemetry::context::Context{})); + EXPECT_NO_THROW(storages.RecordLong(30l, opentelemetry::context::Context{})); EXPECT_EQ(static_cast(storage.get())->num_calls_long, 3); EXPECT_EQ(static_cast(storage.get())->num_calls_double, 1); diff --git a/sdk/test/metrics/sync_instruments_test.cc b/sdk/test/metrics/sync_instruments_test.cc index 27af8711d1..e029821d41 100644 --- a/sdk/test/metrics/sync_instruments_test.cc +++ b/sdk/test/metrics/sync_instruments_test.cc @@ -3,7 +3,9 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/sync_instruments.h" +# include "opentelemetry/context/context.h" # include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" # include @@ -23,11 +25,16 @@ TEST(SyncInstruments, LongCounter) std::unique_ptr metric_storage(new MultiMetricStorage()); LongCounter counter(instrument_descriptor, std::move(metric_storage)); EXPECT_NO_THROW(counter.Add(10l)); - EXPECT_NO_THROW(counter.Add(10l)); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add( 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add( + 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView({}))); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); } TEST(SyncInstruments, DoubleCounter) @@ -37,11 +44,16 @@ TEST(SyncInstruments, DoubleCounter) std::unique_ptr metric_storage(new MultiMetricStorage()); DoubleCounter counter(instrument_descriptor, std::move(metric_storage)); EXPECT_NO_THROW(counter.Add(10.10)); - EXPECT_NO_THROW(counter.Add(10.10)); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add( 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add( + 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView({}))); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); } TEST(SyncInstruments, LongUpDownCounter) @@ -52,11 +64,16 @@ TEST(SyncInstruments, LongUpDownCounter) std::unique_ptr metric_storage(new MultiMetricStorage()); LongUpDownCounter counter(instrument_descriptor, std::move(metric_storage)); EXPECT_NO_THROW(counter.Add(10l)); - EXPECT_NO_THROW(counter.Add(10l)); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add( 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add( + 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView({}))); + EXPECT_NO_THROW(counter.Add(10l, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); } TEST(SyncInstruments, DoubleUpDownCounter) @@ -67,10 +84,15 @@ TEST(SyncInstruments, DoubleUpDownCounter) std::unique_ptr metric_storage(new MultiMetricStorage()); DoubleUpDownCounter counter(instrument_descriptor, std::move(metric_storage)); EXPECT_NO_THROW(counter.Add(10.10)); - EXPECT_NO_THROW(counter.Add(10.10)); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Add( + 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add( 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); + EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Add(10.10, opentelemetry::common::KeyValueIterableView({}))); } @@ -80,12 +102,14 @@ TEST(SyncInstruments, LongHistogram) "long_histogram", "description", "1", InstrumentType::kHistogram, InstrumentValueType::kLong}; std::unique_ptr metric_storage(new MultiMetricStorage()); LongHistogram counter(instrument_descriptor, std::move(metric_storage)); - EXPECT_NO_THROW(counter.Record(10l)); - EXPECT_NO_THROW(counter.Record(10l)); + EXPECT_NO_THROW(counter.Record(10l, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(10l, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Record( - 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); - EXPECT_NO_THROW(counter.Record(10l, opentelemetry::common::KeyValueIterableView({}))); + 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(10l, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); } TEST(SyncInstruments, DoubleHistogram) @@ -95,12 +119,14 @@ TEST(SyncInstruments, DoubleHistogram) InstrumentValueType::kDouble}; std::unique_ptr metric_storage(new MultiMetricStorage()); DoubleHistogram counter(instrument_descriptor, std::move(metric_storage)); - EXPECT_NO_THROW(counter.Record(10.10)); - EXPECT_NO_THROW(counter.Record(10.10)); + EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::context::Context{})); EXPECT_NO_THROW(counter.Record( - 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); - EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::common::KeyValueIterableView({}))); + 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); } #endif \ No newline at end of file diff --git a/sdk/test/metrics/sync_metric_storage_test.cc b/sdk/test/metrics/sync_metric_storage_test.cc index 23ef20b11d..c4bd154460 100644 --- a/sdk/test/metrics/sync_metric_storage_test.cc +++ b/sdk/test/metrics/sync_metric_storage_test.cc @@ -4,6 +4,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" # include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" @@ -18,13 +19,16 @@ TEST(WritableMetricStorageTest, BasicTests) InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, InstrumentValueType::kLong}; - opentelemetry::sdk::metrics::SyncMetricStorage storage(instr_desc, AggregationType::kSum, - new DefaultAttributesProcessor()); - EXPECT_NO_THROW(storage.RecordLong(10l)); - EXPECT_NO_THROW(storage.RecordDouble(10.10)); + opentelemetry::sdk::metrics::SyncMetricStorage storage( + instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), + NoExemplarReservoir::GetNoExemplarReservoir()); + EXPECT_NO_THROW(storage.RecordLong(10l, opentelemetry::context::Context{})); + EXPECT_NO_THROW(storage.RecordDouble(10.10, opentelemetry::context::Context{})); EXPECT_NO_THROW(storage.RecordLong( - 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}))); + 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + opentelemetry::context::Context{})); - EXPECT_NO_THROW(storage.RecordDouble(10.10, opentelemetry::common::KeyValueIterableView({}))); + EXPECT_NO_THROW(storage.RecordDouble(10.10, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{})); } #endif From 2c9ce393e0582a4e0559a73bd9a572cf324b7086 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 24 Mar 2022 16:47:49 -0700 Subject: [PATCH 06/69] [Metrics SDK] - fix spelling (AggregationTemporarily to AggregationTemporality) (#1288) --- exporters/ostream/test/ostream_metric_test.cc | 4 +- .../sdk/metrics/aggregation/sum_aggregation.h | 2 +- .../sdk/metrics/data/point_data.h | 2 +- .../opentelemetry/sdk/metrics/instruments.h | 2 +- .../sdk/metrics/measurement_processor.h | 124 ------------------ .../sdk/metrics/metric_exporter.h | 2 +- .../opentelemetry/sdk/metrics/metric_reader.h | 6 +- .../sdk/metrics/state/metric_collector.h | 4 +- sdk/src/metrics/metric_reader.cc | 8 +- sdk/src/metrics/state/metric_collector.cc | 4 +- sdk/test/metrics/async_metric_storage_test.cc | 4 +- sdk/test/metrics/metric_reader_test.cc | 10 +- 12 files changed, 24 insertions(+), 148 deletions(-) delete mode 100644 sdk/include/opentelemetry/sdk/metrics/measurement_processor.h diff --git a/exporters/ostream/test/ostream_metric_test.cc b/exporters/ostream/test/ostream_metric_test.cc index 51b9882c47..9e98dd4da4 100644 --- a/exporters/ostream/test/ostream_metric_test.cc +++ b/exporters/ostream/test/ostream_metric_test.cc @@ -35,11 +35,11 @@ TEST(OStreamMetricsExporter, ExportSumPointData) record->instrumentation_library_ = instrumentation_library.get(); record->point_data_ = metric_sdk::SumPointData{ opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, 10.0, - metric_sdk::AggregationTemporarily::kUnspecified, false}; + metric_sdk::AggregationTemporality::kUnspecified, false}; auto record2 = std::unique_ptr(new metric_sdk::MetricData(*record)); record2->point_data_ = metric_sdk::SumPointData{ opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, 20l, - metric_sdk::AggregationTemporarily::kUnspecified, false}; + metric_sdk::AggregationTemporality::kUnspecified, false}; std::vector> records; records.push_back(std::move(record)); records.push_back(std::move(record2)); diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h index c8b2eff33c..ff99cec733 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h @@ -25,7 +25,7 @@ static inline void PopulateSumPointData(SumPointData &sum, sum.end_epoch_nanos_ = end_ts; sum.value_ = value; sum.is_monotonic_ = is_monotonic; - sum.aggregation_temporarily_ = AggregationTemporarily::kDelta; + sum.aggregation_temporality_ = AggregationTemporality::kDelta; } class LongSumAggregation : public Aggregation, InstrumentMonotonicityAwareAggregation diff --git a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h index 603bcc30bc..5bbcbd0b1e 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h @@ -25,7 +25,7 @@ class SumPointData opentelemetry::common::SystemTimestamp start_epoch_nanos_; opentelemetry::common::SystemTimestamp end_epoch_nanos_; ValueType value_; - AggregationTemporarily aggregation_temporarily_; + AggregationTemporality aggregation_temporality_; bool is_monotonic_; }; diff --git a/sdk/include/opentelemetry/sdk/metrics/instruments.h b/sdk/include/opentelemetry/sdk/metrics/instruments.h index ad64ce718b..15e6a25705 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/instruments.h @@ -36,7 +36,7 @@ enum class AggregationType kDefault }; -enum class AggregationTemporarily +enum class AggregationTemporality { kUnspecified, kDelta, diff --git a/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h b/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h deleted file mode 100644 index f3b998451b..0000000000 --- a/sdk/include/opentelemetry/sdk/metrics/measurement_processor.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once -#include -#ifndef ENABLE_METRICS_PREVIEW - -# include -# include "opentelemetry/common/key_value_iterable_view.h" -# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" -# include "opentelemetry/sdk/metrics/instruments.h" -# include "opentelemetry/sdk/metrics/metric_reader.h" -# include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" -# include "opentelemetry/sdk/metrics/view/attributes_processor.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace metrics -{ - -static std::size_t MakeKey(const MetricReader &metric_reader) -{ - return reinterpret_cast(&metric_reader); -} - -class MeasurementProcessor -{ -public: - virtual void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0; - - virtual void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept = 0; - - virtual void RecordDouble(double value, - const opentelemetry::context::Context &context) noexcept = 0; - - virtual void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept = 0; - - virtual bool Collect(MetricReader &reader, - AggregationTemporarily aggregation_temporarily, - nostd::function_ref callback) noexcept = 0; -}; - -class DefaultMeasurementProcessor : public MeasurementProcessor -{ -public: - bool AddMetricStorage(const MetricReader &reader) - { - // TBD Check if already present - // pass intrumentation type, and aggregation type instead of hardcodig below. - InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, - InstrumentValueType::kLong}; - metric_storages_[MakeKey(reader)] = std::unique_ptr( - new SyncMetricStorage(instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), - NoExemplarReservoir::GetNoExemplarReservoir())); - return true; - } - - virtual void RecordLong(long value, - const opentelemetry::context::Context &context) noexcept override - { - for (const auto &kv : metric_storages_) - { - kv.second->RecordLong(value, context); - } - } - - virtual void RecordLong(long value, - const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept override - { - for (const auto &kv : metric_storages_) - { - kv.second->RecordLong(value, attributes, context); - } - } - - virtual void RecordDouble(double value, - const opentelemetry::context::Context &context) noexcept override - { - for (const auto &kv : metric_storages_) - { - kv.second->RecordDouble(value, context); - } - } - - virtual void RecordDouble(double value, - const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept override - { - for (const auto &kv : metric_storages_) - { - kv.second->RecordDouble(value, attributes, context); - } - } - - bool Collect(MetricReader &reader, - AggregationTemporarily aggregation_temporarily, - nostd::function_ref callback) noexcept override - { - auto i = metric_storages_.find(MakeKey(reader)); - - // TBD - Remove hardcodings below - std::vector collectors; - if (i != metric_storages_.end()) - { - - return i->second->Collect(nullptr, collectors, nullptr, nullptr, callback); - } - return false; - } - -private: - std::map> metric_storages_; -}; - -} // namespace metrics -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h index 96898c9ad1..3769259472 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h @@ -51,7 +51,7 @@ class MetricExporter std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept = 0; private: - AggregationTemporarily aggregation_temporarily; + AggregationTemporality aggregation_temporality_; }; } // namespace metrics } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h index fdd5d41291..1f7cee8d30 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h @@ -27,7 +27,7 @@ class MetricReader { public: MetricReader( - AggregationTemporarily aggregation_temporarily = AggregationTemporarily::kCummulative); + AggregationTemporality aggregation_temporality = AggregationTemporality::kCummulative); void SetMetricProducer(MetricProducer *metric_producer); @@ -37,7 +37,7 @@ class MetricReader */ bool Collect(nostd::function_ref callback) noexcept; - AggregationTemporarily GetAggregationTemporarily() const noexcept; + AggregationTemporality GetAggregationTemporality() const noexcept; /** * Shutdown the meter reader. @@ -62,7 +62,7 @@ class MetricReader private: MetricProducer *metric_producer_; - AggregationTemporarily aggregation_temporarily_; + AggregationTemporality aggregation_temporality_; mutable opentelemetry::common::SpinLockMutex lock_; bool shutdown_; }; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h index 3049440d9d..51c9cf6eff 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h @@ -18,7 +18,7 @@ class MeterContext; class CollectorHandle { public: - virtual AggregationTemporarily GetAggregationTemporarily() noexcept = 0; + virtual AggregationTemporality GetAggregationTemporality() noexcept = 0; }; /** @@ -33,7 +33,7 @@ class MetricCollector : public MetricProducer, public CollectorHandle MetricCollector(std::shared_ptr &&context, std::unique_ptr metric_reader); - AggregationTemporarily GetAggregationTemporarily() noexcept override; + AggregationTemporality GetAggregationTemporality() noexcept override; /** * The callback to be called for each metric exporter. This will only be those diff --git a/sdk/src/metrics/metric_reader.cc b/sdk/src/metrics/metric_reader.cc index 71aedc227f..8238ad2a55 100644 --- a/sdk/src/metrics/metric_reader.cc +++ b/sdk/src/metrics/metric_reader.cc @@ -13,8 +13,8 @@ namespace sdk namespace metrics { -MetricReader::MetricReader(AggregationTemporarily aggregation_temporarily) - : aggregation_temporarily_(aggregation_temporarily) +MetricReader::MetricReader(AggregationTemporality aggregation_temporality) + : aggregation_temporality_(aggregation_temporality) {} void MetricReader::SetMetricProducer(MetricProducer *metric_producer) @@ -22,9 +22,9 @@ void MetricReader::SetMetricProducer(MetricProducer *metric_producer) metric_producer_ = metric_producer; } -AggregationTemporarily MetricReader::GetAggregationTemporarily() const noexcept +AggregationTemporality MetricReader::GetAggregationTemporality() const noexcept { - return aggregation_temporarily_; + return aggregation_temporality_; } bool MetricReader::Collect(nostd::function_ref callback) noexcept diff --git a/sdk/src/metrics/state/metric_collector.cc b/sdk/src/metrics/state/metric_collector.cc index a52c6e9b1c..5b9fc4ab70 100644 --- a/sdk/src/metrics/state/metric_collector.cc +++ b/sdk/src/metrics/state/metric_collector.cc @@ -24,9 +24,9 @@ MetricCollector::MetricCollector( metric_reader_->SetMetricProducer(this); } -AggregationTemporarily MetricCollector::GetAggregationTemporarily() noexcept +AggregationTemporality MetricCollector::GetAggregationTemporality() noexcept { - return metric_reader_->GetAggregationTemporarily(); + return metric_reader_->GetAggregationTemporality(); } bool MetricCollector::Collect(nostd::function_ref callback) noexcept diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index fd7d24c6f3..0527c7f0ca 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -21,7 +21,7 @@ using namespace opentelemetry::sdk::resource; class MockMetricReader : public MetricReader { public: - MockMetricReader(AggregationTemporarily aggr_temporarily) : MetricReader(aggr_temporarily) {} + MockMetricReader(AggregationTemporality aggr_temporality) : MetricReader(aggr_temporality) {} virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } @@ -44,7 +44,7 @@ TEST(AsyncMetricStorageTest, BasicTests) std::vector> exporters; std::shared_ptr meter_context(new MeterContext(std::move(exporters))); - std::unique_ptr metric_reader(new MockMetricReader(AggregationTemporarily::kDelta)); + std::unique_ptr metric_reader(new MockMetricReader(AggregationTemporality::kDelta)); std::shared_ptr collector = std::shared_ptr( new MetricCollector(std::move(meter_context), std::move(metric_reader))); diff --git a/sdk/test/metrics/metric_reader_test.cc b/sdk/test/metrics/metric_reader_test.cc index d0f7c14981..214f522118 100644 --- a/sdk/test/metrics/metric_reader_test.cc +++ b/sdk/test/metrics/metric_reader_test.cc @@ -14,7 +14,7 @@ using namespace opentelemetry::sdk::metrics; class MockMetricReader : public MetricReader { public: - MockMetricReader(AggregationTemporarily aggr_temporarily) : MetricReader(aggr_temporarily) {} + MockMetricReader(AggregationTemporality aggr_temporality) : MetricReader(aggr_temporality) {} virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } @@ -25,15 +25,15 @@ class MockMetricReader : public MetricReader TEST(MetricReaderTest, BasicTests) { - AggregationTemporarily aggr_temporarily = AggregationTemporarily::kDelta; - std::unique_ptr metric_reader1(new MockMetricReader(aggr_temporarily)); - EXPECT_EQ(metric_reader1->GetAggregationTemporarily(), aggr_temporarily); + AggregationTemporality aggr_temporality = AggregationTemporality::kDelta; + std::unique_ptr metric_reader1(new MockMetricReader(aggr_temporality)); + EXPECT_EQ(metric_reader1->GetAggregationTemporality(), aggr_temporality); std::vector> exporters; std::shared_ptr meter_context1(new MeterContext(std::move(exporters))); EXPECT_NO_THROW(meter_context1->AddMetricReader(std::move(metric_reader1))); - std::unique_ptr metric_reader2(new MockMetricReader(aggr_temporarily)); + std::unique_ptr metric_reader2(new MockMetricReader(aggr_temporality)); std::shared_ptr meter_context2(new MeterContext(std::move(exporters))); MetricProducer *metric_producer = new MetricCollector(std::move(meter_context2), std::move(metric_reader2)); From 91b05720ef38bcd065e1ebb8c9c857764d8d0e3b Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Fri, 25 Mar 2022 17:40:21 +0100 Subject: [PATCH 07/69] fix compilation error with protobuf 3.5 (#1289) --- docker/Dockerfile.centos | 14 ++++++++------ .../exporters/otlp/otlp_environment.h | 2 +- exporters/otlp/src/otlp_http_client.cc | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docker/Dockerfile.centos b/docker/Dockerfile.centos index 66ca8f24b3..66138ba60a 100644 --- a/docker/Dockerfile.centos +++ b/docker/Dockerfile.centos @@ -1,13 +1,15 @@ FROM centos:7 +ARG TOOLSET_VER=11 + RUN yum update -y && yum install -y centos-release-scl epel-release -RUN yum install -y devtoolset-11 \ +RUN yum install -y devtoolset-${TOOLSET_VER} \ cmake3 git \ openssl-devel \ libcurl-devel \ - && source /opt/rh/devtoolset-11/enable + && source /opt/rh/devtoolset-${TOOLSET_VER}/enable -RUN echo "source /opt/rh/devtoolset-11/enable" >> /etc/bashrc +RUN echo "source /opt/rh/devtoolset-${TOOLSET_VER}/enable" >> /etc/bashrc RUN echo "BOOST_LIBRARYDIR=/usr/lib64/boost169" >> /etc/bashrc RUN echo "BOOST_INCLUDEDIR=/usr/include/boost169" >> /etc/bashrc @@ -17,7 +19,7 @@ ARG GRPC_VERSION=v1.43.2 RUN git clone --depth=1 -b $GRPC_VERSION https://github.com/grpc/grpc.git \ && cd grpc && git submodule update --init \ && mkdir -p "third_party/abseil-cpp/build" && cd "third_party/abseil-cpp/build" \ - && source /opt/rh/devtoolset-11/enable \ + && source /opt/rh/devtoolset-${TOOLSET_VER}/enable \ && cmake3 -DCMAKE_CXX_STANDARD=17 -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE .. \ && make -j${nproc} install && cd ../../.. \ && mkdir build && cd build \ @@ -40,7 +42,7 @@ RUN yum install -y \ && wget https://github.com/apache/thrift/archive/refs/tags/v$THRIFT_VERSION.tar.gz \ && tar -xvf v$THRIFT_VERSION.tar.gz \ && mkdir -p thrift-$THRIFT_VERSION/build && cd thrift-$THRIFT_VERSION/build \ - && source /opt/rh/devtoolset-11/enable \ + && source /opt/rh/devtoolset-${TOOLSET_VER}/enable \ && export BOOST_INCLUDEDIR=/usr/include/boost169 \ && export BOOST_LIBRARYDIR=/usr/lib64/boost169 \ && cmake3 \ @@ -66,7 +68,7 @@ RUN yum install -y \ RUN git clone --depth=1 https://github.com/open-telemetry/opentelemetry-cpp.git \ && cd opentelemetry-cpp && git submodule update --init \ && mkdir -p build && cd build \ - && source /opt/rh/devtoolset-11/enable \ + && source /opt/rh/devtoolset-${TOOLSET_VER}/enable \ && export BOOST_INCLUDEDIR=/usr/include/boost169 \ && export BOOST_LIBRARYDIR=/usr/lib64/boost169 \ && cmake3 \ diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h index c60de87eb9..bf7ea6a61c 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h @@ -53,7 +53,7 @@ inline const std::string GetOtlpDefaultHttpEndpoint() return endpoint.size() ? endpoint : kOtlpEndpointDefault; } -inline const bool GetOtlpDefaultIsSslEnable() +inline bool GetOtlpDefaultIsSslEnable() { constexpr char kOtlpTracesIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_TRACES_SSL_ENABLE"; constexpr char kOtlpIsSslEnableEnv[] = "OTEL_EXPORTER_OTLP_SSL_ENABLE"; diff --git a/exporters/otlp/src/otlp_http_client.cc b/exporters/otlp/src/otlp_http_client.cc index 544f74ca7c..e3e1a8c467 100644 --- a/exporters/otlp/src/otlp_http_client.cc +++ b/exporters/otlp/src/otlp_http_client.cc @@ -18,6 +18,7 @@ #include "google/protobuf/message.h" #include "google/protobuf/reflection.h" #include "google/protobuf/stubs/common.h" +#include "google/protobuf/stubs/stringpiece.h" #include "nlohmann/json.hpp" #if defined(GOOGLE_PROTOBUF_VERSION) && GOOGLE_PROTOBUF_VERSION >= 3007000 From c1b959079bd6ae03183f54f246017aa1be5c706b Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Sat, 26 Mar 2022 09:25:42 +0100 Subject: [PATCH 08/69] Fix span SetAttribute crash (#1283) --- CHANGELOG.md | 1 + sdk/src/trace/span.cc | 4 ++++ sdk/test/trace/tracer_test.cc | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f66ec617a..bd41c75626 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Increment the: ## [Unreleased] +* [SDK] Bugfix: span SetAttribute crash ([#1283](https://github.com/open-telemetry/opentelemetry-cpp/pull/1283)) * [EXPORTER] Jaeger Exporter - Populate Span Links ([#1251](https://github.com/open-telemetry/opentelemetry-cpp/pull/1251)) ## [1.2.0] 2022-01-31 diff --git a/sdk/src/trace/span.cc b/sdk/src/trace/span.cc index dff84a22b7..13ea99126c 100644 --- a/sdk/src/trace/span.cc +++ b/sdk/src/trace/span.cc @@ -94,6 +94,10 @@ Span::~Span() void Span::SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept { std::lock_guard lock_guard{mu_}; + if (recordable_ == nullptr) + { + return; + } recordable_->SetAttribute(key, value); } diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index 9d1029cd02..dc806b079f 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -383,6 +383,34 @@ TEST(Tracer, SpanSetAttribute) ASSERT_EQ(3.1, nostd::get(cur_span_data->GetAttributes().at("abc"))); } +TEST(Tracer, TestAfterEnd) +{ + std::unique_ptr exporter(new InMemorySpanExporter()); + std::shared_ptr span_data = exporter->GetData(); + auto tracer = initTracer(std::move(exporter)); + auto span = tracer->StartSpan("span 1"); + span->SetAttribute("abc", 3.1); + + span->End(); + + // test after end + span->SetAttribute("testing null recordable", 3.1); + span->AddEvent("event 1"); + span->AddEvent("event 2", std::chrono::system_clock::now()); + span->AddEvent("event 3", std::chrono::system_clock::now(), {{"attr1", 1}}); + std::string new_name{"new name"}; + span->UpdateName(new_name); + span->SetAttribute("attr1", 3.1); + std::string description{"description"}; + span->SetStatus(opentelemetry::trace::StatusCode::kError, description); + span->End(); + + auto spans = span_data->GetSpans(); + ASSERT_EQ(1, spans.size()); + auto &cur_span_data = spans.at(0); + ASSERT_EQ(3.1, nostd::get(cur_span_data->GetAttributes().at("abc"))); +} + TEST(Tracer, SpanSetEvents) { std::unique_ptr exporter(new InMemorySpanExporter()); From a7e814a632fdaee0c76246358ffad811ac06a7e9 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 29 Mar 2022 18:01:37 -0700 Subject: [PATCH 09/69] Synchronous Metric collection (Delta , Cumulative) (#1265) --- exporters/ostream/BUILD | 57 +++-- .../sdk/metrics/aggregation/aggregation.h | 40 +++- .../metrics/aggregation/default_aggregation.h | 8 +- .../metrics/aggregation/drop_aggregation.h | 20 +- .../aggregation/histogram_aggregation.h | 40 ++-- .../aggregation/lastvalue_aggregation.h | 22 +- .../sdk/metrics/aggregation/sum_aggregation.h | 44 ++-- .../sdk/metrics/data/metric_data.h | 15 +- .../sdk/metrics/data/point_data.h | 56 +++-- .../opentelemetry/sdk/metrics/instruments.h | 2 +- sdk/include/opentelemetry/sdk/metrics/meter.h | 2 +- .../opentelemetry/sdk/metrics/meter_context.h | 1 - .../opentelemetry/sdk/metrics/metric_reader.h | 3 +- .../sdk/metrics/state/async_metric_storage.h | 3 +- .../sdk/metrics/state/attributes_hashmap.h | 19 +- .../sdk/metrics/state/sync_metric_storage.h | 28 ++- sdk/src/metrics/CMakeLists.txt | 1 + .../aggregation/histogram_aggregation.cc | 95 +++++--- .../aggregation/lastvalue_aggregation.cc | 103 ++++++-- .../metrics/aggregation/sum_aggregation.cc | 102 +++++--- sdk/src/metrics/meter.cc | 2 +- sdk/src/metrics/state/metric_collector.cc | 2 +- sdk/src/metrics/state/sync_metric_storage.cc | 131 ++++++++++ sdk/test/metrics/aggregation_test.cc | 38 ++- sdk/test/metrics/async_metric_storage_test.cc | 8 +- sdk/test/metrics/meter_provider_sdk_test.cc | 2 - sdk/test/metrics/metric_reader_test.cc | 2 - sdk/test/metrics/sync_metric_storage_test.cc | 226 +++++++++++++++++- 28 files changed, 804 insertions(+), 268 deletions(-) create mode 100644 sdk/src/metrics/state/sync_metric_storage.cc diff --git a/exporters/ostream/BUILD b/exporters/ostream/BUILD index cca74d6693..19c0f7914d 100644 --- a/exporters/ostream/BUILD +++ b/exporters/ostream/BUILD @@ -43,36 +43,35 @@ cc_library( ], ) -cc_library( - name = "ostream_metric_exporter", - srcs = [ - "src/metric_exporter.cc", - ], - hdrs = [ - "include/opentelemetry/exporters/ostream/metric_exporter.h", - ], - strip_include_prefix = "include", - tags = [ - "metrics", - "ostream", - ], - deps = [ - "//sdk/src/metrics", - ], -) +#TODO MetricData is still changing, uncomment once it is final +# srcs = [ +# "src/metric_exporter.cc", +# ], +# hdrs = [ +# "include/opentelemetry/exporters/ostream/metric_exporter.h", +# ], +# strip_include_prefix = "include", +# tags = [ +# "metrics", +# "ostream", +# ], +# deps = [ +# "//sdk/src/metrics", +# ], +#) -cc_test( - name = "ostream_metric_test", - srcs = ["test/ostream_metric_test.cc"], - tags = [ - "ostream", - "test", - ], - deps = [ - ":ostream_metric_exporter", - "@com_google_googletest//:gtest_main", - ], -) +#cc_test( +# name = "ostream_metric_test", +# srcs = ["test/ostream_metric_test.cc"], +# tags = [ +# "ostream", +# "test", +# ], +# deps = [ +# ":ostream_metric_exporter", +# "@com_google_googletest//:gtest_main", +#], +#) cc_test( name = "ostream_metrics_test_deprecated", diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h index 3bb133ac15..7ec9a6ea2b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h @@ -11,16 +11,6 @@ namespace sdk { namespace metrics { -class InstrumentMonotonicityAwareAggregation -{ -public: - InstrumentMonotonicityAwareAggregation(bool is_monotonic) : is_monotonic_(is_monotonic) {} - bool IsMonotonic() { return is_monotonic_; } - -private: - bool is_monotonic_; -}; - class Aggregation { public: @@ -28,7 +18,35 @@ class Aggregation virtual void Aggregate(double value, const PointAttributes &attributes = {}) noexcept = 0; - virtual PointType Collect() noexcept = 0; + /** + * Returns the result of the merge of the two aggregations. + * + * This should always assume that the aggregations do not overlap and merge together for a new + * cumulative report. + * + * @param delta the newly captured (delta) aggregation + * @return the result of the merge of the given aggregation. + */ + + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept = 0; + + /** + * Returns a new delta aggregation by comparing two cumulative measurements. + * + * @param next the newly captured (cumulative) aggregation. + * @return The resulting delta aggregation. + */ + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept = 0; + + /** + * Returns the point data that the aggregation will produce. + * + * @return PointType + */ + + virtual PointType ToPoint() const noexcept = 0; + + virtual ~Aggregation() = default; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h index f193864926..b5a1283d26 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h @@ -30,8 +30,8 @@ class DefaultAggregation case InstrumentType::kUpDownCounter: case InstrumentType::kObservableUpDownCounter: return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) - ? std::move(std::unique_ptr(new LongSumAggregation(true))) - : std::move(std::unique_ptr(new DoubleSumAggregation(true))); + ? std::move(std::unique_ptr(new LongSumAggregation())) + : std::move(std::unique_ptr(new DoubleSumAggregation())); break; case InstrumentType::kHistogram: return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) @@ -79,11 +79,11 @@ class DefaultAggregation case AggregationType::kSum: if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) { - return std::unique_ptr(new LongSumAggregation(true)); + return std::unique_ptr(new LongSumAggregation()); } else { - return std::unique_ptr(new DoubleSumAggregation(true)); + return std::unique_ptr(new DoubleSumAggregation()); } break; default: diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h index 0af5dd43a5..4e29fa2e46 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h @@ -14,6 +14,10 @@ namespace sdk namespace metrics { +/** + * A null Aggregation which denotes no aggregation should occur. + */ + class DropAggregation : public Aggregation { public: @@ -23,7 +27,21 @@ class DropAggregation : public Aggregation void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - PointType Collect() noexcept override { return DropPointData(); } + std::unique_ptr Merge(const Aggregation &delta) const noexcept override + { + return std::unique_ptr(new DropAggregation()); + } + + std::unique_ptr Diff(const Aggregation &next) const noexcept override + { + return std::unique_ptr(new DropAggregation()); + } + + PointType ToPoint() const noexcept override + { + static DropPointData point_data; + return point_data; + } }; } // namespace metrics } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h index 5a66ecb243..8f33fa27b4 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h @@ -13,57 +13,47 @@ namespace sdk { namespace metrics { -template -static inline void PopulateHistogramDataPoint(HistogramPointData &histogram, - opentelemetry::common::SystemTimestamp epoch_nanos, - T sum, - uint64_t count, - std::vector &counts, - std::vector boundaries) -{ - histogram.epoch_nanos_ = epoch_nanos; - histogram.boundaries_ = boundaries; - histogram.sum_ = sum; - histogram.counts_ = counts; - histogram.count_ = count; -} class LongHistogramAggregation : public Aggregation { public: LongHistogramAggregation(); + LongHistogramAggregation(HistogramPointData &&); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - PointType Collect() noexcept override; + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + + PointType ToPoint() const noexcept override; private: opentelemetry::common::SpinLockMutex lock_; - std::vector boundaries_; - long sum_; - std::vector counts_; - uint64_t count_; + HistogramPointData point_data_; }; class DoubleHistogramAggregation : public Aggregation { public: DoubleHistogramAggregation(); + DoubleHistogramAggregation(HistogramPointData &&); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; - PointType Collect() noexcept override; + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + + PointType ToPoint() const noexcept override; private: - opentelemetry::common::SpinLockMutex lock_; - std::vector boundaries_; - double sum_; - std::vector counts_; - uint64_t count_; + mutable opentelemetry::common::SpinLockMutex lock_; + mutable HistogramPointData point_data_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h index 092a0df30e..7f185d51a1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h @@ -17,34 +17,42 @@ class LongLastValueAggregation : public Aggregation { public: LongLastValueAggregation(); + LongLastValueAggregation(LastValuePointData &&); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - PointType Collect() noexcept override; + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + + PointType ToPoint() const noexcept override; private: opentelemetry::common::SpinLockMutex lock_; - long value_; - bool is_lastvalue_valid_; + LastValuePointData point_data_; }; class DoubleLastValueAggregation : public Aggregation { public: DoubleLastValueAggregation(); + DoubleLastValueAggregation(LastValuePointData &&); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; - PointType Collect() noexcept override; + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + + PointType ToPoint() const noexcept override; private: - opentelemetry::common::SpinLockMutex lock_; - double value_; - bool is_lastvalue_valid_; + mutable opentelemetry::common::SpinLockMutex lock_; + mutable LastValuePointData point_data_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h index ff99cec733..b0f0169b24 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h @@ -14,52 +14,46 @@ namespace sdk namespace metrics { -template -static inline void PopulateSumPointData(SumPointData &sum, - opentelemetry::common::SystemTimestamp start_ts, - opentelemetry::common::SystemTimestamp end_ts, - T value, - bool is_monotonic) -{ - sum.start_epoch_nanos_ = start_ts; - sum.end_epoch_nanos_ = end_ts; - sum.value_ = value; - sum.is_monotonic_ = is_monotonic; - sum.aggregation_temporality_ = AggregationTemporality::kDelta; -} - -class LongSumAggregation : public Aggregation, InstrumentMonotonicityAwareAggregation +class LongSumAggregation : public Aggregation { public: - LongSumAggregation(bool is_monotonic); + LongSumAggregation(); + LongSumAggregation(SumPointData &&); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - PointType Collect() noexcept override; + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + + PointType ToPoint() const noexcept override; private: opentelemetry::common::SpinLockMutex lock_; - opentelemetry::common::SystemTimestamp start_epoch_nanos_; - long sum_; + SumPointData point_data_; }; -class DoubleSumAggregation : public Aggregation, InstrumentMonotonicityAwareAggregation +class DoubleSumAggregation : public Aggregation { public: - DoubleSumAggregation(bool is_monotonic); + DoubleSumAggregation(); + DoubleSumAggregation(SumPointData &&); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; - PointType Collect() noexcept override; + virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + + virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + + PointType ToPoint() const noexcept override; private: - opentelemetry::common::SpinLockMutex lock_; - opentelemetry::common::SystemTimestamp start_epoch_nanos_; - double sum_; + mutable opentelemetry::common::SpinLockMutex lock_; + SumPointData point_data_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h b/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h index cb7bc4cf80..738d4540f7 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h @@ -17,18 +17,23 @@ namespace sdk namespace metrics { -using PointAttributes = opentelemetry::sdk::common::AttributeMap; +using PointAttributes = opentelemetry::sdk::common::OrderedAttributeMap; using PointType = opentelemetry::nostd:: variant; +struct PointDataAttributes +{ + PointAttributes attributes; + PointType point_data; +}; + class MetricData { public: - opentelemetry::sdk::resource::Resource *resource_; - opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary *instrumentation_library_; - PointAttributes attributes_; InstrumentDescriptor instrument_descriptor; - PointType point_data_; + opentelemetry::common::SystemTimestamp start_ts; + opentelemetry::common::SystemTimestamp end_ts; + std::vector point_data_attr_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h index 5bbcbd0b1e..714f96c9af 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h @@ -8,7 +8,7 @@ # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/version.h" -# include +# include OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -17,40 +17,62 @@ namespace metrics { using ValueType = nostd::variant; -using ListType = nostd::variant, std::vector>; +using ListType = nostd::variant, std::list>; + +// TODO: remove ctors and initializers from below classes when GCC<5 stops shipping on Ubuntu class SumPointData { public: - opentelemetry::common::SystemTimestamp start_epoch_nanos_; - opentelemetry::common::SystemTimestamp end_epoch_nanos_; - ValueType value_; - AggregationTemporality aggregation_temporality_; - bool is_monotonic_; + // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu + SumPointData(SumPointData &&) = default; + SumPointData(const SumPointData &) = default; + SumPointData &operator=(SumPointData &&) = default; + SumPointData() = default; + + ValueType value_ = {}; }; class LastValuePointData { public: - opentelemetry::common::SystemTimestamp epoch_nanos_; - bool is_lastvalue_valid_; - ValueType value_; + // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu + LastValuePointData(LastValuePointData &&) = default; + LastValuePointData(const LastValuePointData &) = default; + LastValuePointData &operator=(LastValuePointData &&) = default; + LastValuePointData() = default; + + ValueType value_ = {}; + bool is_lastvalue_valid_ = {}; + opentelemetry::common::SystemTimestamp sample_ts_ = {}; }; class HistogramPointData { public: - opentelemetry::common::SystemTimestamp epoch_nanos_; - ListType boundaries_; - ValueType sum_; - std::vector counts_; - uint64_t count_; + // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu + HistogramPointData(HistogramPointData &&) = default; + HistogramPointData &operator=(HistogramPointData &&) = default; + HistogramPointData(const HistogramPointData &) = default; + HistogramPointData() = default; + + ListType boundaries_ = {}; + ValueType sum_ = {}; + std::vector counts_ = {}; + uint64_t count_ = {}; }; class DropPointData -{}; +{ +public: + // TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu + DropPointData(DropPointData &&) = default; + DropPointData(const DropPointData &) = default; + DropPointData() = default; + DropPointData &operator=(DropPointData &&) = default; +}; } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/instruments.h b/sdk/include/opentelemetry/sdk/metrics/instruments.h index 15e6a25705..5d85357143 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/instruments.h @@ -40,7 +40,7 @@ enum class AggregationTemporality { kUnspecified, kDelta, - kCummulative + kCumulative }; struct InstrumentDescriptor diff --git a/sdk/include/opentelemetry/sdk/metrics/meter.h b/sdk/include/opentelemetry/sdk/metrics/meter.h index fc9fb36503..c9e02918a0 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter.h @@ -103,7 +103,7 @@ class Meter final : public opentelemetry::metrics::Meter const noexcept; /** collect metrics across all the meters **/ - bool collect(CollectorHandle *collector, + bool Collect(CollectorHandle *collector, opentelemetry::common::SystemTimestamp collect_ts, nostd::function_ref callback) noexcept; diff --git a/sdk/include/opentelemetry/sdk/metrics/meter_context.h b/sdk/include/opentelemetry/sdk/metrics/meter_context.h index 8a31821353..74f67a1c46 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter_context.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter_context.h @@ -111,7 +111,6 @@ class MeterContext : public std::enable_shared_from_this /** * Adds a meter to the list of configured meters. - * * Note: This method is INTERNAL to sdk not thread safe. * * @param meter diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h index 1f7cee8d30..57690ac87c 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h @@ -7,7 +7,6 @@ # include "opentelemetry/sdk/common/global_log_handler.h" # include "opentelemetry/sdk/metrics/data/metric_data.h" # include "opentelemetry/sdk/metrics/instruments.h" - # include "opentelemetry/version.h" # include @@ -27,7 +26,7 @@ class MetricReader { public: MetricReader( - AggregationTemporality aggregation_temporality = AggregationTemporality::kCummulative); + AggregationTemporality aggregation_temporality = AggregationTemporality::kCumulative); void SetMetricProducer(MetricProducer *metric_producer); diff --git a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h index 019d533006..31ab70c5b8 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h @@ -6,12 +6,11 @@ # include "opentelemetry/sdk/common/attributemap_hash.h" # include "opentelemetry/sdk/metrics/instruments.h" -# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" +# include "opentelemetry/sdk/metrics/state/metric_collector.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" -# include "opentelemetry/sdk/resource/resource.h" # include # include "opentelemetry/sdk/metrics/observer_result.h" diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index 32301f8038..50d40e0ae6 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -37,7 +37,7 @@ class AttributesHashMap public: Aggregation *Get(const MetricAttributes &attributes) const { - std::lock_guard guard(GetLock()); + std::lock_guard guard(lock_); auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { @@ -52,7 +52,7 @@ class AttributesHashMap */ bool Has(const MetricAttributes &attributes) const { - std::lock_guard guard(GetLock()); + std::lock_guard guard(lock_); return (hash_map_.find(attributes) == hash_map_.end()) ? false : true; } @@ -64,7 +64,8 @@ class AttributesHashMap Aggregation *GetOrSetDefault(const MetricAttributes &attributes, std::function()> aggregation_callback) { - std::lock_guard guard(GetLock()); + std::lock_guard guard(lock_); + auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { @@ -80,7 +81,7 @@ class AttributesHashMap */ void Set(const MetricAttributes &attributes, std::unique_ptr value) { - std::lock_guard guard(GetLock()); + std::lock_guard guard(lock_); hash_map_[attributes] = std::move(value); } @@ -90,7 +91,7 @@ class AttributesHashMap bool GetAllEnteries( nostd::function_ref callback) const { - std::lock_guard guard(GetLock()); + std::lock_guard guard(lock_); for (auto &kv : hash_map_) { if (!callback(kv.first, *(kv.second.get()))) @@ -106,7 +107,7 @@ class AttributesHashMap */ size_t Size() { - std::lock_guard guard(GetLock()); + std::lock_guard guard(lock_); return hash_map_.size(); } @@ -114,11 +115,7 @@ class AttributesHashMap std::unordered_map, AttributeHashGenerator> hash_map_; - static opentelemetry::common::SpinLockMutex &GetLock() noexcept - { - static opentelemetry::common::SpinLockMutex lock; - return lock; - } + mutable opentelemetry::common::SpinLockMutex lock_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h index bfe50b152d..8269d2fd3c 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -9,11 +9,14 @@ # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/exemplar/reservoir.h" # include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" +# include "opentelemetry/sdk/metrics/state/metric_collector.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" + # include "opentelemetry/sdk/metrics/view/attributes_processor.h" # include "opentelemetry/sdk/metrics/view/view.h" # include "opentelemetry/sdk/resource/resource.h" +# include # include OPENTELEMETRY_BEGIN_NAMESPACE @@ -22,6 +25,12 @@ namespace sdk namespace metrics { +struct LastReportedMetrics +{ + std::unique_ptr attributes_map; + opentelemetry::common::SystemTimestamp collection_ts; +}; + class SyncMetricStorage : public MetricStorage, public WritableMetricStorage { @@ -73,7 +82,6 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage { return; } - exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value); } @@ -88,7 +96,6 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage { return; } - exemplar_reservoir_->OfferMeasurement(value, attributes, context, std::chrono::system_clock::now()); auto attr = attributes_processor_->process(attributes); @@ -99,20 +106,19 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage nostd::span> collectors, opentelemetry::common::SystemTimestamp sdk_start_ts, opentelemetry::common::SystemTimestamp collection_ts, - nostd::function_ref callback) noexcept override - { - MetricData data; - if (callback(data)) - { - return true; - } - return false; - } + nostd::function_ref callback) noexcept override; private: InstrumentDescriptor instrument_descriptor_; AggregationType aggregation_type_; + + // hashmap to maintain the metrics for delta collection (i.e, collection since last Collect call) std::unique_ptr attributes_hashmap_; + // unreported metrics stash for all the collectors + std::unordered_map>> + unreported_metrics_; + // last reported metrics stash for all the collectors. + std::unordered_map last_reported_metrics_; const AttributesProcessor *attributes_processor_; std::function()> create_default_aggregation_; nostd::shared_ptr exemplar_reservoir_; diff --git a/sdk/src/metrics/CMakeLists.txt b/sdk/src/metrics/CMakeLists.txt index 119477eb06..d8eff48cd5 100644 --- a/sdk/src/metrics/CMakeLists.txt +++ b/sdk/src/metrics/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( meter_context.cc metric_reader.cc state/metric_collector.cc + state/sync_metric_storage.cc aggregation/histogram_aggregation.cc aggregation/lastvalue_aggregation.cc aggregation/sum_aggregation.cc diff --git a/sdk/src/metrics/aggregation/histogram_aggregation.cc b/sdk/src/metrics/aggregation/histogram_aggregation.cc index 2ebe3715bb..60f65c51b1 100644 --- a/sdk/src/metrics/aggregation/histogram_aggregation.cc +++ b/sdk/src/metrics/aggregation/histogram_aggregation.cc @@ -13,65 +13,104 @@ namespace metrics { LongHistogramAggregation::LongHistogramAggregation() - : boundaries_{0l, 5l, 10l, 25l, 50l, 75l, 100l, 250l, 500l, 1000l}, - counts_(boundaries_.size() + 1, 0), - sum_(0l), - count_(0) +{ + + point_data_.boundaries_ = std::list{0l, 5l, 10l, 25l, 50l, 75l, 100l, 250l, 500l, 1000l}; + point_data_.counts_ = + std::vector(nostd::get>(point_data_.boundaries_).size() + 1, 0); + point_data_.sum_ = 0l; + point_data_.count_ = 0; +} + +LongHistogramAggregation::LongHistogramAggregation(HistogramPointData &&data) + : point_data_{std::move(data)} {} void LongHistogramAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); - count_ += 1; - sum_ += value; - for (auto it = boundaries_.begin(); it != boundaries_.end(); ++it) + point_data_.count_ += 1; + point_data_.sum_ = nostd::get(point_data_.sum_) + value; + size_t index = 0; + for (auto it = nostd::get>(point_data_.boundaries_).begin(); + it != nostd::get>(point_data_.boundaries_).end(); ++it) { if (value < *it) { - counts_[std::distance(boundaries_.begin(), it)] += 1; + point_data_.counts_[index] += 1; return; } + index++; } } -PointType LongHistogramAggregation::Collect() noexcept +std::unique_ptr LongHistogramAggregation::Merge( + const Aggregation &delta) const noexcept { - HistogramPointData point_data; - auto epoch_nanos = std::chrono::system_clock::now(); - const std::lock_guard locked(lock_); - PopulateHistogramDataPoint(point_data, epoch_nanos, sum_, count_, counts_, boundaries_); - return point_data; + return nullptr; +} + +std::unique_ptr LongHistogramAggregation::Diff(const Aggregation &next) const noexcept +{ + return nullptr; +} + +PointType LongHistogramAggregation::ToPoint() const noexcept +{ + return point_data_; } DoubleHistogramAggregation::DoubleHistogramAggregation() - : boundaries_{0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0}, - counts_(boundaries_.size() + 1, 0), - sum_(0.0), - count_(0) +{ + + point_data_.boundaries_ = + std::list{0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0}; + point_data_.counts_ = + std::vector(nostd::get>(point_data_.boundaries_).size() + 1, 0); + point_data_.sum_ = 0.0; + point_data_.count_ = 0; +} + +DoubleHistogramAggregation::DoubleHistogramAggregation(HistogramPointData &&data) + : point_data_{std::move(data)} {} void DoubleHistogramAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); - count_ += 1; - sum_ += value; - for (auto it = boundaries_.begin(); it != boundaries_.end(); ++it) + point_data_.count_ += 1; + point_data_.sum_ = nostd::get(point_data_.sum_) + value; + size_t index = 0; + for (auto it = nostd::get>(point_data_.boundaries_).begin(); + it != nostd::get>(point_data_.boundaries_).end(); ++it) { if (value < *it) { - counts_[std::distance(boundaries_.begin(), it)] += 1; + point_data_.counts_[index] += 1; return; } + index++; } } -PointType DoubleHistogramAggregation::Collect() noexcept +std::unique_ptr DoubleHistogramAggregation::Merge( + const Aggregation &delta) const noexcept { - HistogramPointData point_data; - auto epoch_nanos = std::chrono::system_clock::now(); - const std::lock_guard locked(lock_); - PopulateHistogramDataPoint(point_data, epoch_nanos, sum_, count_, counts_, boundaries_); - return point_data; + // TODO - Implement me + return nullptr; +} + +std::unique_ptr DoubleHistogramAggregation::Diff( + const Aggregation &next) const noexcept +{ + // TODO - Implement me + return nullptr; +} + +PointType DoubleHistogramAggregation::ToPoint() const noexcept +{ + // TODO Implement me + return point_data_; } } // namespace metrics diff --git a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc index 290b526344..9c0252be31 100644 --- a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc +++ b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc @@ -14,46 +14,109 @@ namespace sdk namespace metrics { -LongLastValueAggregation::LongLastValueAggregation() : is_lastvalue_valid_(false) {} +LongLastValueAggregation::LongLastValueAggregation() +{ + point_data_.is_lastvalue_valid_ = false; + point_data_.value_ = 0l; +} +LongLastValueAggregation::LongLastValueAggregation(LastValuePointData &&data) + : point_data_{std::move(data)} +{} void LongLastValueAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); - is_lastvalue_valid_ = true; - value_ = value; + point_data_.is_lastvalue_valid_ = true; + point_data_.value_ = value; } -PointType LongLastValueAggregation::Collect() noexcept +std::unique_ptr LongLastValueAggregation::Merge( + const Aggregation &delta) const noexcept { - const std::lock_guard locked(lock_); - if (!is_lastvalue_valid_) + if (nostd::get(ToPoint()).sample_ts_.time_since_epoch() > + nostd::get(delta.ToPoint()).sample_ts_.time_since_epoch()) + { + LastValuePointData merge_data = std::move(nostd::get(ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(merge_data))); + } + else { - return LastValuePointData{ - opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), false, 0l}; + LastValuePointData merge_data = std::move(nostd::get(delta.ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(merge_data))); } - return LastValuePointData{ - opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), true, value_}; } -DoubleLastValueAggregation::DoubleLastValueAggregation() : is_lastvalue_valid_(false) {} +std::unique_ptr LongLastValueAggregation::Diff(const Aggregation &next) const noexcept +{ + if (nostd::get(ToPoint()).sample_ts_.time_since_epoch() > + nostd::get(next.ToPoint()).sample_ts_.time_since_epoch()) + { + LastValuePointData diff_data = std::move(nostd::get(ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(diff_data))); + } + else + { + LastValuePointData diff_data = std::move(nostd::get(next.ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(diff_data))); + } +} + +PointType LongLastValueAggregation::ToPoint() const noexcept +{ + return point_data_; +} + +DoubleLastValueAggregation::DoubleLastValueAggregation() +{ + point_data_.is_lastvalue_valid_ = false; + point_data_.value_ = 0.0; +} +DoubleLastValueAggregation::DoubleLastValueAggregation(LastValuePointData &&data) + : point_data_{std::move(data)} +{} void DoubleLastValueAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); - is_lastvalue_valid_ = true; - value_ = value; + point_data_.is_lastvalue_valid_ = true; + point_data_.value_ = value; } -PointType DoubleLastValueAggregation::Collect() noexcept +std::unique_ptr DoubleLastValueAggregation::Merge( + const Aggregation &delta) const noexcept { - const std::lock_guard locked(lock_); - if (!is_lastvalue_valid_) + if (nostd::get(ToPoint()).sample_ts_.time_since_epoch() > + nostd::get(delta.ToPoint()).sample_ts_.time_since_epoch()) + { + LastValuePointData merge_data = std::move(nostd::get(ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(merge_data))); + } + else { - return LastValuePointData{ - opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), false, 0.0}; + LastValuePointData merge_data = std::move(nostd::get(delta.ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(merge_data))); } - return LastValuePointData{ - opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()), true, value_}; +} + +std::unique_ptr DoubleLastValueAggregation::Diff( + const Aggregation &next) const noexcept +{ + if (nostd::get(ToPoint()).sample_ts_.time_since_epoch() > + nostd::get(next.ToPoint()).sample_ts_.time_since_epoch()) + { + LastValuePointData diff_data = std::move(nostd::get(ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(diff_data))); + } + else + { + LastValuePointData diff_data = std::move(nostd::get(next.ToPoint())); + return std::unique_ptr(new LongLastValueAggregation(std::move(diff_data))); + } +} + +PointType DoubleLastValueAggregation::ToPoint() const noexcept +{ + return point_data_; } } // namespace metrics } // namespace sdk diff --git a/sdk/src/metrics/aggregation/sum_aggregation.cc b/sdk/src/metrics/aggregation/sum_aggregation.cc index e0d1330f68..94b871cd34 100644 --- a/sdk/src/metrics/aggregation/sum_aggregation.cc +++ b/sdk/src/metrics/aggregation/sum_aggregation.cc @@ -3,8 +3,10 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" +# include "opentelemetry/sdk/metrics/data/point_data.h" # include "opentelemetry/version.h" +# include # include OPENTELEMETRY_BEGIN_NAMESPACE @@ -13,54 +15,90 @@ namespace sdk namespace metrics { -LongSumAggregation::LongSumAggregation(bool is_monotonic) - : InstrumentMonotonicityAwareAggregation(is_monotonic), - start_epoch_nanos_(opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())), - sum_(0l) -{} +LongSumAggregation::LongSumAggregation() +{ + point_data_.value_ = 0l; +} + +LongSumAggregation::LongSumAggregation(SumPointData &&data) : point_data_{std::move(data)} {} void LongSumAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); - sum_ += value; + point_data_.value_ = nostd::get(point_data_.value_) + value; } -PointType LongSumAggregation::Collect() noexcept +std::unique_ptr LongSumAggregation::Merge(const Aggregation &delta) const noexcept { - opentelemetry::common::SystemTimestamp current_ts(std::chrono::system_clock::now()); - SumPointData sum; - { - const std::lock_guard locked(lock_); - PopulateSumPointData(sum, start_epoch_nanos_, current_ts, sum_, IsMonotonic()); - start_epoch_nanos_ = current_ts; - sum_ = 0; - } - return sum; + long merge_value = + nostd::get( + nostd::get((static_cast(delta).ToPoint())) + .value_) + + nostd::get(nostd::get(ToPoint()).value_); + std::unique_ptr aggr(new LongSumAggregation()); + static_cast(aggr.get())->point_data_.value_ = merge_value; + return aggr; } -DoubleSumAggregation::DoubleSumAggregation(bool is_monotonic) - : InstrumentMonotonicityAwareAggregation(is_monotonic), - start_epoch_nanos_(opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())), - sum_(0L) -{} +std::unique_ptr LongSumAggregation::Diff(const Aggregation &next) const noexcept +{ + + long diff_value = nostd::get(nostd::get( + (static_cast(next).ToPoint())) + .value_) - + nostd::get(nostd::get(ToPoint()).value_); + std::unique_ptr aggr(new LongSumAggregation()); + static_cast(aggr.get())->point_data_.value_ = diff_value; + return aggr; +} + +PointType LongSumAggregation::ToPoint() const noexcept +{ + return point_data_; +} + +DoubleSumAggregation::DoubleSumAggregation() +{ + point_data_.value_ = 0.0; +} + +DoubleSumAggregation::DoubleSumAggregation(SumPointData &&data) : point_data_(std::move(data)) {} void DoubleSumAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); - sum_ += value; + point_data_.value_ = nostd::get(point_data_.value_) + value; +} + +std::unique_ptr DoubleSumAggregation::Merge(const Aggregation &delta) const noexcept +{ + double merge_value = + nostd::get( + nostd::get((static_cast(delta).ToPoint())) + .value_) + + nostd::get(nostd::get(ToPoint()).value_); + std::unique_ptr aggr(new DoubleSumAggregation()); + static_cast(aggr.get())->point_data_.value_ = merge_value; + return aggr; } -PointType DoubleSumAggregation::Collect() noexcept +std::unique_ptr DoubleSumAggregation::Diff(const Aggregation &next) const noexcept { - opentelemetry::common::SystemTimestamp current_ts(std::chrono::system_clock::now()); - SumPointData sum; - { - const std::lock_guard locked(lock_); - PopulateSumPointData(sum, start_epoch_nanos_, current_ts, sum_, IsMonotonic()); - start_epoch_nanos_ = current_ts; - sum_ = 0; - } - return sum; + + double diff_value = + nostd::get( + nostd::get((static_cast(next).ToPoint())) + .value_) - + nostd::get(nostd::get(ToPoint()).value_); + std::unique_ptr aggr(new DoubleSumAggregation()); + static_cast(aggr.get())->point_data_.value_ = diff_value; + return aggr; +} + +PointType DoubleSumAggregation::ToPoint() const noexcept +{ + const std::lock_guard locked(lock_); + return point_data_; } } // namespace metrics diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index 20e3b02768..fb74d55eb4 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -211,7 +211,7 @@ std::unique_ptr Meter::RegisterMetricStorage( } /** collect metrics across all the meters **/ -bool Meter::collect(CollectorHandle *collector, +bool Meter::Collect(CollectorHandle *collector, opentelemetry::common::SystemTimestamp collect_ts, nostd::function_ref callback) noexcept { diff --git a/sdk/src/metrics/state/metric_collector.cc b/sdk/src/metrics/state/metric_collector.cc index 5b9fc4ab70..cd3b8eb6ca 100644 --- a/sdk/src/metrics/state/metric_collector.cc +++ b/sdk/src/metrics/state/metric_collector.cc @@ -34,7 +34,7 @@ bool MetricCollector::Collect(nostd::function_ref callback) no for (auto &meter : meter_context_->GetMeters()) { auto collection_ts = std::chrono::system_clock::now(); - meter->collect(this, collection_ts, callback); + meter->Collect(this, collection_ts, callback); } return true; } diff --git a/sdk/src/metrics/state/sync_metric_storage.cc b/sdk/src/metrics/state/sync_metric_storage.cc new file mode 100644 index 0000000000..5c14f8bbc3 --- /dev/null +++ b/sdk/src/metrics/state/sync_metric_storage.cc @@ -0,0 +1,131 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +bool SyncMetricStorage::Collect(CollectorHandle *collector, + nostd::span> collectors, + opentelemetry::common::SystemTimestamp sdk_start_ts, + opentelemetry::common::SystemTimestamp collection_ts, + nostd::function_ref callback) noexcept +{ + opentelemetry::common::SystemTimestamp last_collection_ts = sdk_start_ts; + auto aggregation_temporarily = collector->GetAggregationTemporality(); + + // Add the current delta metrics to `unreported metrics stash` for all the collectors, + // this will also empty the delta metrics hashmap, and make it available for + // recordings + std::shared_ptr delta_metrics = std::move(attributes_hashmap_); + attributes_hashmap_.reset(new AttributesHashMap); + for (auto &col : collectors) + { + unreported_metrics_[col.get()].push_back(delta_metrics); + } + + // Get the unreported metrics for the `collector` from `unreported metrics stash` + // since last collection, this will also cleanup the unreported metrics for `collector` + // from the stash. + auto present = unreported_metrics_.find(collector); + if (present == unreported_metrics_.end()) + { + // no unreported metrics for the collector, return. + return true; + } + auto unreported_list = std::move(present->second); + + // Iterate over the unreporter metrics for `collector` and store result in `merged_metrics` + std::unique_ptr merged_metrics(new AttributesHashMap); + for (auto &agg_hashmap : unreported_list) + { + agg_hashmap->GetAllEnteries([&merged_metrics, this](const MetricAttributes &attributes, + Aggregation &aggregation) { + auto agg = merged_metrics->Get(attributes); + if (agg) + { + merged_metrics->Set(attributes, std::move(agg->Merge(aggregation))); + } + else + { + merged_metrics->Set( + attributes, + std::move( + DefaultAggregation::CreateAggregation(instrument_descriptor_)->Merge(aggregation))); + merged_metrics->GetAllEnteries( + [](const MetricAttributes &attr, Aggregation &aggr) { return true; }); + } + return true; + }); + } + // Get the last reported metrics for the `collector` from `last reported metrics` stash + // - If the aggregation_temporarily for the collector is cumulative + // - Merge the last reported metrics with unreported metrics (which is in merged_metrics), + // Final result of merge would be in merged_metrics. + // - Move the final merge to the `last reported metrics` stash. + // - If the aggregation_temporarily is delta + // - Store the unreported metrics for `collector` (which is in merged_mtrics) to + // `last reported metrics` stash. + + auto reported = last_reported_metrics_.find(collector); + if (reported != last_reported_metrics_.end()) + { + last_collection_ts = last_reported_metrics_[collector].collection_ts; + auto last_aggr_hashmap = std::move(last_reported_metrics_[collector].attributes_map); + if (aggregation_temporarily == AggregationTemporality::kCumulative) + { + // merge current delta to previous cumulative + last_aggr_hashmap->GetAllEnteries( + [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { + auto agg = merged_metrics->Get(attributes); + if (agg) + { + merged_metrics->Set(attributes, agg->Merge(aggregation)); + } + else + { + merged_metrics->Set(attributes, + DefaultAggregation::CreateAggregation(instrument_descriptor_)); + } + return true; + }); + } + last_reported_metrics_[collector] = + LastReportedMetrics{std::move(merged_metrics), collection_ts}; + } + else + { + merged_metrics->GetAllEnteries( + [](const MetricAttributes &attr, Aggregation &aggr) { return true; }); + last_reported_metrics_.insert( + std::make_pair(collector, LastReportedMetrics{std::move(merged_metrics), collection_ts})); + } + + // Generate the MetricData from the final merged_metrics, and invoke callback over it. + + AttributesHashMap *result_to_export = (last_reported_metrics_[collector]).attributes_map.get(); + MetricData metric_data; + metric_data.instrument_descriptor = instrument_descriptor_; + metric_data.start_ts = last_collection_ts; + metric_data.end_ts = collection_ts; + result_to_export->GetAllEnteries( + [&metric_data](const MetricAttributes &attributes, Aggregation &aggregation) { + PointDataAttributes point_data_attr; + point_data_attr.point_data = aggregation.ToPoint(); + point_data_attr.attributes = attributes; + metric_data.point_data_attr_.push_back(point_data_attr); + return true; + }); + return callback(metric_data); +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/test/metrics/aggregation_test.cc b/sdk/test/metrics/aggregation_test.cc index ec753111ff..a32826b145 100644 --- a/sdk/test/metrics/aggregation_test.cc +++ b/sdk/test/metrics/aggregation_test.cc @@ -13,82 +13,80 @@ using namespace opentelemetry::sdk::metrics; namespace nostd = opentelemetry::nostd; TEST(Aggregation, LongSumAggregation) { - LongSumAggregation aggr(true); - auto data = aggr.Collect(); + LongSumAggregation aggr; + auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto sum_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(sum_data.value_)); EXPECT_EQ(nostd::get(sum_data.value_), 0l); - EXPECT_EQ(sum_data.is_monotonic_, true); EXPECT_NO_THROW(aggr.Aggregate(12l, {})); EXPECT_NO_THROW(aggr.Aggregate(0l, {})); - sum_data = nostd::get(aggr.Collect()); + sum_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(nostd::get(sum_data.value_), 12l); } TEST(Aggregation, DoubleSumAggregation) { - DoubleSumAggregation aggr(true); - auto data = aggr.Collect(); + DoubleSumAggregation aggr; + auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto sum_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(sum_data.value_)); EXPECT_EQ(nostd::get(sum_data.value_), 0); - EXPECT_EQ(sum_data.is_monotonic_, true); EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); EXPECT_NO_THROW(aggr.Aggregate(1.0, {})); - sum_data = nostd::get(aggr.Collect()); + sum_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(nostd::get(sum_data.value_), 13.0); } TEST(Aggregation, LongLastValueAggregation) { LongLastValueAggregation aggr; - auto data = aggr.Collect(); + auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto lastvalue_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(lastvalue_data.value_)); EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); EXPECT_NO_THROW(aggr.Aggregate(12l, {})); EXPECT_NO_THROW(aggr.Aggregate(1l, {})); - lastvalue_data = nostd::get(aggr.Collect()); + lastvalue_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(nostd::get(lastvalue_data.value_), 1.0); } TEST(Aggregation, DoubleLastValueAggregation) { DoubleLastValueAggregation aggr; - auto data = aggr.Collect(); + auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto lastvalue_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(lastvalue_data.value_)); EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); EXPECT_NO_THROW(aggr.Aggregate(1.0, {})); - lastvalue_data = nostd::get(aggr.Collect()); + lastvalue_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(nostd::get(lastvalue_data.value_), 1.0); } TEST(Aggregation, LongHistogramAggregation) { LongHistogramAggregation aggr; - auto data = aggr.Collect(); + auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto histogram_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); - ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); + ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); EXPECT_EQ(nostd::get(histogram_data.sum_), 0); EXPECT_EQ(histogram_data.count_, 0); EXPECT_NO_THROW(aggr.Aggregate(12l, {})); // lies in fourth bucket EXPECT_NO_THROW(aggr.Aggregate(100l, {})); // lies in eight bucket - histogram_data = nostd::get(aggr.Collect()); + histogram_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(nostd::get(histogram_data.sum_), 112); EXPECT_EQ(histogram_data.count_, 2); EXPECT_EQ(histogram_data.counts_[3], 1); EXPECT_EQ(histogram_data.counts_[7], 1); EXPECT_NO_THROW(aggr.Aggregate(13l, {})); // lies in fourth bucket EXPECT_NO_THROW(aggr.Aggregate(252l, {})); // lies in ninth bucket - histogram_data = nostd::get(aggr.Collect()); + histogram_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(histogram_data.count_, 4); EXPECT_EQ(histogram_data.counts_[3], 2); EXPECT_EQ(histogram_data.counts_[8], 1); @@ -97,23 +95,23 @@ TEST(Aggregation, LongHistogramAggregation) TEST(Aggregation, DoubleHistogramAggregation) { DoubleHistogramAggregation aggr; - auto data = aggr.Collect(); + auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto histogram_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); - ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); + ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); EXPECT_EQ(nostd::get(histogram_data.sum_), 0); EXPECT_EQ(histogram_data.count_, 0); EXPECT_NO_THROW(aggr.Aggregate(12.0, {})); // lies in fourth bucket EXPECT_NO_THROW(aggr.Aggregate(100.0, {})); // lies in eight bucket - histogram_data = nostd::get(aggr.Collect()); + histogram_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(nostd::get(histogram_data.sum_), 112); EXPECT_EQ(histogram_data.count_, 2); EXPECT_EQ(histogram_data.counts_[3], 1); EXPECT_EQ(histogram_data.counts_[7], 1); EXPECT_NO_THROW(aggr.Aggregate(13.0, {})); // lies in fourth bucket EXPECT_NO_THROW(aggr.Aggregate(252.0, {})); // lies in ninth bucket - histogram_data = nostd::get(aggr.Collect()); + histogram_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(histogram_data.count_, 4); EXPECT_EQ(histogram_data.counts_[3], 2); EXPECT_EQ(histogram_data.counts_[8], 1); diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index 0527c7f0ca..f7c9914e3c 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -42,6 +42,10 @@ TEST(AsyncMetricStorageTest, BasicTests) InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, InstrumentValueType::kLong}; + auto sdk_start_ts = std::chrono::system_clock::now(); + // Some computation here + auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5); + std::vector> exporters; std::shared_ptr meter_context(new MeterContext(std::move(exporters))); std::unique_ptr metric_reader(new MockMetricReader(AggregationTemporality::kDelta)); @@ -53,7 +57,7 @@ TEST(AsyncMetricStorageTest, BasicTests) opentelemetry::sdk::metrics::AsyncMetricStorage storage( instr_desc, AggregationType::kSum, &measurement_fetch, new DefaultAttributesProcessor()); - storage.Collect(collector.get(), collectors, std::chrono::system_clock::now(), - std::chrono::system_clock::now(), metric_callback); + EXPECT_NO_THROW( + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, metric_callback)); } #endif \ No newline at end of file diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index 015d3023ae..6ede67d032 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -40,9 +40,7 @@ class MockMetricReader : public MetricReader { public: virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } - virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept override { return true; } - virtual void OnInitialized() noexcept override {} }; diff --git a/sdk/test/metrics/metric_reader_test.cc b/sdk/test/metrics/metric_reader_test.cc index 214f522118..68a3fcc5f5 100644 --- a/sdk/test/metrics/metric_reader_test.cc +++ b/sdk/test/metrics/metric_reader_test.cc @@ -17,9 +17,7 @@ class MockMetricReader : public MetricReader MockMetricReader(AggregationTemporality aggr_temporality) : MetricReader(aggr_temporality) {} virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } - virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept override { return true; } - virtual void OnInitialized() noexcept override {} }; diff --git a/sdk/test/metrics/sync_metric_storage_test.cc b/sdk/test/metrics/sync_metric_storage_test.cc index c4bd154460..b0440fdbb3 100644 --- a/sdk/test/metrics/sync_metric_storage_test.cc +++ b/sdk/test/metrics/sync_metric_storage_test.cc @@ -12,23 +12,235 @@ # include using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::common; using M = std::map; -TEST(WritableMetricStorageTest, BasicTests) +class MockCollectorHandle : public CollectorHandle { - InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, +public: + MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} + + AggregationTemporality GetAggregationTemporality() noexcept override { return temporality; } + +private: + AggregationTemporality temporality; +}; + +class WritableMetricStorageTestFixture : public ::testing::TestWithParam +{}; + +TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) +{ + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + long expected_total_get_requests = 0; + long expected_total_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, InstrumentValueType::kLong}; + std::map attributes_get = {{"RequestType", "GET"}}; + std::map attributes_put = {{"RequestType", "PUT"}}; opentelemetry::sdk::metrics::SyncMetricStorage storage( instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), NoExemplarReservoir::GetNoExemplarReservoir()); - EXPECT_NO_THROW(storage.RecordLong(10l, opentelemetry::context::Context{})); - EXPECT_NO_THROW(storage.RecordDouble(10.10, opentelemetry::context::Context{})); + + storage.RecordLong(10l, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 10; + + EXPECT_NO_THROW(storage.RecordLong( + 30l, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 30; + + storage.RecordLong(20l, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 20; + + EXPECT_NO_THROW(storage.RecordLong( + 40l, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + std::shared_ptr collector(new MockCollectorHandle(temporality)); + std::vector> collectors; + collectors.push_back(collector); + + // Some computation here + auto collection_ts = std::chrono::system_clock::now(); + size_t count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); + + // In case of delta temporarily, subsequent collection would contain new data points, so resetting + // the counts + if (temporality == AggregationTemporality::kDelta) + { + expected_total_get_requests = 0; + expected_total_put_requests = 0; + } + EXPECT_NO_THROW(storage.RecordLong( - 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + 50l, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{})); + expected_total_get_requests += 50; + EXPECT_NO_THROW(storage.RecordLong( + 40l, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); +} +INSTANTIATE_TEST_CASE_P(WritableMetricStorageTestLong, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + +TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) +{ + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + double expected_total_get_requests = 0; + double expected_total_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, + InstrumentValueType::kDouble}; + std::map attributes_get = {{"RequestType", "GET"}}; + std::map attributes_put = {{"RequestType", "PUT"}}; + + opentelemetry::sdk::metrics::SyncMetricStorage storage( + instr_desc, AggregationType::kSum, new DefaultAttributesProcessor(), + NoExemplarReservoir::GetNoExemplarReservoir()); + + storage.RecordDouble(10.0, + KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 10; + + EXPECT_NO_THROW(storage.RecordDouble( + 30.0, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{})); + expected_total_put_requests += 30; - EXPECT_NO_THROW(storage.RecordDouble(10.10, opentelemetry::common::KeyValueIterableView({}), - opentelemetry::context::Context{})); + storage.RecordDouble(20.0, + KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_get_requests += 20; + + EXPECT_NO_THROW(storage.RecordDouble( + 40.0, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + std::shared_ptr collector(new MockCollectorHandle(temporality)); + std::vector> collectors; + collectors.push_back(collector); + + // Some computation here + auto collection_ts = std::chrono::system_clock::now(); + size_t count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); + + // In case of delta temporarily, subsequent collection would contain new data points, so resetting + // the counts + if (temporality == AggregationTemporality::kDelta) + { + expected_total_get_requests = 0; + expected_total_put_requests = 0; + } + + EXPECT_NO_THROW(storage.RecordDouble( + 50.0, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{})); + expected_total_get_requests += 50; + EXPECT_NO_THROW(storage.RecordDouble( + 40.0, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{})); + expected_total_put_requests += 40; + + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + count_attributes++; + } + } + return true; + }); } +INSTANTIATE_TEST_CASE_P(WritableMetricStorageTestDouble, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + #endif From 76c664a20b8219b91ead69ded6b7ee873b1a85ba Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Fri, 1 Apr 2022 02:51:26 +0800 Subject: [PATCH 10/69] Rename `http_client_curl` to `opentelemetry_http_client_curl` (#1301) Signed-off-by: owent --- examples/http/CMakeLists.txt | 9 +++++---- exporters/elasticsearch/CMakeLists.txt | 2 +- exporters/jaeger/CMakeLists.txt | 2 +- exporters/otlp/CMakeLists.txt | 2 +- exporters/zipkin/CMakeLists.txt | 3 ++- ext/src/http/client/curl/CMakeLists.txt | 19 ++++++++++--------- ext/test/http/CMakeLists.txt | 6 ++++-- ext/test/w3c_tracecontext_test/CMakeLists.txt | 6 +++--- 8 files changed, 27 insertions(+), 22 deletions(-) diff --git a/examples/http/CMakeLists.txt b/examples/http/CMakeLists.txt index 2eddcfe03f..a1181c93a4 100644 --- a/examples/http/CMakeLists.txt +++ b/examples/http/CMakeLists.txt @@ -10,10 +10,11 @@ else() add_executable(http_server server.cc) target_link_libraries( - http_client ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace http_client_curl - opentelemetry_exporter_ostream_span ${CURL_LIBRARIES}) + http_client ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace + opentelemetry_http_client_curl opentelemetry_exporter_ostream_span + ${CURL_LIBRARIES}) target_link_libraries( - http_server ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace http_client_curl - opentelemetry_exporter_ostream_span) + http_server ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace + opentelemetry_http_client_curl opentelemetry_exporter_ostream_span) endif() diff --git a/exporters/elasticsearch/CMakeLists.txt b/exporters/elasticsearch/CMakeLists.txt index 1538a6f44a..9b2833854e 100644 --- a/exporters/elasticsearch/CMakeLists.txt +++ b/exporters/elasticsearch/CMakeLists.txt @@ -10,7 +10,7 @@ target_include_directories( target_link_libraries( opentelemetry_exporter_elasticsearch_logs - PUBLIC opentelemetry_trace opentelemetry_logs http_client_curl) + PUBLIC opentelemetry_trace opentelemetry_logs opentelemetry_http_client_curl) install( TARGETS opentelemetry_exporter_elasticsearch_logs diff --git a/exporters/jaeger/CMakeLists.txt b/exporters/jaeger/CMakeLists.txt index 0659c399b0..6d3d8b88fb 100644 --- a/exporters/jaeger/CMakeLists.txt +++ b/exporters/jaeger/CMakeLists.txt @@ -31,7 +31,7 @@ target_include_directories( target_link_libraries( opentelemetry_exporter_jaeger_trace - PUBLIC opentelemetry_resources http_client_curl + PUBLIC opentelemetry_resources opentelemetry_http_client_curl PRIVATE thrift::thrift) if(MSVC) diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 0332267922..1dba7ea1c7 100755 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -46,7 +46,7 @@ if(WITH_OTLP_HTTP) PROPERTIES EXPORT_NAME otlp_http_client) target_link_libraries( opentelemetry_exporter_otlp_http_client - PUBLIC opentelemetry_sdk opentelemetry_proto http_client_curl + PUBLIC opentelemetry_sdk opentelemetry_proto opentelemetry_http_client_curl nlohmann_json::nlohmann_json) if(nlohmann_json_clone) add_dependencies(opentelemetry_exporter_otlp_http_client diff --git a/exporters/zipkin/CMakeLists.txt b/exporters/zipkin/CMakeLists.txt index b9591324fd..b82339f1ee 100644 --- a/exporters/zipkin/CMakeLists.txt +++ b/exporters/zipkin/CMakeLists.txt @@ -20,7 +20,8 @@ add_library(opentelemetry_exporter_zipkin_trace src/zipkin_exporter.cc target_link_libraries( opentelemetry_exporter_zipkin_trace - PUBLIC opentelemetry_trace http_client_curl nlohmann_json::nlohmann_json) + PUBLIC opentelemetry_trace opentelemetry_http_client_curl + nlohmann_json::nlohmann_json) install( TARGETS opentelemetry_exporter_zipkin_trace diff --git a/ext/src/http/client/curl/CMakeLists.txt b/ext/src/http/client/curl/CMakeLists.txt index 64486b96db..78a81cfe3e 100644 --- a/ext/src/http/client/curl/CMakeLists.txt +++ b/ext/src/http/client/curl/CMakeLists.txt @@ -1,22 +1,23 @@ find_package(CURL) if(CURL_FOUND) - add_library(http_client_curl http_client_factory_curl.cc http_client_curl.cc) + add_library(opentelemetry_http_client_curl http_client_factory_curl.cc + http_client_curl.cc) - set_target_properties(http_client_curl PROPERTIES EXPORT_NAME - http_client_curl) + set_target_properties(opentelemetry_http_client_curl + PROPERTIES EXPORT_NAME http_client_curl) if(TARGET CURL::libcurl) - target_link_libraries(http_client_curl PUBLIC opentelemetry_ext - CURL::libcurl) + target_link_libraries(opentelemetry_http_client_curl + PUBLIC opentelemetry_ext CURL::libcurl) else() - target_include_directories(http_client_curl + target_include_directories(opentelemetry_http_client_curl INTERFACE "${CURL_INCLUDE_DIRS}") - target_link_libraries(http_client_curl PUBLIC opentelemetry_ext - ${CURL_LIBRARIES}) + target_link_libraries(opentelemetry_http_client_curl + PUBLIC opentelemetry_ext ${CURL_LIBRARIES}) endif() install( - TARGETS http_client_curl + TARGETS opentelemetry_http_client_curl EXPORT "${PROJECT_NAME}-target" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/ext/test/http/CMakeLists.txt b/ext/test/http/CMakeLists.txt index 13b7c8206e..341648085d 100644 --- a/ext/test/http/CMakeLists.txt +++ b/ext/test/http/CMakeLists.txt @@ -7,10 +7,12 @@ if(CURL_FOUND) ${CMAKE_THREAD_LIBS_INIT}) if(TARGET CURL::libcurl) - target_link_libraries(${FILENAME} CURL::libcurl http_client_curl) + target_link_libraries(${FILENAME} opentelemetry_http_client_curl + CURL::libcurl) else() include_directories(${CURL_INCLUDE_DIRS}) - target_link_libraries(${FILENAME} ${CURL_LIBRARIES} http_client_curl) + target_link_libraries(${FILENAME} ${CURL_LIBRARIES} + opentelemetry_http_client_curl) endif() gtest_add_tests( TARGET ${FILENAME} diff --git a/ext/test/w3c_tracecontext_test/CMakeLists.txt b/ext/test/w3c_tracecontext_test/CMakeLists.txt index 30e2f5d0f3..ea74a8eeb0 100644 --- a/ext/test/w3c_tracecontext_test/CMakeLists.txt +++ b/ext/test/w3c_tracecontext_test/CMakeLists.txt @@ -7,9 +7,9 @@ else() add_executable(w3c_tracecontext_test main.cc) target_link_libraries( w3c_tracecontext_test - PRIVATE ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace http_client_curl - opentelemetry_exporter_ostream_span ${CURL_LIBRARIES} - nlohmann_json::nlohmann_json) + PRIVATE ${CMAKE_THREAD_LIBS_INIT} opentelemetry_trace + opentelemetry_http_client_curl opentelemetry_exporter_ostream_span + ${CURL_LIBRARIES} nlohmann_json::nlohmann_json) if(nlohmann_json_clone) add_dependencies(w3c_tracecontext_test nlohmann_json::nlohmann_json) endif() From 2034c9bcfa9cf6a995891efed36264088a333d37 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 1 Apr 2022 10:57:31 -0700 Subject: [PATCH 11/69] Don't show coverage annotation for pull requests (#1304) --- .github/.codecov.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/.codecov.yaml b/.github/.codecov.yaml index e2c304a9b4..2b3003ff57 100644 --- a/.github/.codecov.yaml +++ b/.github/.codecov.yaml @@ -12,11 +12,7 @@ coverage: informational: true target: auto threshold: 10% - patch: - default: - informational: true - target: auto - threshold: 10% + patch: false parsers: gcov: From 33d9c628f2e7029b6b92733df69336f7e384c7e4 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Fri, 1 Apr 2022 14:07:44 -0700 Subject: [PATCH 12/69] Implement periodic exporting metric reader (#1286) --- exporters/ostream/BUILD | 6 +- .../export/periodic_exporting_metric_reader.h | 72 +++++++++++++ .../sdk/metrics/metric_exporter.h | 9 +- .../opentelemetry/sdk/metrics/metric_reader.h | 1 + sdk/src/metrics/CMakeLists.txt | 1 + .../periodic_exporting_metric_reader.cc | 101 ++++++++++++++++++ sdk/src/metrics/metric_reader.cc | 10 +- sdk/test/metrics/CMakeLists.txt | 3 +- sdk/test/metrics/meter_provider_sdk_test.cc | 3 +- .../periodic_exporting_metric_reader_test.cc | 81 ++++++++++++++ 10 files changed, 272 insertions(+), 15 deletions(-) create mode 100644 sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h create mode 100644 sdk/src/metrics/export/periodic_exporting_metric_reader.cc create mode 100644 sdk/test/metrics/periodic_exporting_metric_reader_test.cc diff --git a/exporters/ostream/BUILD b/exporters/ostream/BUILD index 19c0f7914d..f74d896344 100644 --- a/exporters/ostream/BUILD +++ b/exporters/ostream/BUILD @@ -43,7 +43,9 @@ cc_library( ], ) -#TODO MetricData is still changing, uncomment once it is final +# TODO - Uncomment once MetricData interface is finalised +#cc_library( +# name = "ostream_metric_exporter", # srcs = [ # "src/metric_exporter.cc", # ], @@ -70,7 +72,7 @@ cc_library( # deps = [ # ":ostream_metric_exporter", # "@com_google_googletest//:gtest_main", -#], +# ], #) cc_test( diff --git a/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h new file mode 100644 index 0000000000..29125a6ea2 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h @@ -0,0 +1,72 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/sdk/metrics/metric_reader.h" +# include "opentelemetry/version.h" + +# include +# include +# include +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class MetricExporter; +/** + * Struct to hold PeriodicExortingMetricReader options. + */ + +constexpr std::chrono::milliseconds kExportIntervalMillis = std::chrono::milliseconds(60000); +constexpr std::chrono::milliseconds kExportTimeOutMillis = std::chrono::milliseconds(30000); +struct PeriodicExportingMetricReaderOptions +{ + + /* The time interval between two consecutive exports. */ + std::chrono::milliseconds export_interval_millis = + std::chrono::milliseconds(kExportIntervalMillis); + + /* how long the export can run before it is cancelled. */ + std::chrono::milliseconds export_timeout_millis = std::chrono::milliseconds(kExportTimeOutMillis); +}; + +class PeriodicExportingMetricReader : public MetricReader +{ + +public: + PeriodicExportingMetricReader( + std::unique_ptr exporter, + const PeriodicExportingMetricReaderOptions &option, + AggregationTemporality aggregation_temporality = AggregationTemporality::kCumulative); + +private: + bool OnForceFlush(std::chrono::microseconds timeout) noexcept override; + + bool OnShutDown(std::chrono::microseconds timeout) noexcept override; + + void OnInitialized() noexcept override; + + std::unique_ptr exporter_; + std::chrono::milliseconds export_interval_millis_; + std::chrono::milliseconds export_timeout_millis_; + + void DoBackgroundWork(); + + /* The background worker thread */ + std::thread worker_thread_; + + /* Synchronization primitives */ + std::condition_variable cv_; + std::mutex cv_m_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h index 3769259472..2488edd7ed 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h @@ -30,11 +30,9 @@ class MetricExporter /** * Exports a batch of metrics recordables. This method must not be called * concurrently for the same exporter instance. - * @param spans a span of unique pointers to metrics data + * @param data metrics data */ - virtual opentelemetry::sdk::common::ExportResult Export( - const nostd::span> - &records) noexcept = 0; + virtual opentelemetry::sdk::common::ExportResult Export(const MetricData &data) noexcept = 0; /** * Force flush the exporter. @@ -49,9 +47,6 @@ class MetricExporter */ virtual bool Shutdown( std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept = 0; - -private: - AggregationTemporality aggregation_temporality_; }; } // namespace metrics } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h index 57690ac87c..7cf449e1e3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h @@ -57,6 +57,7 @@ class MetricReader virtual void OnInitialized() noexcept {} +protected: bool IsShutdown() const noexcept; private: diff --git a/sdk/src/metrics/CMakeLists.txt b/sdk/src/metrics/CMakeLists.txt index d8eff48cd5..b6656b5bf8 100644 --- a/sdk/src/metrics/CMakeLists.txt +++ b/sdk/src/metrics/CMakeLists.txt @@ -4,6 +4,7 @@ add_library( meter.cc meter_context.cc metric_reader.cc + export/periodic_exporting_metric_reader.cc state/metric_collector.cc state/sync_metric_storage.cc aggregation/histogram_aggregation.cc diff --git a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc new file mode 100644 index 0000000000..e9a91a9e06 --- /dev/null +++ b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc @@ -0,0 +1,101 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/common/global_log_handler.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" + +# include +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +PeriodicExportingMetricReader::PeriodicExportingMetricReader( + std::unique_ptr exporter, + const PeriodicExportingMetricReaderOptions &option, + AggregationTemporality aggregation_temporality) + : MetricReader(aggregation_temporality), + exporter_{std::move(exporter)}, + export_interval_millis_{option.export_interval_millis}, + export_timeout_millis_{option.export_timeout_millis} +{ + if (export_interval_millis_ <= export_timeout_millis_) + { + OTEL_INTERNAL_LOG_WARN( + "[Periodic Exporting Metric Reader] Invalid configuration: " + "export_interval_millis_ should be less than export_timeout_millis_, using default values"); + export_interval_millis_ = kExportIntervalMillis; + export_timeout_millis_ = kExportTimeOutMillis; + } +} + +void PeriodicExportingMetricReader::OnInitialized() noexcept +{ + worker_thread_ = std::thread(&PeriodicExportingMetricReader::DoBackgroundWork, this); +} + +void PeriodicExportingMetricReader::DoBackgroundWork() +{ + std::unique_lock lk(cv_m_); + do + { + if (IsShutdown()) + { + break; + } + std::atomic cancel_export_for_timeout{false}; + auto start = std::chrono::steady_clock::now(); + auto future_receive = std::async(std::launch::async, [this, &cancel_export_for_timeout] { + Collect([this, &cancel_export_for_timeout](MetricData data) { + if (cancel_export_for_timeout) + { + OTEL_INTERNAL_LOG_ERROR( + "[Periodic Exporting Metric Reader] Collect took longer configured time: " + << export_timeout_millis_.count() << " ms, and timed out"); + return false; + } + this->exporter_->Export(data); + return true; + }); + }); + std::future_status status; + do + { + status = future_receive.wait_for(std::chrono::milliseconds(export_timeout_millis_)); + if (status == std::future_status::timeout) + { + cancel_export_for_timeout = true; + break; + } + } while (status != std::future_status::ready); + auto end = std::chrono::steady_clock::now(); + auto export_time_ms = std::chrono::duration_cast(end - start); + auto remaining_wait_interval_ms = export_interval_millis_ - export_time_ms; + cv_.wait_for(lk, remaining_wait_interval_ms); + } while (true); +} + +bool PeriodicExportingMetricReader::OnForceFlush(std::chrono::microseconds timeout) noexcept +{ + return exporter_->ForceFlush(timeout); +} + +bool PeriodicExportingMetricReader::OnShutDown(std::chrono::microseconds timeout) noexcept +{ + if (worker_thread_.joinable()) + { + cv_.notify_one(); + worker_thread_.join(); + } + return exporter_->Shutdown(timeout); +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/src/metrics/metric_reader.cc b/sdk/src/metrics/metric_reader.cc index 8238ad2a55..abf73d766a 100644 --- a/sdk/src/metrics/metric_reader.cc +++ b/sdk/src/metrics/metric_reader.cc @@ -20,6 +20,7 @@ MetricReader::MetricReader(AggregationTemporality aggregation_temporality) void MetricReader::SetMetricProducer(MetricProducer *metric_producer) { metric_producer_ = metric_producer; + OnInitialized(); } AggregationTemporality MetricReader::GetAggregationTemporality() const noexcept @@ -46,18 +47,21 @@ bool MetricReader::Collect(nostd::function_ref callback) noexc bool MetricReader::Shutdown(std::chrono::microseconds timeout) noexcept { bool status = true; - if (IsShutdown()) { OTEL_INTERNAL_LOG_WARN("MetricReader::Shutdown - Cannot invoke shutdown twice!"); } + + { + const std::lock_guard locked(lock_); + shutdown_ = true; + } + if (!OnShutDown(timeout)) { status = false; OTEL_INTERNAL_LOG_WARN("MetricReader::OnShutDown Shutdown failed. Will not be tried again!"); } - const std::lock_guard locked(lock_); - shutdown_ = true; return status; } diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index fa1f22c73a..faf2f2b49f 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -11,7 +11,8 @@ foreach( observer_result_test sync_instruments_test async_instruments_test - metric_reader_test) + metric_reader_test + periodic_exporting_metric_reader_test) add_executable(${testname} "${testname}.cc") target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index 6ede67d032..ec0a39b523 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -18,8 +18,7 @@ class MockMetricExporter : public MetricExporter public: MockMetricExporter() = default; - opentelemetry::sdk::common::ExportResult Export( - const opentelemetry::nostd::span> &records) noexcept override + opentelemetry::sdk::common::ExportResult Export(const MetricData &records) noexcept override { return opentelemetry::sdk::common::ExportResult::kSuccess; } diff --git a/sdk/test/metrics/periodic_exporting_metric_reader_test.cc b/sdk/test/metrics/periodic_exporting_metric_reader_test.cc new file mode 100644 index 0000000000..f13fbb0e04 --- /dev/null +++ b/sdk/test/metrics/periodic_exporting_metric_reader_test.cc @@ -0,0 +1,81 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/metrics/export/metric_producer.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" + +# include + +using namespace opentelemetry; +using namespace opentelemetry::sdk::instrumentationlibrary; +using namespace opentelemetry::sdk::metrics; + +class MockPushMetricExporter : public MetricExporter +{ +public: + opentelemetry::sdk::common::ExportResult Export(const MetricData &record) noexcept override + { + records_.push_back(record); + return opentelemetry::sdk::common::ExportResult::kSuccess; + } + + bool ForceFlush( + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override + { + return false; + } + + bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept override + { + return true; + } + + size_t GetDataCount() { return records_.size(); } + +private: + std::vector records_; +}; + +class MockMetricProducer : public MetricProducer +{ +public: + MockMetricProducer(std::chrono::microseconds sleep_ms = std::chrono::microseconds::zero()) + : sleep_ms_{sleep_ms}, data_sent_size_(0) + {} + + bool Collect(nostd::function_ref callback) noexcept override + { + std::this_thread::sleep_for(sleep_ms_); + data_sent_size_++; + MetricData data; + callback(data); + return true; + } + + size_t GetDataCount() { return data_sent_size_; } + +private: + std::chrono::microseconds sleep_ms_; + size_t data_sent_size_; +}; + +TEST(PeriodicExporingMetricReader, BasicTests) +{ + std::unique_ptr exporter(new MockPushMetricExporter()); + PeriodicExportingMetricReaderOptions options; + options.export_timeout_millis = std::chrono::milliseconds(200); + options.export_interval_millis = std::chrono::milliseconds(500); + auto exporter_ptr = exporter.get(); + PeriodicExportingMetricReader reader(std::move(exporter), options); + MockMetricProducer producer; + reader.SetMetricProducer(&producer); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + reader.Shutdown(); + EXPECT_EQ(static_cast(exporter_ptr)->GetDataCount(), + static_cast(&producer)->GetDataCount()); +} + +#endif \ No newline at end of file From 48a40601061905542a52dd11109a868517a6e304 Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Tue, 5 Apr 2022 04:09:48 +0800 Subject: [PATCH 13/69] Add `async-changes` branch to pull_request of github action (#1309) Signed-off-by: owent --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a851728a2e..c29ee3084f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: [ main ] pull_request: - branches: [ main ] + branches: [ main, async-changes ] jobs: cmake_test: From be75bbc862a81319f8f9cae11c14f79f2c776aa9 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 4 Apr 2022 15:09:02 -0700 Subject: [PATCH 14/69] Add InstrumentationInfo and Resource to the metrics data to be exported. (#1299) --- .../sdk/metrics/async_instruments.h | 53 ++++++------------- .../sdk/metrics/export/metric_producer.h | 23 +++++++- sdk/include/opentelemetry/sdk/metrics/meter.h | 7 ++- .../sdk/metrics/metric_exporter.h | 2 +- .../opentelemetry/sdk/metrics/metric_reader.h | 4 +- .../sdk/metrics/state/async_metric_storage.h | 9 ++-- .../sdk/metrics/state/metric_collector.h | 2 +- .../sdk/metrics/state/metric_storage.h | 10 ++-- .../sdk/metrics/state/sync_metric_storage.h | 2 +- .../periodic_exporting_metric_reader.cc | 4 +- sdk/src/metrics/meter.cc | 29 +++++----- sdk/src/metrics/metric_reader.cc | 3 +- sdk/src/metrics/state/metric_collector.cc | 11 +++- sdk/src/metrics/state/sync_metric_storage.cc | 2 +- sdk/test/metrics/async_instruments_test.cc | 29 +++++----- sdk/test/metrics/async_metric_storage_test.cc | 2 +- sdk/test/metrics/meter_provider_sdk_test.cc | 2 +- sdk/test/metrics/metric_reader_test.cc | 2 +- .../periodic_exporting_metric_reader_test.cc | 8 +-- 19 files changed, 98 insertions(+), 106 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/async_instruments.h b/sdk/include/opentelemetry/sdk/metrics/async_instruments.h index f38ad6a3b4..8b1f76377b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/async_instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/async_instruments.h @@ -6,7 +6,6 @@ # include "opentelemetry/metrics/async_instruments.h" # include "opentelemetry/metrics/observer_result.h" # include "opentelemetry/nostd/string_view.h" -# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/metrics/instruments.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -19,22 +18,14 @@ class Asynchronous { public: Asynchronous(nostd::string_view name, - const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - *instrumentation_library, void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", nostd::string_view unit = "") - : name_(name), - instrumentation_library_{instrumentation_library}, - callback_(callback), - description_(description), - unit_(unit) + : name_(name), callback_(callback), description_(description), unit_(unit) {} protected: std::string name_; - const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - *instrumentation_library_; void (*callback_)(opentelemetry::metrics::ObserverResult &); std::string description_; std::string unit_; @@ -45,12 +36,10 @@ class LongObservableCounter : public opentelemetry::metrics::ObservableCounter &), nostd::string_view description = "", nostd::string_view unit = "") - : Asynchronous(name, instrumentation_library, callback, description, unit) + : Asynchronous(name, callback, description, unit) {} }; @@ -60,12 +49,10 @@ class DoubleObservableCounter : public opentelemetry::metrics::ObservableCounter { public: DoubleObservableCounter(nostd::string_view name, - const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - *instrumentation_library, void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", nostd::string_view unit = "") - : Asynchronous(name, instrumentation_library, callback, description, unit) + : Asynchronous(name, callback, description, unit) {} }; @@ -75,12 +62,10 @@ class LongObservableGauge : public opentelemetry::metrics::ObservableGauge { public: LongObservableGauge(nostd::string_view name, - const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - *instrumentation_library, void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", nostd::string_view unit = "") - : Asynchronous(name, instrumentation_library, callback, description, unit) + : Asynchronous(name, callback, description, unit) {} }; @@ -90,12 +75,10 @@ class DoubleObservableGauge : public opentelemetry::metrics::ObservableGauge &), nostd::string_view description = "", nostd::string_view unit = "") - : Asynchronous(name, instrumentation_library, callback, description, unit) + : Asynchronous(name, callback, description, unit) {} }; @@ -104,14 +87,11 @@ class LongObservableUpDownCounter : public opentelemetry::metrics::ObservableUpD public Asynchronous { public: - LongObservableUpDownCounter( - nostd::string_view name, - const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - *instrumentation_library, - void (*callback)(opentelemetry::metrics::ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") - : Asynchronous(name, instrumentation_library, callback, description, unit) + LongObservableUpDownCounter(nostd::string_view name, + void (*callback)(opentelemetry::metrics::ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") + : Asynchronous(name, callback, description, unit) {} }; @@ -121,14 +101,11 @@ class DoubleObservableUpDownCounter public Asynchronous { public: - DoubleObservableUpDownCounter( - nostd::string_view name, - const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary - *instrumentation_library, - void (*callback)(opentelemetry::metrics::ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") - : Asynchronous(name, instrumentation_library, callback, description, unit) + DoubleObservableUpDownCounter(nostd::string_view name, + void (*callback)(opentelemetry::metrics::ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") + : Asynchronous(name, callback, description, unit) {} }; diff --git a/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h b/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h index 7c9ee57755..d3b38759ad 100644 --- a/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h +++ b/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h @@ -3,13 +3,33 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/metrics/data/metric_data.h" +# include "opentelemetry/sdk/resource/resource.h" + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { namespace metrics { +/** + * Metric Data to be exported along with resources and + * Instrumentation library. + */ +struct InstrumentationInfoMetrics +{ + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + *instrumentation_library_; + std::vector metric_data_; +}; + +struct ResourceMetrics +{ + const opentelemetry::sdk::resource::Resource *resource_; + std::vector instrumentation_info_metric_data_; +}; + /** * MetricProducer is the interface that is used to make metric data available to the * OpenTelemetry exporters. Implementations should be stateful, in that each call to @@ -27,7 +47,8 @@ class MetricProducer * * @return a status of completion of method. */ - virtual bool Collect(nostd::function_ref callback) noexcept = 0; + virtual bool Collect( + nostd::function_ref callback) noexcept = 0; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/meter.h b/sdk/include/opentelemetry/sdk/metrics/meter.h index c9e02918a0..4a6ea26aeb 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter.h @@ -102,10 +102,9 @@ class Meter final : public opentelemetry::metrics::Meter const sdk::instrumentationlibrary::InstrumentationLibrary *GetInstrumentationLibrary() const noexcept; - /** collect metrics across all the meters **/ - bool Collect(CollectorHandle *collector, - opentelemetry::common::SystemTimestamp collect_ts, - nostd::function_ref callback) noexcept; + /** collect metrics across all the instruments configured for the meter **/ + std::vector Collect(CollectorHandle *collector, + opentelemetry::common::SystemTimestamp collect_ts) noexcept; private: // order of declaration is important here - instrumentation library should destroy after diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h index 2488edd7ed..b6b5acf3a9 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h @@ -32,7 +32,7 @@ class MetricExporter * concurrently for the same exporter instance. * @param data metrics data */ - virtual opentelemetry::sdk::common::ExportResult Export(const MetricData &data) noexcept = 0; + virtual opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &data) noexcept = 0; /** * Force flush the exporter. diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h index 7cf449e1e3..94924315f8 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h @@ -6,6 +6,7 @@ # include "opentelemetry/common/spin_lock_mutex.h" # include "opentelemetry/sdk/common/global_log_handler.h" # include "opentelemetry/sdk/metrics/data/metric_data.h" +# include "opentelemetry/sdk/metrics/export/metric_producer.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/version.h" @@ -18,7 +19,6 @@ namespace sdk namespace metrics { -class MetricProducer; /** * MetricReader defines the interface to collect metrics from SDK */ @@ -34,7 +34,7 @@ class MetricReader * Collect the metrics from SDK. * @return return the status of the operation. */ - bool Collect(nostd::function_ref callback) noexcept; + bool Collect(nostd::function_ref callback) noexcept; AggregationTemporality GetAggregationTemporality() const noexcept; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h index 31ab70c5b8..cfbf521538 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h @@ -4,16 +4,15 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/common/attributemap_hash.h" -# include "opentelemetry/sdk/metrics/instruments.h" - # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/observer_result.h" # include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" # include "opentelemetry/sdk/metrics/state/metric_collector.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" # include -# include "opentelemetry/sdk/metrics/observer_result.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -40,7 +39,7 @@ class AsyncMetricStorage : public MetricStorage nostd::span> collectors, opentelemetry::common::SystemTimestamp sdk_start_ts, opentelemetry::common::SystemTimestamp collection_ts, - nostd::function_ref metric_collection_callback) noexcept override + nostd::function_ref metric_collection_callback) noexcept override { opentelemetry::sdk::metrics::ObserverResult ob_res(attributes_processor_); @@ -57,7 +56,7 @@ class AsyncMetricStorage : public MetricStorage // TBD -> read aggregation from hashmap, and perform metric collection MetricData metric_data; - if (metric_collection_callback(metric_data)) + if (metric_collection_callback(std::move(metric_data))) { return true; } diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h index 51c9cf6eff..20372f5209 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h @@ -41,7 +41,7 @@ class MetricCollector : public MetricProducer, public CollectorHandle * * @return a status of completion of method. */ - bool Collect(nostd::function_ref callback) noexcept override; + bool Collect(nostd::function_ref callback) noexcept override; bool ForceFlush(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h index 20f7d56140..e0ba55cbfe 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h @@ -25,7 +25,7 @@ class MetricStorage nostd::span> collectors, opentelemetry::common::SystemTimestamp sdk_start_ts, opentelemetry::common::SystemTimestamp collection_ts, - nostd::function_ref callback) noexcept = 0; + nostd::function_ref callback) noexcept = 0; }; class WritableMetricStorage @@ -54,14 +54,10 @@ class NoopMetricStorage : public MetricStorage nostd::span> collectors, opentelemetry::common::SystemTimestamp sdk_start_ts, opentelemetry::common::SystemTimestamp collection_ts, - nostd::function_ref callback) noexcept override + nostd::function_ref callback) noexcept override { MetricData metric_data; - if (callback(metric_data)) - { - return true; - } - return false; + return callback(std::move(metric_data)); } }; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h index 8269d2fd3c..c16f33ede2 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -106,7 +106,7 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage nostd::span> collectors, opentelemetry::common::SystemTimestamp sdk_start_ts, opentelemetry::common::SystemTimestamp collection_ts, - nostd::function_ref callback) noexcept override; + nostd::function_ref callback) noexcept override; private: InstrumentDescriptor instrument_descriptor_; diff --git a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc index e9a91a9e06..f11f84544f 100644 --- a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc +++ b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc @@ -51,7 +51,7 @@ void PeriodicExportingMetricReader::DoBackgroundWork() std::atomic cancel_export_for_timeout{false}; auto start = std::chrono::steady_clock::now(); auto future_receive = std::async(std::launch::async, [this, &cancel_export_for_timeout] { - Collect([this, &cancel_export_for_timeout](MetricData data) { + Collect([this, &cancel_export_for_timeout](ResourceMetrics &metric_data) { if (cancel_export_for_timeout) { OTEL_INTERNAL_LOG_ERROR( @@ -59,7 +59,7 @@ void PeriodicExportingMetricReader::DoBackgroundWork() << export_timeout_millis_.count() << " ms, and timed out"); return false; } - this->exporter_->Export(data); + this->exporter_->Export(metric_data); return true; }); }); diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index fb74d55eb4..e7ca822b6d 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -64,7 +64,7 @@ nostd::shared_ptr> Meter::CreateLongObservableC nostd::string_view unit) noexcept { return nostd::shared_ptr>{ - new LongObservableCounter(name, GetInstrumentationLibrary(), callback, description, unit)}; + new LongObservableCounter(name, callback, description, unit)}; } nostd::shared_ptr> Meter::CreateDoubleObservableCounter( @@ -74,7 +74,7 @@ nostd::shared_ptr> Meter::CreateDoubleObserva nostd::string_view unit) noexcept { return nostd::shared_ptr>{ - new DoubleObservableCounter(name, GetInstrumentationLibrary(), callback, description, unit)}; + new DoubleObservableCounter(name, callback, description, unit)}; } nostd::shared_ptr> Meter::CreateLongHistogram( @@ -112,7 +112,7 @@ nostd::shared_ptr> Meter::CreateLongObservableGau nostd::string_view unit) noexcept { return nostd::shared_ptr>{ - new LongObservableGauge(name, GetInstrumentationLibrary(), callback, description, unit)}; + new LongObservableGauge(name, callback, description, unit)}; } nostd::shared_ptr> Meter::CreateDoubleObservableGauge( @@ -122,7 +122,7 @@ nostd::shared_ptr> Meter::CreateDoubleObservabl nostd::string_view unit) noexcept { return nostd::shared_ptr>{ - new DoubleObservableGauge(name, GetInstrumentationLibrary(), callback, description, unit)}; + new DoubleObservableGauge(name, callback, description, unit)}; } nostd::shared_ptr> Meter::CreateLongUpDownCounter( @@ -159,8 +159,8 @@ nostd::shared_ptr> Meter::CreateLongObser nostd::string_view description, nostd::string_view unit) noexcept { - return nostd::shared_ptr>{new LongObservableUpDownCounter( - name, GetInstrumentationLibrary(), callback, description, unit)}; + return nostd::shared_ptr>{ + new LongObservableUpDownCounter(name, callback, description, unit)}; } nostd::shared_ptr> @@ -170,8 +170,7 @@ Meter::CreateDoubleObservableUpDownCounter(nostd::string_view name, nostd::string_view unit) noexcept { return nostd::shared_ptr>{ - new DoubleObservableUpDownCounter(name, GetInstrumentationLibrary(), callback, description, - unit)}; + new DoubleObservableUpDownCounter(name, callback, description, unit)}; } const sdk::instrumentationlibrary::InstrumentationLibrary *Meter::GetInstrumentationLibrary() @@ -211,22 +210,20 @@ std::unique_ptr Meter::RegisterMetricStorage( } /** collect metrics across all the meters **/ -bool Meter::Collect(CollectorHandle *collector, - opentelemetry::common::SystemTimestamp collect_ts, - nostd::function_ref callback) noexcept +std::vector Meter::Collect(CollectorHandle *collector, + opentelemetry::common::SystemTimestamp collect_ts) noexcept { - std::vector data; + std::vector metric_data_list; for (auto &metric_storage : storage_registry_) { - // TBD - this needs to be asynchronous metric_storage.second->Collect(collector, meter_context_->GetCollectors(), meter_context_->GetSDKStartTime(), collect_ts, - [&callback](MetricData &metric_data) { - callback(metric_data); + [&metric_data_list](MetricData metric_data) { + metric_data_list.push_back(metric_data); return true; }); } - return true; + return metric_data_list; } } // namespace metrics diff --git a/sdk/src/metrics/metric_reader.cc b/sdk/src/metrics/metric_reader.cc index abf73d766a..eafcc60e7e 100644 --- a/sdk/src/metrics/metric_reader.cc +++ b/sdk/src/metrics/metric_reader.cc @@ -28,7 +28,8 @@ AggregationTemporality MetricReader::GetAggregationTemporality() const noexcept return aggregation_temporality_; } -bool MetricReader::Collect(nostd::function_ref callback) noexcept +bool MetricReader::Collect( + nostd::function_ref callback) noexcept { if (!metric_producer_) { diff --git a/sdk/src/metrics/state/metric_collector.cc b/sdk/src/metrics/state/metric_collector.cc index cd3b8eb6ca..6cae7bf12c 100644 --- a/sdk/src/metrics/state/metric_collector.cc +++ b/sdk/src/metrics/state/metric_collector.cc @@ -29,13 +29,20 @@ AggregationTemporality MetricCollector::GetAggregationTemporality() noexcept return metric_reader_->GetAggregationTemporality(); } -bool MetricCollector::Collect(nostd::function_ref callback) noexcept +bool MetricCollector::Collect( + nostd::function_ref callback) noexcept { + ResourceMetrics resource_metrics; for (auto &meter : meter_context_->GetMeters()) { auto collection_ts = std::chrono::system_clock::now(); - meter->Collect(this, collection_ts, callback); + InstrumentationInfoMetrics instrumentation_info_metrics; + instrumentation_info_metrics.metric_data_ = meter->Collect(this, collection_ts); + instrumentation_info_metrics.instrumentation_library_ = meter->GetInstrumentationLibrary(); + resource_metrics.instrumentation_info_metric_data_.push_back(instrumentation_info_metrics); } + resource_metrics.resource_ = &meter_context_->GetResource(); + callback(resource_metrics); return true; } diff --git a/sdk/src/metrics/state/sync_metric_storage.cc b/sdk/src/metrics/state/sync_metric_storage.cc index 5c14f8bbc3..f42de82b4b 100644 --- a/sdk/src/metrics/state/sync_metric_storage.cc +++ b/sdk/src/metrics/state/sync_metric_storage.cc @@ -15,7 +15,7 @@ bool SyncMetricStorage::Collect(CollectorHandle *collector, nostd::span> collectors, opentelemetry::common::SystemTimestamp sdk_start_ts, opentelemetry::common::SystemTimestamp collection_ts, - nostd::function_ref callback) noexcept + nostd::function_ref callback) noexcept { opentelemetry::common::SystemTimestamp last_collection_ts = sdk_start_ts; auto aggregation_temporarily = collector->GetAggregationTemporality(); diff --git a/sdk/test/metrics/async_instruments_test.cc b/sdk/test/metrics/async_instruments_test.cc index ad3a81b031..ff9504f78c 100644 --- a/sdk/test/metrics/async_instruments_test.cc +++ b/sdk/test/metrics/async_instruments_test.cc @@ -3,16 +3,12 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/async_instruments.h" -# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include using namespace opentelemetry; -using namespace opentelemetry::sdk::instrumentationlibrary; using namespace opentelemetry::sdk::metrics; -auto instrumentation_library = InstrumentationLibrary::Create("opentelemetry-cpp", "0.1.0"); - using M = std::map; void asyc_generate_measurements_long(opentelemetry::metrics::ObserverResult &observer) {} @@ -22,44 +18,43 @@ void asyc_generate_measurements_double(opentelemetry::metrics::ObserverResult &observer) {}; - EXPECT_NO_THROW(LongObservableCounter counter("long_counter", instrumentation_library.get(), - asyc_generate_meas_long, "description", "1")); + EXPECT_NO_THROW( + LongObservableCounter counter("long_counter", asyc_generate_meas_long, "description", "1")); } TEST(AsyncInstruments, DoubleObservableCounter) { auto asyc_generate_meas_double = [](opentelemetry::metrics::ObserverResult &observer) {}; - EXPECT_NO_THROW(DoubleObservableCounter counter("long_counter", instrumentation_library.get(), - asyc_generate_meas_double, "description", "1")); + EXPECT_NO_THROW(DoubleObservableCounter counter("long_counter", asyc_generate_meas_double, + "description", "1")); } TEST(AsyncInstruments, LongObservableGauge) { auto asyc_generate_meas_long = [](opentelemetry::metrics::ObserverResult &observer) {}; - EXPECT_NO_THROW(LongObservableGauge counter("long_counter", instrumentation_library.get(), - asyc_generate_meas_long, "description", "1")); + EXPECT_NO_THROW( + LongObservableGauge counter("long_counter", asyc_generate_meas_long, "description", "1")); } TEST(AsyncInstruments, DoubleObservableGauge) { auto asyc_generate_meas_double = [](opentelemetry::metrics::ObserverResult &observer) {}; - EXPECT_NO_THROW(DoubleObservableGauge counter("long_counter", instrumentation_library.get(), - asyc_generate_meas_double, "description", "1")); + EXPECT_NO_THROW( + DoubleObservableGauge counter("long_counter", asyc_generate_meas_double, "description", "1")); } TEST(AsyncInstruments, LongObservableUpDownCounter) { auto asyc_generate_meas_long = [](opentelemetry::metrics::ObserverResult &observer) {}; - EXPECT_NO_THROW(LongObservableUpDownCounter counter("long_counter", instrumentation_library.get(), - asyc_generate_meas_long, "description", "1")); + EXPECT_NO_THROW(LongObservableUpDownCounter counter("long_counter", asyc_generate_meas_long, + "description", "1")); } TEST(AsyncInstruments, DoubleObservableUpDownCounter) { auto asyc_generate_meas_double = [](opentelemetry::metrics::ObserverResult &observer) {}; - EXPECT_NO_THROW( - DoubleObservableUpDownCounter counter("long_counter", instrumentation_library.get(), - asyc_generate_meas_double, "description", "1")); + EXPECT_NO_THROW(DoubleObservableUpDownCounter counter("long_counter", asyc_generate_meas_double, + "description", "1")); } #endif diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index f7c9914e3c..512e24472c 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -38,7 +38,7 @@ void measurement_fetch(opentelemetry::metrics::ObserverResult &observer_re TEST(AsyncMetricStorageTest, BasicTests) { - auto metric_callback = [](MetricData &metric_data) { return true; }; + auto metric_callback = [](MetricData &&metric_data) { return true; }; InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, InstrumentValueType::kLong}; diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index ec0a39b523..3c059cc44c 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -18,7 +18,7 @@ class MockMetricExporter : public MetricExporter public: MockMetricExporter() = default; - opentelemetry::sdk::common::ExportResult Export(const MetricData &records) noexcept override + opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &records) noexcept override { return opentelemetry::sdk::common::ExportResult::kSuccess; } diff --git a/sdk/test/metrics/metric_reader_test.cc b/sdk/test/metrics/metric_reader_test.cc index 68a3fcc5f5..61a4364934 100644 --- a/sdk/test/metrics/metric_reader_test.cc +++ b/sdk/test/metrics/metric_reader_test.cc @@ -35,6 +35,6 @@ TEST(MetricReaderTest, BasicTests) std::shared_ptr meter_context2(new MeterContext(std::move(exporters))); MetricProducer *metric_producer = new MetricCollector(std::move(meter_context2), std::move(metric_reader2)); - EXPECT_NO_THROW(metric_producer->Collect([](MetricData data) { return true; })); + EXPECT_NO_THROW(metric_producer->Collect([](ResourceMetrics &metric_data) { return true; })); } #endif diff --git a/sdk/test/metrics/periodic_exporting_metric_reader_test.cc b/sdk/test/metrics/periodic_exporting_metric_reader_test.cc index f13fbb0e04..5219f31100 100644 --- a/sdk/test/metrics/periodic_exporting_metric_reader_test.cc +++ b/sdk/test/metrics/periodic_exporting_metric_reader_test.cc @@ -16,7 +16,7 @@ using namespace opentelemetry::sdk::metrics; class MockPushMetricExporter : public MetricExporter { public: - opentelemetry::sdk::common::ExportResult Export(const MetricData &record) noexcept override + opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &record) noexcept override { records_.push_back(record); return opentelemetry::sdk::common::ExportResult::kSuccess; @@ -36,7 +36,7 @@ class MockPushMetricExporter : public MetricExporter size_t GetDataCount() { return records_.size(); } private: - std::vector records_; + std::vector records_; }; class MockMetricProducer : public MetricProducer @@ -46,11 +46,11 @@ class MockMetricProducer : public MetricProducer : sleep_ms_{sleep_ms}, data_sent_size_(0) {} - bool Collect(nostd::function_ref callback) noexcept override + bool Collect(nostd::function_ref callback) noexcept override { std::this_thread::sleep_for(sleep_ms_); data_sent_size_++; - MetricData data; + ResourceMetrics data; callback(data); return true; } From 237a0b26372b8a75ae941272b78bc07f12692c7b Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Mon, 4 Apr 2022 20:41:02 -0700 Subject: [PATCH 15/69] Excempt should be applied on issue instead of PR (#1316) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 53ebe3259b..e55a93d08d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,4 +13,4 @@ jobs: close-issue-message: 'Closed as inactive. Feel free to reopen if this is still an issue.' days-before-issue-stale: 60 days-before-issue-close: 7 - exempt-pr-labels: 'do-not-stale' + exempt-issue-labels: 'do-not-stale' From fd338cc9f96cd2ad2af7b3bed496c10c22098582 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Apr 2022 23:05:14 -0700 Subject: [PATCH 16/69] Bump codecov/codecov-action from 2.1.0 to 3 (#1318) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c29ee3084f..3b0af15acb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -375,7 +375,7 @@ jobs: - name: run tests and generate report run: ./ci/do_ci.sh code.coverage - name: upload report - uses: codecov/codecov-action@v2.1.0 + uses: codecov/codecov-action@v3 with: file: /home/runner/build/coverage.info From 74ec691e4a73c3160f2bb2aaf0a9626fb282beec Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Thu, 7 Apr 2022 14:06:59 +0800 Subject: [PATCH 17/69] Move public definitions into `opentelemetry_api`. (#1314) Signed-off-by: owent --- CMakeLists.txt | 46 +--------------------------------------------- api/CMakeLists.txt | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5573d156e8..09c21fd678 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,24 +125,11 @@ if(NOT DEFINED CMAKE_CXX_STANDARD) endif() endif() -if(WITH_ABSEIL) - find_package(absl CONFIG REQUIRED) - - set(CORE_RUNTIME_LIBS absl::bad_variant_access absl::any absl::base - absl::bits absl::city) - - # target_link_libraries(main PRIVATE absl::any absl::base absl::bits - # absl::city) -endif() - if(WITH_STL) # These definitions are needed for test projects that do not link against # opentelemetry-api library directly. We ensure that variant implementation # (absl::variant or std::variant) in variant unit test code is consistent with - # the global project build definitions. - add_definitions(-DHAVE_CPP_STDLIB) - - # Optimize for speed to reduce the hops + # the global project build definitions. Optimize for speed to reduce the hops if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") if(CMAKE_BUILD_TYPE MATCHES Debug) # Turn off optimizations for DEBUG @@ -157,20 +144,6 @@ if(WITH_STL) endif() endif() -if(WITH_GSL) - add_definitions(-DHAVE_GSL) - - # Guidelines Support Library path. Used if we are not on not get C++20. - # - find_package(Microsoft.GSL QUIET) - if(TARGET Microsoft.GSL::GSL) - list(APPEND CORE_RUNTIME_LIBS Microsoft.GSL::GSL) - else() - set(GSL_DIR third_party/ms-gsl) - include_directories(${GSL_DIR}/include) - endif() -endif() - option(WITH_OTLP "Whether to include the OpenTelemetry Protocol in the SDK" OFF) option(WITH_ZIPKIN "Whether to include the Zipkin exporter in the SDK" OFF) @@ -190,12 +163,7 @@ option(BUILD_TESTING "Whether to enable tests" ON) option(BUILD_W3CTRACECONTEXT_TEST "Whether to build w3c trace context" OFF) -if(WITH_NO_GENENV) - add_definitions(-DNO_GETENV) -endif() - if(WIN32) - add_definitions(-DNOMINMAX) if(BUILD_TESTING) if(MSVC) # GTest bug: https://github.com/google/googletest/issues/860 @@ -203,9 +171,6 @@ if(WIN32) endif() endif() option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON) - if(WITH_ETW) - add_definitions(-DHAVE_MSGPACK) - endif(WITH_ETW) endif(WIN32) option( @@ -215,17 +180,8 @@ option( option(WITH_EXAMPLES "Whether to build examples" ON) option(WITH_METRICS_PREVIEW "Whether to build metrics preview" OFF) - -if(WITH_METRICS_PREVIEW) - add_definitions(-DENABLE_METRICS_PREVIEW) -endif() - option(WITH_LOGS_PREVIEW "Whether to build logs preview" OFF) -if(WITH_LOGS_PREVIEW) - add_definitions(-DENABLE_LOGS_PREVIEW) -endif() - find_package(Threads) function(install_windows_deps) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index adea77ca2d..375e8458e8 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -42,7 +42,14 @@ if(BUILD_TESTING) endif() if(WITH_ABSEIL) + + find_package(absl CONFIG REQUIRED) + target_compile_definitions(opentelemetry_api INTERFACE HAVE_ABSEIL) + target_link_libraries( + opentelemetry_api INTERFACE absl::bad_variant_access absl::any absl::base + absl::bits absl::city) + endif() if(WITH_STL) @@ -52,6 +59,21 @@ else() message("Building with nostd types...") endif() +if(WITH_GSL) + target_compile_definitions(opentelemetry_api INTERFACE HAVE_GSL) + + # Guidelines Support Library path. Used if we are not on not get C++20. + # + find_package(Microsoft.GSL QUIET) + if(TARGET Microsoft.GSL::GSL) + target_link_libraries(opentelemetry_api INTERFACE Microsoft.GSL::GSL) + else() + set(GSL_DIR third_party/ms-gsl) + target_include_directories( + opentelemetry_api INTERFACE "$") + endif() +endif() + if(WITH_METRICS_PREVIEW) target_compile_definitions(opentelemetry_api INTERFACE ENABLE_METRICS_PREVIEW) endif() @@ -60,6 +82,13 @@ if(WITH_LOGS_PREVIEW) target_compile_definitions(opentelemetry_api INTERFACE ENABLE_LOGS_PREVIEW) endif() -if(CORE_RUNTIME_LIBS) - target_link_libraries(opentelemetry_api INTERFACE ${CORE_RUNTIME_LIBS}) +if(WITH_NO_GENENV) + target_compile_definitions(opentelemetry_api INTERFACE NO_GETENV) +endif() + +if(WIN32) + target_compile_definitions(opentelemetry_api INTERFACE NOMINMAX) + if(WITH_ETW) + target_compile_definitions(opentelemetry_api INTERFACE HAVE_MSGPACK) + endif() endif() From 6b87300b5a354cf377f164eecd914e80171a69e6 Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Thu, 7 Apr 2022 23:56:44 +0800 Subject: [PATCH 18/69] Add building test without RTTI (#1294) --- .github/workflows/ci.yml | 22 +++ api/include/opentelemetry/common/macros.h | 16 +++ ci/README.md | 2 + ci/do_ci.sh | 12 +- examples/multi_processor/main.cc | 12 +- .../opentelemetry/exporters/etw/etw_logger.h | 2 +- .../opentelemetry/exporters/etw/etw_tracer.h | 4 +- .../opentelemetry/exporters/etw/utils.h | 17 +-- .../memory/in_memory_span_exporter.h | 2 +- .../opentelemetry/sdk/_metrics/controller.h | 6 + .../sdk/_metrics/sync_instruments.h | 14 ++ .../sdk/_metrics/ungrouped_processor.h | 56 ++++++++ sdk/src/_metrics/meter.cc | 14 +- sdk/test/_metrics/metric_instrument_test.cc | 126 ++++++++++-------- sdk/test/metrics/meter_provider_sdk_test.cc | 2 +- sdk/test/trace/tracer_provider_test.cc | 6 +- sdk/test/trace/tracer_test.cc | 4 +- 17 files changed, 226 insertions(+), 91 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b0af15acb..7030c719d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -216,6 +216,28 @@ jobs: - name: run tests run: ./ci/do_ci.sh bazel.noexcept + bazel_nortti: + name: Bazel nortti + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: Mount Bazel Cache + uses: actions/cache@v3 + env: + cache-name: bazel_cache + with: + path: /home/runner/.cache/bazel + key: bazel_nortti + - name: setup + run: | + sudo ./ci/setup_thrift.sh dependencies_only + sudo ./ci/setup_ci_environment.sh + sudo ./ci/install_bazelisk.sh + - name: run tests + run: ./ci/do_ci.sh bazel.nortti + bazel_asan: name: Bazel asan config runs-on: ubuntu-latest diff --git a/api/include/opentelemetry/common/macros.h b/api/include/opentelemetry/common/macros.h index 8c2b6bd175..982e368ce3 100644 --- a/api/include/opentelemetry/common/macros.h +++ b/api/include/opentelemetry/common/macros.h @@ -24,3 +24,19 @@ #else # define OPENTELEMETRY_MAYBE_UNUSED #endif + +#ifndef OPENTELEMETRY_RTTI_ENABLED +# if defined(__clang__) +# if __has_feature(cxx_rtti) +# define OPENTELEMETRY_RTTI_ENABLED +# endif +# elif defined(__GNUG__) +# if defined(__GXX_RTTI) +# define OPENTELEMETRY_RTTI_ENABLED +# endif +# elif defined(_MSC_VER) +# if defined(_CPPRTTI) +# define OPENTELEMETRY_RTTI_ENABLED +# endif +# endif +#endif diff --git a/ci/README.md b/ci/README.md index d315965962..14a6107eb8 100644 --- a/ci/README.md +++ b/ci/README.md @@ -12,6 +12,8 @@ CI tests can be run on docker by invoking the script `./ci/run_docker.sh * `bazel.legacy.test`: build bazel targets and run tests for the targets meant to work with older compilers. * `bazel.noexcept`: build bazel targets and run tests with exceptions disabled. +* `bazel.nortti`: build bazel targets and run tests with runtime type + identification disabled. * `bazel.asan`: build bazel targets and run tests with AddressSanitizer. * `bazel.tsan`: build bazel targets and run tests with ThreadSanitizer. * `bazel.valgrind`: build bazel targets and run tests under the valgrind memory diff --git a/ci/do_ci.sh b/ci/do_ci.sh index f9fc8ed215..008e983842 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -59,7 +59,11 @@ mkdir -p "${BUILD_DIR}" [ -z "${PLUGIN_DIR}" ] && export PLUGIN_DIR=$HOME/plugin mkdir -p "${PLUGIN_DIR}" -BAZEL_OPTIONS="--copt=-DENABLE_METRICS_PREVIEW --copt=-DENABLE_LOGS_PREVIEW --copt=-DENABLE_TEST" +BAZEL_OPTIONS="--copt=-DENABLE_LOGS_PREVIEW --copt=-DENABLE_TEST" +# Previous legacy metrics use virtual drive, which can not be used without RTTI +if [[ "$1" != "bazel.nortti" ]]; then + BAZEL_OPTIONS="$BAZEL_OPTIONS --copt=-DENABLE_METRICS_PREVIEW" +fi BAZEL_TEST_OPTIONS="$BAZEL_OPTIONS --test_output=errors" # https://github.com/bazelbuild/bazel/issues/4341 @@ -221,6 +225,12 @@ elif [[ "$1" == "bazel.noexcept" ]]; then bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... exit 0 +elif [[ "$1" == "bazel.nortti" ]]; then + # there are some exceptions and error handling code from the Prometheus and Jaeger Clients + # that make this test always fail. ignore Prometheus and Jaeger exporters in the noexcept here. + bazel $BAZEL_STARTUP_OPTIONS build --cxxopt=-fno-rtti --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... + bazel $BAZEL_STARTUP_OPTIONS test --cxxopt=-fno-rtti --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... + exit 0 elif [[ "$1" == "bazel.asan" ]]; then bazel $BAZEL_STARTUP_OPTIONS test --config=asan $BAZEL_TEST_OPTIONS //... exit 0 diff --git a/examples/multi_processor/main.cc b/examples/multi_processor/main.cc index f57da5e228..2b722b6688 100644 --- a/examples/multi_processor/main.cc +++ b/examples/multi_processor/main.cc @@ -20,21 +20,19 @@ namespace trace_api = opentelemetry::trace; namespace trace_sdk = opentelemetry::sdk::trace; namespace nostd = opentelemetry::nostd; -InMemorySpanExporter *memory_span_exporter; - namespace { -void initTracer() +InMemorySpanExporter *initTracer() { auto exporter1 = std::unique_ptr( new opentelemetry::exporter::trace::OStreamSpanExporter); auto processor1 = std::unique_ptr( new trace_sdk::SimpleSpanProcessor(std::move(exporter1))); - auto exporter2 = std::unique_ptr(new InMemorySpanExporter()); + InMemorySpanExporter *memory_span_exporter = new InMemorySpanExporter(); + auto exporter2 = std::unique_ptr(memory_span_exporter); // fetch the exporter for dumping data later - memory_span_exporter = dynamic_cast(exporter2.get()); auto processor2 = std::unique_ptr( new trace_sdk::SimpleSpanProcessor(std::move(exporter2))); @@ -44,6 +42,8 @@ void initTracer() provider->AddProcessor(std::move(processor2)); // Set the global trace provider trace_api::Provider::SetTracerProvider(std::move(provider)); + + return memory_span_exporter; } void dumpSpans(std::vector> &spans) @@ -81,7 +81,7 @@ void dumpSpans(std::vector> &spans) int main() { // Removing this line will leave the default noop TracerProvider in place. - initTracer(); + InMemorySpanExporter *memory_span_exporter = initTracer(); foo_library(); auto memory_spans = memory_span_exporter->GetData()->GetSpans(); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h index 6f3a394b0d..84f6b6970f 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h @@ -110,7 +110,7 @@ class Logger : public opentelemetry::logs::Logger common::SystemTimestamp timestamp) noexcept override { -# ifdef RTTI_ENABLED +# ifdef OPENTELEMETRY_RTTI_ENABLED common::KeyValueIterable &attribs = const_cast(attributes); Properties *evt = dynamic_cast(&attribs); // Properties *res = dynamic_cast(&resr); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index a946e70a6f..65fe2770f2 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -377,7 +377,7 @@ class Tracer : public opentelemetry::trace::Tracer const opentelemetry::trace::SpanContextKeyValueIterable &links, const opentelemetry::trace::StartSpanOptions &options = {}) noexcept override { -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED common::KeyValueIterable &attribs = const_cast(attributes); Properties *evt = dynamic_cast(&attribs); if (evt != nullptr) @@ -531,7 +531,7 @@ class Tracer : public opentelemetry::trace::Tracer common::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept { -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED common::KeyValueIterable &attribs = const_cast(attributes); Properties *evt = dynamic_cast(&attribs); if (evt != nullptr) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index f1f2898954..8b0a015821 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -12,6 +12,7 @@ #include #include +#include "opentelemetry/common/macros.h" #include "opentelemetry/exporters/etw/uuid.h" #include "opentelemetry/version.h" @@ -25,22 +26,6 @@ # pragma comment(lib, "Ole32.Lib") #endif -#ifndef RTTI_ENABLED -# if defined(__clang__) -# if __has_feature(cxx_rtti) -# define RTTI_ENABLED -# endif -# elif defined(__GNUG__) -# if defined(__GXX_RTTI) -# define RTTI_ENABLED -# endif -# elif defined(_MSC_VER) -# if defined(_CPPRTTI) -# define RTTI_ENABLED -# endif -# endif -#endif - OPENTELEMETRY_BEGIN_NAMESPACE namespace utils diff --git a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h index 3e47ccb177..28b7bc34e8 100644 --- a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h +++ b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_exporter.h @@ -54,7 +54,7 @@ class InMemorySpanExporter final : public opentelemetry::sdk::trace::SpanExporte for (auto &recordable : recordables) { auto span = std::unique_ptr( - dynamic_cast(recordable.release())); + static_cast(recordable.release())); if (span != nullptr) { data_->Add(std::move(span)); diff --git a/sdk/include/opentelemetry/sdk/_metrics/controller.h b/sdk/include/opentelemetry/sdk/_metrics/controller.h index 9d80787bcd..66a57a2efa 100644 --- a/sdk/include/opentelemetry/sdk/_metrics/controller.h +++ b/sdk/include/opentelemetry/sdk/_metrics/controller.h @@ -9,7 +9,9 @@ # include # include # include + # include "opentelemetry/_metrics/instrument.h" +# include "opentelemetry/common/macros.h" # include "opentelemetry/nostd/unique_ptr.h" # include "opentelemetry/sdk/_metrics/exporter.h" # include "opentelemetry/sdk/_metrics/meter.h" @@ -120,7 +122,11 @@ class PushController void tick() { this->mu_.lock(); +# ifdef OPENTELEMETRY_RTTI_ENABLED std::vector collected = dynamic_cast(meter_.get())->Collect(); +# else + std::vector collected = static_cast(meter_.get())->Collect(); +# endif for (const auto &rec : collected) { processor_->process(rec); diff --git a/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h b/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h index 46274571af..80d9b6092d 100644 --- a/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h +++ b/sdk/include/opentelemetry/sdk/_metrics/sync_instruments.h @@ -9,7 +9,9 @@ # include # include # include + # include "opentelemetry/_metrics/sync_instruments.h" +# include "opentelemetry/common/macros.h" # include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h" # include "opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h" # include "opentelemetry/sdk/_metrics/instrument.h" @@ -156,7 +158,11 @@ class Counter final : public SynchronousInstrument, public opentelemetry::met { toDelete.push_back(x.first); } +# ifdef OPENTELEMETRY_RTTI_ENABLED auto agg_ptr = dynamic_cast *>(x.second.get())->GetAggregator(); +# else + auto agg_ptr = static_cast *>(x.second.get())->GetAggregator(); +# endif if (agg_ptr->is_updated()) { agg_ptr->checkpoint(); @@ -287,7 +293,11 @@ class UpDownCounter final : public SynchronousInstrument, { toDelete.push_back(x.first); } +# ifdef OPENTELEMETRY_RTTI_ENABLED auto agg_ptr = dynamic_cast *>(x.second.get())->GetAggregator(); +# else + auto agg_ptr = static_cast *>(x.second.get())->GetAggregator(); +# endif if (agg_ptr->is_updated()) { agg_ptr->checkpoint(); @@ -417,7 +427,11 @@ class ValueRecorder final : public SynchronousInstrument, { toDelete.push_back(x.first); } +# ifdef OPENTELEMETRY_RTTI_ENABLED auto agg_ptr = dynamic_cast *>(x.second.get())->GetAggregator(); +# else + auto agg_ptr = static_cast *>(x.second.get())->GetAggregator(); +# endif if (agg_ptr->is_updated()) { agg_ptr->checkpoint(); diff --git a/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h b/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h index 5894144c7f..cc13ae52b6 100644 --- a/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h +++ b/sdk/include/opentelemetry/sdk/_metrics/ungrouped_processor.h @@ -5,6 +5,8 @@ #ifdef ENABLE_METRICS_PREVIEW # include + +# include "opentelemetry/common/macros.h" # include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h" # include "opentelemetry/sdk/_metrics/aggregator/exact_aggregator.h" # include "opentelemetry/sdk/_metrics/aggregator/gauge_aggregator.h" @@ -216,12 +218,19 @@ class UngroupedMetricsProcessor : public MetricsProcessor auto agg_kind = batch_agg->get_aggregator_kind(); if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Counter) { +# ifdef OPENTELEMETRY_RTTI_ENABLED std::shared_ptr> temp_batch_agg_counter = std::dynamic_pointer_cast>(batch_agg); std::shared_ptr> temp_record_agg_counter = std::dynamic_pointer_cast>(record_agg); +# else + std::shared_ptr> temp_batch_agg_counter = + std::static_pointer_cast>(batch_agg); + std::shared_ptr> temp_record_agg_counter = + std::static_pointer_cast>(record_agg); +# endif auto temp_batch_agg_raw_counter = temp_batch_agg_counter.get(); auto temp_record_agg_raw_counter = temp_record_agg_counter.get(); @@ -229,6 +238,7 @@ class UngroupedMetricsProcessor : public MetricsProcessor } else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::MinMaxSumCount) { +# ifdef OPENTELEMETRY_RTTI_ENABLED std::shared_ptr> temp_batch_agg_mmsc = std::dynamic_pointer_cast>( @@ -238,6 +248,17 @@ class UngroupedMetricsProcessor : public MetricsProcessor temp_record_agg_mmsc = std::dynamic_pointer_cast>( record_agg); +# else + std::shared_ptr> + temp_batch_agg_mmsc = + std::static_pointer_cast>( + batch_agg); + + std::shared_ptr> + temp_record_agg_mmsc = + std::static_pointer_cast>( + record_agg); +# endif auto temp_batch_agg_raw_mmsc = temp_batch_agg_mmsc.get(); auto temp_record_agg_raw_mmsc = temp_record_agg_mmsc.get(); @@ -246,11 +267,19 @@ class UngroupedMetricsProcessor : public MetricsProcessor } else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Gauge) { +# ifdef OPENTELEMETRY_RTTI_ENABLED std::shared_ptr> temp_batch_agg_gauge = std::dynamic_pointer_cast>(batch_agg); std::shared_ptr> temp_record_agg_gauge = std::dynamic_pointer_cast>(record_agg); +# else + std::shared_ptr> temp_batch_agg_gauge = + std::static_pointer_cast>(batch_agg); + + std::shared_ptr> temp_record_agg_gauge = + std::static_pointer_cast>(record_agg); +# endif auto temp_batch_agg_raw_gauge = temp_batch_agg_gauge.get(); auto temp_record_agg_raw_gauge = temp_record_agg_gauge.get(); @@ -259,12 +288,19 @@ class UngroupedMetricsProcessor : public MetricsProcessor } else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Sketch) { +# ifdef OPENTELEMETRY_RTTI_ENABLED std::shared_ptr> temp_batch_agg_sketch = std::dynamic_pointer_cast>(batch_agg); std::shared_ptr> temp_record_agg_sketch = std::dynamic_pointer_cast>(record_agg); +# else + std::shared_ptr> temp_batch_agg_sketch = + std::static_pointer_cast>(batch_agg); + std::shared_ptr> temp_record_agg_sketch = + std::static_pointer_cast>(record_agg); +# endif auto temp_batch_agg_raw_sketch = temp_batch_agg_sketch.get(); auto temp_record_agg_raw_sketch = temp_record_agg_sketch.get(); @@ -272,6 +308,7 @@ class UngroupedMetricsProcessor : public MetricsProcessor } else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Histogram) { +# ifdef OPENTELEMETRY_RTTI_ENABLED std::shared_ptr> temp_batch_agg_histogram = std::dynamic_pointer_cast>( @@ -281,6 +318,17 @@ class UngroupedMetricsProcessor : public MetricsProcessor temp_record_agg_histogram = std::dynamic_pointer_cast>( record_agg); +# else + std::shared_ptr> + temp_batch_agg_histogram = + std::static_pointer_cast>( + batch_agg); + + std::shared_ptr> + temp_record_agg_histogram = + std::static_pointer_cast>( + record_agg); +# endif auto temp_batch_agg_raw_histogram = temp_batch_agg_histogram.get(); auto temp_record_agg_raw_histogram = temp_record_agg_histogram.get(); @@ -289,11 +337,19 @@ class UngroupedMetricsProcessor : public MetricsProcessor } else if (agg_kind == opentelemetry::sdk::metrics::AggregatorKind::Exact) { +# ifdef OPENTELEMETRY_RTTI_ENABLED std::shared_ptr> temp_batch_agg_exact = std::dynamic_pointer_cast>(batch_agg); std::shared_ptr> temp_record_agg_exact = std::dynamic_pointer_cast>(record_agg); +# else + std::shared_ptr> temp_batch_agg_exact = + std::static_pointer_cast>(batch_agg); + + std::shared_ptr> temp_record_agg_exact = + std::static_pointer_cast>(record_agg); +# endif auto temp_batch_agg_raw_exact = temp_batch_agg_exact.get(); auto temp_record_agg_raw_exact = temp_record_agg_exact.get(); diff --git a/sdk/src/_metrics/meter.cc b/sdk/src/_metrics/meter.cc index 5207865b9c..f48eccfbd6 100644 --- a/sdk/src/_metrics/meter.cc +++ b/sdk/src/_metrics/meter.cc @@ -2,7 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 #ifdef ENABLE_METRICS_PREVIEW + # include "opentelemetry/sdk/_metrics/meter.h" +# include "opentelemetry/common/macros.h" namespace metrics_api = opentelemetry::metrics; @@ -664,7 +666,11 @@ void Meter::CollectSingleSyncInstrument( i++; return; } - auto cast_ptr = std::dynamic_pointer_cast>(i->second); +# ifdef OPENTELEMETRY_RTTI_ENABLED + auto cast_ptr = std::dynamic_pointer_cast>(i->second); +# else + auto cast_ptr = std::static_pointer_cast>(i->second); +# endif std::vector new_records = cast_ptr->GetRecords(); records.insert(records.begin(), new_records.begin(), new_records.end()); } @@ -734,7 +740,11 @@ void Meter::CollectSingleAsyncInstrument( i++; return; } - auto cast_ptr = std::dynamic_pointer_cast>(i->second); +# ifdef OPENTELEMETRY_RTTI_ENABLED + auto cast_ptr = std::dynamic_pointer_cast>(i->second); +# else + auto cast_ptr = std::static_pointer_cast>(i->second); +# endif std::vector new_records = cast_ptr->GetRecords(); records.insert(records.begin(), new_records.begin(), new_records.end()); } diff --git a/sdk/test/_metrics/metric_instrument_test.cc b/sdk/test/_metrics/metric_instrument_test.cc index 089baf1211..28df53fc32 100644 --- a/sdk/test/_metrics/metric_instrument_test.cc +++ b/sdk/test/_metrics/metric_instrument_test.cc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #ifdef ENABLE_METRICS_PREVIEW + # include # include # include @@ -9,11 +10,19 @@ # include # include # include + +# include "opentelemetry/common/macros.h" # include "opentelemetry/sdk/_metrics/async_instruments.h" # include "opentelemetry/sdk/_metrics/sync_instruments.h" namespace metrics_api = opentelemetry::metrics; +# ifdef OPENTELEMETRY_RTTI_ENABLED +# define METRICS_TEST_TYPE_CAST(TO, FROM) dynamic_cast(FROM) +# else +# define METRICS_TEST_TYPE_CAST(TO, FROM) static_cast(FROM) +# endif + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { @@ -37,12 +46,15 @@ TEST(ApiSdkConversion, async) auto labelkv = common::KeyValueIterableView{labels}; alpha->observe(123456, labelkv); - EXPECT_EQ(dynamic_cast *>(alpha.get())->GetRecords()[0].GetLabels(), + EXPECT_EQ(METRICS_TEST_TYPE_CAST(AsynchronousInstrument *, alpha.get()) + ->GetRecords()[0] + .GetLabels(), "{key587:value264}"); alpha->observe(123456, labelkv); - AggregatorVariant canCollect = - dynamic_cast *>(alpha.get())->GetRecords()[0].GetAggregator(); + AggregatorVariant canCollect = METRICS_TEST_TYPE_CAST(AsynchronousInstrument *, alpha.get()) + ->GetRecords()[0] + .GetAggregator(); EXPECT_EQ(nostd::holds_alternative>>(canCollect), false); EXPECT_EQ(nostd::holds_alternative>>(canCollect), true); EXPECT_EQ(nostd::get>>(canCollect)->get_checkpoint()[0], 123456); @@ -292,11 +304,13 @@ TEST(Counter, StressAdd) second.join(); third.join(); - EXPECT_EQ(dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv)].get()) + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundCounter *, + alpha->boundInstruments_[KvToString(labelkv)].get()) ->GetAggregator() ->get_values()[0], 2000); - EXPECT_EQ(dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv1)].get()) + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundCounter *, + alpha->boundInstruments_[KvToString(labelkv1)].get()) ->GetAggregator() ->get_values()[0], 3000); @@ -343,16 +357,16 @@ TEST(IntUpDownCounter, StressAdd) third.join(); fourth.join(); - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv)].get()) - ->GetAggregator() - ->get_values()[0], - 12340 * 2); - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv1)].get()) - ->GetAggregator() - ->get_values()[0], - 56780 - 12340); + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundUpDownCounter *, + alpha->boundInstruments_[KvToString(labelkv)].get()) + ->GetAggregator() + ->get_values()[0], + 12340 * 2); + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundUpDownCounter *, + alpha->boundInstruments_[KvToString(labelkv1)].get()) + ->GetAggregator() + ->get_values()[0], + 56780 - 12340); } void RecorderCallback(std::shared_ptr> in, @@ -396,47 +410,47 @@ TEST(IntValueRecorder, StressRecord) third.join(); fourth.join(); - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv)].get()) - ->GetAggregator() - ->get_values()[0], - 0); // min - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv)].get()) - ->GetAggregator() - ->get_values()[1], - 49); // max - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv)].get()) - ->GetAggregator() - ->get_values()[2], - 1525); // sum - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv)].get()) - ->GetAggregator() - ->get_values()[3], - 75); // count - - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv1)].get()) - ->GetAggregator() - ->get_values()[0], - -99); // min - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv1)].get()) - ->GetAggregator() - ->get_values()[1], - 24); // max - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv1)].get()) - ->GetAggregator() - ->get_values()[2], - -4650); // sum - EXPECT_EQ( - dynamic_cast *>(alpha->boundInstruments_[KvToString(labelkv1)].get()) - ->GetAggregator() - ->get_values()[3], - 125); // count + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv)].get()) + ->GetAggregator() + ->get_values()[0], + 0); // min + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv)].get()) + ->GetAggregator() + ->get_values()[1], + 49); // max + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv)].get()) + ->GetAggregator() + ->get_values()[2], + 1525); // sum + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv)].get()) + ->GetAggregator() + ->get_values()[3], + 75); // count + + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv1)].get()) + ->GetAggregator() + ->get_values()[0], + -99); // min + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv1)].get()) + ->GetAggregator() + ->get_values()[1], + 24); // max + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv1)].get()) + ->GetAggregator() + ->get_values()[2], + -4650); // sum + EXPECT_EQ(METRICS_TEST_TYPE_CAST(BoundValueRecorder *, + alpha->boundInstruments_[KvToString(labelkv1)].get()) + ->GetAggregator() + ->get_values()[3], + 125); // count } TEST(Instruments, NoUpdateNoRecord) diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index 3c059cc44c..4a2792c3a7 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -68,7 +68,7 @@ TEST(MeterProvider, GetMeter) ASSERT_NE(m3, m6); // Should be an sdk::trace::Tracer with the processor attached. -# ifdef RTTI_ENABLED +# ifdef OPENTELEMETRY_RTTI_ENABLED auto sdkMeter1 = dynamic_cast(m1.get()); # else auto sdkMeter1 = static_cast(m1.get()); diff --git a/sdk/test/trace/tracer_provider_test.cc b/sdk/test/trace/tracer_provider_test.cc index d72d6bd40f..498f66127d 100644 --- a/sdk/test/trace/tracer_provider_test.cc +++ b/sdk/test/trace/tracer_provider_test.cc @@ -39,7 +39,7 @@ TEST(TracerProvider, GetTracer) ASSERT_NE(t3, t6); // Should be an sdk::trace::Tracer with the processor attached. -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED auto sdkTracer1 = dynamic_cast(t1.get()); #else auto sdkTracer1 = static_cast(t1.get()); @@ -53,7 +53,7 @@ TEST(TracerProvider, GetTracer) std::make_shared(std::move(processors2), Resource::Create({}), std::unique_ptr(new AlwaysOffSampler()), std::unique_ptr(new RandomIdGenerator))); -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED auto sdkTracer2 = dynamic_cast(tp2.GetTracer("test").get()); #else auto sdkTracer2 = static_cast(tp2.GetTracer("test").get()); @@ -65,7 +65,7 @@ TEST(TracerProvider, GetTracer) ASSERT_EQ(instrumentation_library1.GetVersion(), ""); // Should be an sdk::trace::Tracer with the processor attached. -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED auto sdkTracer3 = dynamic_cast(t3.get()); #else auto sdkTracer3 = static_cast(t3.get()); diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index dc806b079f..15a7566b9b 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -347,7 +347,7 @@ TEST(Tracer, GetSampler) // Create a Tracer with a default AlwaysOnSampler auto tracer_on = initTracer(nullptr); -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED auto &t1 = std::dynamic_pointer_cast(tracer_on)->GetSampler(); #else auto &t1 = std::static_pointer_cast(tracer_on)->GetSampler(); @@ -357,7 +357,7 @@ TEST(Tracer, GetSampler) // Create a Tracer with a AlwaysOffSampler auto tracer_off = initTracer(nullptr, new AlwaysOffSampler()); -#ifdef RTTI_ENABLED +#ifdef OPENTELEMETRY_RTTI_ENABLED auto &t2 = std::dynamic_pointer_cast(tracer_off)->GetSampler(); #else auto &t2 = std::static_pointer_cast(tracer_off)->GetSampler(); From 3122254e8238738d74f78130817b090a8fdc0a9a Mon Sep 17 00:00:00 2001 From: Ben Landrum <71329856+benlandrum@users.noreply.github.com> Date: Thu, 7 Apr 2022 13:02:11 -0400 Subject: [PATCH 19/69] Remove implicitly deleted default constructor (#1267) Co-authored-by: Tom Tan Co-authored-by: Lalit Kumar Bhasin --- api/include/opentelemetry/context/runtime_context.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/include/opentelemetry/context/runtime_context.h b/api/include/opentelemetry/context/runtime_context.h index fbcf425c2c..74fa2151ea 100644 --- a/api/include/opentelemetry/context/runtime_context.h +++ b/api/include/opentelemetry/context/runtime_context.h @@ -22,8 +22,6 @@ class Token private: friend class RuntimeContextStorage; - Token() noexcept = default; - // A constructor that sets the token's Context object to the // one that was passed in. Token(const Context &context) : context_(context) {} From d72dcb69b07ffe773e490ee797126357480b9cb0 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 11 Apr 2022 00:45:36 -0700 Subject: [PATCH 20/69] [ETW Exporter] - ETW provider handle cleanup (#1322) --- .../include/opentelemetry/exporters/etw/etw_provider.h | 8 ++++++-- exporters/etw/test/etw_provider_test.cc | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 5b00f05574..51cca03a60 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -203,7 +203,8 @@ class ETWProvider { std::lock_guard lock(m_providerMapLock); - auto m = providers(); + // use reference to provider list, NOT it' copy. + auto &m = providers(); auto it = m.begin(); while (it != m.end()) { @@ -228,7 +229,10 @@ class ETWProvider } it->second.providerHandle = INVALID_HANDLE; - m.erase(it); + if (result == STATUS_OK) + { + m.erase(it); + } } return result; } diff --git a/exporters/etw/test/etw_provider_test.cc b/exporters/etw/test/etw_provider_test.cc index 433630270f..d5ebbcad43 100644 --- a/exporters/etw/test/etw_provider_test.cc +++ b/exporters/etw/test/etw_provider_test.cc @@ -18,6 +18,7 @@ TEST(ETWProvider, ProviderIsRegisteredSuccessfully) bool registered = etw.is_registered(providerName); ASSERT_TRUE(registered); + etw.close(handle); } TEST(ETWProvider, ProviderIsNotRegisteredSuccessfully) @@ -46,6 +47,7 @@ TEST(ETWProvider, CheckOpenGUIDDataSuccessfully) auto guidStrName = uuid_name.to_string(); ASSERT_STREQ(guidStrHandle.c_str(), guidStrName.c_str()); + etw.close(handle); } TEST(ETWProvider, CheckCloseSuccess) @@ -53,10 +55,10 @@ TEST(ETWProvider, CheckCloseSuccess) std::string providerName = "OpenTelemetry-ETW-Provider"; static ETWProvider etw; - auto handle = etw.open(providerName.c_str()); - + auto handle = etw.open(providerName.c_str(), ETWProvider::EventFormat::ETW_MANIFEST); auto result = etw.close(handle); ASSERT_NE(result, etw.STATUS_ERROR); + ASSERT_FALSE(etw.is_registered(providerName)); } #endif From e200c1f183ab1340448b0992e96054f5aa591f46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 07:55:15 -0700 Subject: [PATCH 21/69] Bump actions/stale from 4 to 5 (#1323) --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index e55a93d08d..ff3e02df62 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,7 +7,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v4 + - uses: actions/stale@v5 with: stale-issue-message: 'This issue was marked as stale due to lack of activity. It will be closed in 7 days if no furthur activity occurs.' close-issue-message: 'Closed as inactive. Feel free to reopen if this is still an issue.' From 755f109a0d44f277da33145af1e285da624b3fd8 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Tue, 12 Apr 2022 20:12:21 +0200 Subject: [PATCH 22/69] ostream metrics example (#1312) --- examples/common/metrics_foo_library/BUILD | 17 ++ .../common/metrics_foo_library/foo_library.cc | 25 ++ .../common/metrics_foo_library/foo_library.h | 9 + examples/metrics_simple/BUILD | 15 + examples/metrics_simple/metrics_ostream.cc | 65 ++++ exporters/ostream/BUILD | 59 ++-- .../exporters/ostream/metric_exporter.h | 10 +- exporters/ostream/src/metric_exporter.cc | 88 +++--- exporters/ostream/test/ostream_metric_test.cc | 278 ++++++++++-------- .../sdk/metrics/metric_exporter.h | 1 + .../sdk/metrics/view/instrument_selector.h | 2 +- 11 files changed, 382 insertions(+), 187 deletions(-) create mode 100644 examples/common/metrics_foo_library/BUILD create mode 100644 examples/common/metrics_foo_library/foo_library.cc create mode 100644 examples/common/metrics_foo_library/foo_library.h create mode 100644 examples/metrics_simple/metrics_ostream.cc diff --git a/examples/common/metrics_foo_library/BUILD b/examples/common/metrics_foo_library/BUILD new file mode 100644 index 0000000000..bc84949732 --- /dev/null +++ b/examples/common/metrics_foo_library/BUILD @@ -0,0 +1,17 @@ +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "common_metrics_foo_library", + srcs = [ + "foo_library.cc", + ], + hdrs = [ + "foo_library.h", + ], + defines = ["BAZEL_BUILD"], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/metrics", + ], +) diff --git a/examples/common/metrics_foo_library/foo_library.cc b/examples/common/metrics_foo_library/foo_library.cc new file mode 100644 index 0000000000..344f51c082 --- /dev/null +++ b/examples/common/metrics_foo_library/foo_library.cc @@ -0,0 +1,25 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/metrics/provider.h" + +namespace nostd = opentelemetry::nostd; +namespace metrics_api = opentelemetry::metrics; + +void foo_library(const std::string &name) +{ + // Get the Meter from the MeterProvider + auto provider = metrics_api::Provider::GetMeterProvider(); + nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); + auto double_counter = meter->CreateDoubleCounter(name); + double_counter->Add(28.5); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + double_counter->Add(3.14); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + double_counter->Add(23.5); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); +} +#endif diff --git a/examples/common/metrics_foo_library/foo_library.h b/examples/common/metrics_foo_library/foo_library.h new file mode 100644 index 0000000000..662646a6a4 --- /dev/null +++ b/examples/common/metrics_foo_library/foo_library.h @@ -0,0 +1,9 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include + +void foo_library(const std::string &name); +#endif diff --git a/examples/metrics_simple/BUILD b/examples/metrics_simple/BUILD index b845a2f890..95d6490ba2 100644 --- a/examples/metrics_simple/BUILD +++ b/examples/metrics_simple/BUILD @@ -11,3 +11,18 @@ cc_binary( "//sdk/src/_metrics:metrics_deprecated", ], ) + +cc_binary( + name = "metrics_ostream_example", + srcs = [ + "metrics_ostream.cc", + ], + linkopts = ["-pthread"], + tags = ["ostream"], + deps = [ + "//api", + "//examples/common/metrics_foo_library:common_metrics_foo_library", + "//exporters/ostream:ostream_metric_exporter", + "//sdk/src/metrics", + ], +) diff --git a/examples/metrics_simple/metrics_ostream.cc b/examples/metrics_simple/metrics_ostream.cc new file mode 100644 index 0000000000..9fae5f07b7 --- /dev/null +++ b/examples/metrics_simple/metrics_ostream.cc @@ -0,0 +1,65 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/exporters/ostream/metric_exporter.h" +# include "opentelemetry/metrics/provider.h" +# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/metrics/meter.h" +# include "opentelemetry/sdk/metrics/meter_provider.h" + +# ifdef BAZEL_BUILD +# include "examples/common/metrics_foo_library/foo_library.h" +# else +# include "metrics_foo_library/foo_library.h" +# endif + +namespace metric_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace exportermetrics = opentelemetry::exporter::metrics; +namespace metrics_api = opentelemetry::metrics; + +namespace +{ + +void initMetrics(const std::string &name) +{ + std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; + std::vector> exporters; + + std::string version{"1.2.0"}; + std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; + + // Initialize and set the global MeterProvider + metric_sdk::PeriodicExportingMetricReaderOptions options; + options.export_interval_millis = std::chrono::milliseconds(1000); + options.export_timeout_millis = std::chrono::milliseconds(500); + std::unique_ptr reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + auto provider = std::shared_ptr( + new metric_sdk::MeterProvider(std::move(exporters))); + auto p = std::static_pointer_cast(provider); + p->AddMetricReader(std::move(reader)); + std::unique_ptr instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, name)}; + std::unique_ptr meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); + metrics_api::Provider::SetMeterProvider(provider); +} +} // namespace +int main() +{ + std::string name{"ostream_metric_example"}; + initMetrics(name); + foo_library(name); +} +#else +int main() {} +#endif diff --git a/exporters/ostream/BUILD b/exporters/ostream/BUILD index f74d896344..cca74d6693 100644 --- a/exporters/ostream/BUILD +++ b/exporters/ostream/BUILD @@ -43,37 +43,36 @@ cc_library( ], ) -# TODO - Uncomment once MetricData interface is finalised -#cc_library( -# name = "ostream_metric_exporter", -# srcs = [ -# "src/metric_exporter.cc", -# ], -# hdrs = [ -# "include/opentelemetry/exporters/ostream/metric_exporter.h", -# ], -# strip_include_prefix = "include", -# tags = [ -# "metrics", -# "ostream", -# ], -# deps = [ -# "//sdk/src/metrics", -# ], -#) +cc_library( + name = "ostream_metric_exporter", + srcs = [ + "src/metric_exporter.cc", + ], + hdrs = [ + "include/opentelemetry/exporters/ostream/metric_exporter.h", + ], + strip_include_prefix = "include", + tags = [ + "metrics", + "ostream", + ], + deps = [ + "//sdk/src/metrics", + ], +) -#cc_test( -# name = "ostream_metric_test", -# srcs = ["test/ostream_metric_test.cc"], -# tags = [ -# "ostream", -# "test", -# ], -# deps = [ -# ":ostream_metric_exporter", -# "@com_google_googletest//:gtest_main", -# ], -#) +cc_test( + name = "ostream_metric_test", + srcs = ["test/ostream_metric_test.cc"], + tags = [ + "ostream", + "test", + ], + deps = [ + ":ostream_metric_exporter", + "@com_google_googletest//:gtest_main", + ], +) cc_test( name = "ostream_metrics_test_deprecated", diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h index 5f27db13d2..465ae02bb6 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h @@ -35,11 +35,9 @@ class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricEx /** * Export - * @param records a span of unique pointers to metrics data + * @param data metrics data */ - sdk::common::ExportResult Export( - const nostd::span> &records) noexcept - override; + sdk::common::ExportResult Export(const sdk::metrics::ResourceMetrics &data) noexcept override; /** * Force flush the exporter. @@ -60,7 +58,9 @@ class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricEx bool is_shutdown_ = false; mutable opentelemetry::common::SpinLockMutex lock_; bool isShutdown() const noexcept; - void printPointData(opentelemetry::sdk::metrics::PointType &point_data); + void printInstrumentationInfoMetricData( + const sdk::metrics::InstrumentationInfoMetrics &info_metrics); + void printPointData(const opentelemetry::sdk::metrics::PointType &point_data); }; } // namespace metrics } // namespace exporter diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index f8d26a7fa5..fad9e03d49 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -1,68 +1,90 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include #ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/exporters/ostream/metric_exporter.h" # include +# include "opentelemetry/exporters/ostream/metric_exporter.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" # include "opentelemetry/sdk_config.h" +namespace +{ +std::string timeToString(opentelemetry::common::SystemTimestamp time_stamp) +{ + std::time_t epoch_time = std::chrono::system_clock::to_time_t(time_stamp); + return std::ctime(&epoch_time); +} +} // namespace + OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { namespace metrics { +template +inline void printVec(std::ostream &os, Container &vec) +{ + using T = typename std::decay::type; + os << '['; + if (vec.size() > 1) + { + std::copy(vec.begin(), vec.end(), std::ostream_iterator(os, ", ")); + } + os << ']'; +} + OStreamMetricExporter::OStreamMetricExporter(std::ostream &sout) noexcept : sout_(sout) {} sdk::common::ExportResult OStreamMetricExporter::Export( - const nostd::span> &records) noexcept + const sdk::metrics::ResourceMetrics &data) noexcept { if (isShutdown()) { OTEL_INTERNAL_LOG_ERROR("[OStream Metric] Exporting " - << records.size() << " records(s) failed, exporter is shutdown"); + << data.instrumentation_info_metric_data_.size() + << " records(s) failed, exporter is shutdown"); return sdk::common::ExportResult::kFailure; } - for (auto &record : records) + for (auto &record : data.instrumentation_info_metric_data_) { - sout_ << "{" - << "\n name : " << record->instrumentation_library_->GetName() - << "\n version : " << record->instrumentation_library_->GetVersion(); - printPointData(record->point_data_); - sout_ << "\n}\n"; + printInstrumentationInfoMetricData(record); } return sdk::common::ExportResult::kSuccess; } -template -inline void printVec(std::ostream &os, std::vector &vec) +void OStreamMetricExporter::printInstrumentationInfoMetricData( + const sdk::metrics::InstrumentationInfoMetrics &info_metric) { - os << '['; - if (vec.size() > 1) - { - std::copy(vec.begin(), vec.end() - 1, std::ostream_iterator(os, ", ")); - } - if (!vec.empty()) + sout_ << "{"; + sout_ << "\n name\t\t: " << info_metric.instrumentation_library_->GetName() + << "\n schema url\t: " << info_metric.instrumentation_library_->GetSchemaURL() + << "\n version\t: " << info_metric.instrumentation_library_->GetVersion(); + for (const auto &record : info_metric.metric_data_) { - os << vec.back(); + sout_ << "\n start time\t: " << timeToString(record.start_ts) + << " end time\t: " << timeToString(record.end_ts) + << " description\t: " << record.instrument_descriptor.description_ + << "\n unit\t\t: " << record.instrument_descriptor.unit_; + + for (const auto &pd : record.point_data_attr_) + { + printPointData(pd.point_data); + } } - os << ']'; + sout_ << "\n}\n"; } -void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointType &point_data) +void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::PointType &point_data) { if (nostd::holds_alternative(point_data)) { auto sum_point_data = nostd::get(point_data); - sout_ << "\n type : SumPointData"; - sout_ << "\n start timestamp : " - << std::to_string(sum_point_data.start_epoch_nanos_.time_since_epoch().count()); - sout_ << "\n end timestamp : " - << std::to_string(sum_point_data.end_epoch_nanos_.time_since_epoch().count()); - sout_ << "\n value : "; + sout_ << "\n type\t\t: SumPointData"; + sout_ << "\n value\t\t: "; if (nostd::holds_alternative(sum_point_data.value_)) { sout_ << nostd::get(sum_point_data.value_); @@ -76,8 +98,6 @@ void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointTyp { auto histogram_point_data = nostd::get(point_data); sout_ << "\n type : HistogramPointData"; - sout_ << "\n timestamp : " - << std::to_string(histogram_point_data.epoch_nanos_.time_since_epoch().count()); sout_ << "\n count : " << histogram_point_data.count_; sout_ << "\n sum : "; if (nostd::holds_alternative(histogram_point_data.sum_)) @@ -90,14 +110,14 @@ void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointTyp } sout_ << "\n buckets : "; - if (nostd::holds_alternative>(histogram_point_data.boundaries_)) + if (nostd::holds_alternative>(histogram_point_data.boundaries_)) { - auto &double_boundaries = nostd::get>(histogram_point_data.boundaries_); + auto &double_boundaries = nostd::get>(histogram_point_data.boundaries_); printVec(sout_, double_boundaries); } - else if (nostd::holds_alternative>(histogram_point_data.boundaries_)) + else if (nostd::holds_alternative>(histogram_point_data.boundaries_)) { - auto &long_boundaries = nostd::get>(histogram_point_data.boundaries_); + auto &long_boundaries = nostd::get>(histogram_point_data.boundaries_); printVec(sout_, long_boundaries); } @@ -109,8 +129,8 @@ void OStreamMetricExporter::printPointData(opentelemetry::sdk::metrics::PointTyp auto last_point_data = nostd::get(point_data); sout_ << "\n type : LastValuePointData"; sout_ << "\n timestamp : " - << std::to_string(last_point_data.epoch_nanos_.time_since_epoch().count()) - << std::boolalpha << "\n valid : " << last_point_data.is_lastvalue_valid_; + << std::to_string(last_point_data.sample_ts_.time_since_epoch().count()) << std::boolalpha + << "\n valid : " << last_point_data.is_lastvalue_valid_; sout_ << "\n value : "; if (nostd::holds_alternative(last_point_data.value_)) { diff --git a/exporters/ostream/test/ostream_metric_test.cc b/exporters/ostream/test/ostream_metric_test.cc index 9e98dd4da4..3618d93e7a 100644 --- a/exporters/ostream/test/ostream_metric_test.cc +++ b/exporters/ostream/test/ostream_metric_test.cc @@ -1,14 +1,19 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 - -#include #ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/resource/resource_detector.h" + +# include # include "opentelemetry/exporters/ostream/metric_exporter.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" - -# include +# include "opentelemetry/sdk/metrics/data/metric_data.h" +# include "opentelemetry/sdk/resource/resource.h" namespace metric_sdk = opentelemetry::sdk::metrics; namespace nostd = opentelemetry::nostd; @@ -19,7 +24,7 @@ TEST(OStreamMetricsExporter, Shutdown) auto exporter = std::unique_ptr(new exportermetrics::OStreamMetricExporter); ASSERT_TRUE(exporter->Shutdown()); - auto result = exporter->Export(nostd::span>{}); + auto result = exporter->Export(metric_sdk::ResourceMetrics{}); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kFailure); } @@ -28,48 +33,51 @@ TEST(OStreamMetricsExporter, ExportSumPointData) auto exporter = std::unique_ptr(new exportermetrics::OStreamMetricExporter); - std::unique_ptr record(new metric_sdk::MetricData); + metric_sdk::SumPointData sum_point_data{}; + sum_point_data.value_ = 10.0; + metric_sdk::SumPointData sum_point_data2{}; + sum_point_data2.value_ = 20.0; + metric_sdk::ResourceMetrics data; + auto resource = opentelemetry::sdk::resource::Resource::Create( + opentelemetry::sdk::resource::ResourceAttributes{}); + data.resource_ = &resource; auto instrumentation_library = opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create("library_name", "1.2.0"); - record->instrumentation_library_ = instrumentation_library.get(); - record->point_data_ = metric_sdk::SumPointData{ - opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, 10.0, - metric_sdk::AggregationTemporality::kUnspecified, false}; - auto record2 = std::unique_ptr(new metric_sdk::MetricData(*record)); - record2->point_data_ = metric_sdk::SumPointData{ - opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, 20l, - metric_sdk::AggregationTemporality::kUnspecified, false}; - std::vector> records; - records.push_back(std::move(record)); - records.push_back(std::move(record2)); + metric_sdk::MetricData metric_data{ + metric_sdk::InstrumentDescriptor{"library_name", "description", "unit", + metric_sdk::InstrumentType::kCounter, + metric_sdk::InstrumentValueType::kDouble}, + opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, + std::vector{ + {metric_sdk::PointAttributes{}, sum_point_data}, + {metric_sdk::PointAttributes{}, sum_point_data2}}}; + data.instrumentation_info_metric_data_ = std::vector{ + {instrumentation_library.get(), std::vector{metric_data}}}; std::stringstream stdoutOutput; std::streambuf *sbuf = std::cout.rdbuf(); std::cout.rdbuf(stdoutOutput.rdbuf()); - auto result = exporter->Export(records); + auto result = exporter->Export(data); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess); std::cout.rdbuf(sbuf); - std::string expectedOutput = - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - " type : SumPointData\n" - " start timestamp : 0\n" - " end timestamp : 0\n" - " value : 10\n" - "}\n" - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - " type : SumPointData\n" - " start timestamp : 0\n" - " end timestamp : 0\n" - " value : 20\n" - "}\n"; - ASSERT_EQ(stdoutOutput.str(), expectedOutput); + std::string expected_output = + "{" + "\n name\t\t: library_name" + "\n schema url\t: " + "\n version\t: 1.2.0" + "\n start time\t: Thu Jan 1 00:00:00 1970" + "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n description\t: description" + "\n unit\t\t: unit" + "\n type\t\t: SumPointData" + "\n value\t\t: 10" + "\n type\t\t: SumPointData" + "\n value\t\t: 20" + "\n}\n"; + ASSERT_EQ(stdoutOutput.str(), expected_output); } TEST(OStreamMetricsExporter, ExportHistogramPointData) @@ -77,56 +85,63 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) auto exporter = std::unique_ptr(new exportermetrics::OStreamMetricExporter); - std::unique_ptr record(new metric_sdk::MetricData); + metric_sdk::HistogramPointData histogram_point_data{}; + histogram_point_data.boundaries_ = std::list{10.1, 20.2, 30.2}; + histogram_point_data.count_ = 3; + histogram_point_data.counts_ = {200, 300, 400, 500}; + histogram_point_data.sum_ = 900.5; + metric_sdk::HistogramPointData histogram_point_data2{}; + histogram_point_data2.boundaries_ = std::list{10, 20, 30}; + histogram_point_data2.count_ = 3; + histogram_point_data2.counts_ = {200, 300, 400, 500}; + histogram_point_data2.sum_ = 900l; + metric_sdk::ResourceMetrics data; + auto resource = opentelemetry::sdk::resource::Resource::Create( + opentelemetry::sdk::resource::ResourceAttributes{}); + data.resource_ = &resource; auto instrumentation_library = opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create("library_name", "1.2.0"); - record->instrumentation_library_ = instrumentation_library.get(); - record->point_data_ = metric_sdk::HistogramPointData{opentelemetry::common::SystemTimestamp{}, - std::vector{10.1, 20.2, 30.2}, - 900.5, - {200, 300, 400, 500}, - 3}; - auto record2 = std::unique_ptr(new metric_sdk::MetricData(*record)); - record2->point_data_ = metric_sdk::HistogramPointData{opentelemetry::common::SystemTimestamp{}, - std::vector{10, 20, 30}, - 900l, - {200, 300, 400, 500}, - 3}; - std::vector> records; - records.push_back(std::move(record)); - records.push_back(std::move(record2)); + metric_sdk::MetricData metric_data{ + metric_sdk::InstrumentDescriptor{"library_name", "description", "unit", + metric_sdk::InstrumentType::kCounter, + metric_sdk::InstrumentValueType::kDouble}, + opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, + std::vector{ + {metric_sdk::PointAttributes{}, histogram_point_data}, + {metric_sdk::PointAttributes{}, histogram_point_data2}}}; + data.instrumentation_info_metric_data_ = std::vector{ + {instrumentation_library.get(), std::vector{metric_data}}}; std::stringstream stdoutOutput; std::streambuf *sbuf = std::cout.rdbuf(); std::cout.rdbuf(stdoutOutput.rdbuf()); - auto result = exporter->Export(records); + auto result = exporter->Export(data); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess); std::cout.rdbuf(sbuf); - std::string expectedOutput = - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - " type : HistogramPointData\n" - " timestamp : 0\n" - " count : 3\n" - " sum : 900.5\n" - " buckets : [10.1, 20.2, 30.2]\n" - " counts : [200, 300, 400, 500]\n" - "}\n" - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - " type : HistogramPointData\n" - " timestamp : 0\n" - " count : 3\n" - " sum : 900\n" - " buckets : [10, 20, 30]\n" - " counts : [200, 300, 400, 500]\n" - "}\n"; - ASSERT_EQ(stdoutOutput.str(), expectedOutput); + std::string expected_output = + "{" + "\n name\t\t: library_name" + "\n schema url\t: " + "\n version\t: 1.2.0" + "\n start time\t: Thu Jan 1 00:00:00 1970" + "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n description\t: description" + "\n unit\t\t: unit" + "\n type : HistogramPointData" + "\n count : 3" + "\n sum : 900.5" + "\n buckets : [10.1, 20.2, 30.2, ]" + "\n counts : [200, 300, 400, 500, ]" + "\n type : HistogramPointData" + "\n count : 3" + "\n sum : 900" + "\n buckets : [10, 20, 30, ]" + "\n counts : [200, 300, 400, 500, ]" + "\n}\n"; + ASSERT_EQ(stdoutOutput.str(), expected_output); } TEST(OStreamMetricsExporter, ExportLastValuePointData) @@ -134,46 +149,59 @@ TEST(OStreamMetricsExporter, ExportLastValuePointData) auto exporter = std::unique_ptr(new exportermetrics::OStreamMetricExporter); - std::unique_ptr record(new metric_sdk::MetricData); + metric_sdk::ResourceMetrics data; + auto resource = opentelemetry::sdk::resource::Resource::Create( + opentelemetry::sdk::resource::ResourceAttributes{}); + data.resource_ = &resource; auto instrumentation_library = opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create("library_name", "1.2.0"); - record->instrumentation_library_ = instrumentation_library.get(); - record->point_data_ = - metric_sdk::LastValuePointData{opentelemetry::common::SystemTimestamp{}, true, 10.0}; - auto record2 = std::unique_ptr(new metric_sdk::MetricData(*record)); - record2->point_data_ = - metric_sdk::LastValuePointData{opentelemetry::common::SystemTimestamp{}, true, 20l}; - std::vector> records; - records.push_back(std::move(record)); - records.push_back(std::move(record2)); + metric_sdk::LastValuePointData last_value_point_data{}; + last_value_point_data.value_ = 10.0; + last_value_point_data.is_lastvalue_valid_ = true; + last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{}; + metric_sdk::LastValuePointData last_value_point_data2{}; + last_value_point_data2.value_ = 20l; + last_value_point_data2.is_lastvalue_valid_ = true; + last_value_point_data2.sample_ts_ = opentelemetry::common::SystemTimestamp{}; + metric_sdk::MetricData metric_data{ + metric_sdk::InstrumentDescriptor{"library_name", "description", "unit", + metric_sdk::InstrumentType::kCounter, + metric_sdk::InstrumentValueType::kDouble}, + opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, + std::vector{ + {metric_sdk::PointAttributes{}, last_value_point_data}, + {metric_sdk::PointAttributes{}, last_value_point_data2}}}; + data.instrumentation_info_metric_data_ = std::vector{ + {instrumentation_library.get(), std::vector{metric_data}}}; std::stringstream stdoutOutput; std::streambuf *sbuf = std::cout.rdbuf(); std::cout.rdbuf(stdoutOutput.rdbuf()); - auto result = exporter->Export(records); + auto result = exporter->Export(data); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess); std::cout.rdbuf(sbuf); - std::string expectedOutput = - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - " type : LastValuePointData\n" - " timestamp : 0\n" - " valid : true\n" - " value : 10\n" - "}\n" - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - " type : LastValuePointData\n" - " timestamp : 0\n" - " valid : true\n" - " value : 20\n" - "}\n"; - ASSERT_EQ(stdoutOutput.str(), expectedOutput); + std::string expected_output = + "{" + "\n name\t\t: library_name" + "\n schema url\t: " + "\n version\t: 1.2.0" + "\n start time\t: Thu Jan 1 00:00:00 1970" + "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n description\t: description" + "\n unit\t\t: unit" + "\n type : LastValuePointData" + "\n timestamp : 0" + "\n valid : true" + "\n value : 10" + "\n type : LastValuePointData" + "\n timestamp : 0" + "\n valid : true" + "\n value : 20" + "\n}\n"; + ASSERT_EQ(stdoutOutput.str(), expected_output); } TEST(OStreamMetricsExporter, ExportDropPointData) @@ -181,30 +209,46 @@ TEST(OStreamMetricsExporter, ExportDropPointData) auto exporter = std::unique_ptr(new exportermetrics::OStreamMetricExporter); - std::unique_ptr record(new metric_sdk::MetricData); + metric_sdk::ResourceMetrics data; + auto resource = opentelemetry::sdk::resource::Resource::Create( + opentelemetry::sdk::resource::ResourceAttributes{}); + data.resource_ = &resource; auto instrumentation_library = opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create("library_name", "1.2.0"); - record->instrumentation_library_ = instrumentation_library.get(); - record->point_data_ = metric_sdk::DropPointData{}; - std::vector> records; - records.push_back(std::move(record)); + metric_sdk::DropPointData drop_point_data{}; + metric_sdk::DropPointData drop_point_data2{}; + metric_sdk::MetricData metric_data{ + metric_sdk::InstrumentDescriptor{"library_name", "description", "unit", + metric_sdk::InstrumentType::kCounter, + metric_sdk::InstrumentValueType::kDouble}, + opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, + std::vector{ + {metric_sdk::PointAttributes{}, drop_point_data}, + {metric_sdk::PointAttributes{}, drop_point_data2}}}; + data.instrumentation_info_metric_data_ = std::vector{ + {instrumentation_library.get(), std::vector{metric_data}}}; std::stringstream stdoutOutput; std::streambuf *sbuf = std::cout.rdbuf(); std::cout.rdbuf(stdoutOutput.rdbuf()); - auto result = exporter->Export(records); + auto result = exporter->Export(data); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess); std::cout.rdbuf(sbuf); - std::string expectedOutput = - "{\n" - " name : library_name\n" - " version : 1.2.0\n" - "}\n"; - - ASSERT_EQ(stdoutOutput.str(), expectedOutput); + std::string expected_output = + "{" + "\n name\t\t: library_name" + "\n schema url\t: " + "\n version\t: 1.2.0" + "\n start time\t: Thu Jan 1 00:00:00 1970" + "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n description\t: description" + "\n unit\t\t: unit" + "\n}\n"; + + ASSERT_EQ(stdoutOutput.str(), expected_output); } #endif diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h index b6b5acf3a9..127ef468ac 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h @@ -6,6 +6,7 @@ # include "opentelemetry/nostd/span.h" # include "opentelemetry/sdk/common/exporter_utils.h" +# include "opentelemetry/sdk/metrics/export/metric_producer.h" # include "opentelemetry/version.h" # include diff --git a/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h b/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h index 4912277d09..e79a292c0b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/instrument_selector.h @@ -27,8 +27,8 @@ class InstrumentSelector InstrumentType GetInstrumentType() { return instrument_type_; } private: - opentelemetry::sdk::metrics::InstrumentType instrument_type_; std::unique_ptr name_filter_; + opentelemetry::sdk::metrics::InstrumentType instrument_type_; }; } // namespace metrics } // namespace sdk From da2911cf4458c7068f967c17c65d07eeba449a08 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Tue, 12 Apr 2022 12:46:07 -0700 Subject: [PATCH 23/69] Prepare v1.3.0 release (#1324) --- CHANGELOG.md | 44 +++++++++++++++++++ api/include/opentelemetry/version.h | 2 +- docs/public/conf.py | 2 +- .../opentelemetry/sdk/version/version.h | 2 +- sdk/src/version/version.cc | 2 +- 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd41c75626..425029d72f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,52 @@ Increment the: ## [Unreleased] +## [1.3.0] 2022-04-11 + +* [ETW EXPORTER] ETW provider handle cleanup ([#1322](https://github.com/open-telemetry/opentelemetry-cpp/pull/1322)) +* [BUILD] Move public definitions into `opentelemetry_api`. ([#1314](https://github.com/open-telemetry/opentelemetry-cpp/pull/1314)) +* [METRICS] OStream example ([#1312](https://github.com/open-telemetry/opentelemetry-cpp/pull/1312)) +* [BUILD] Rename `http_client_curl` to `opentelemetry_http_client_curl` ([#1301](https://github.com/open-telemetry/opentelemetry-cpp/pull/1301)) +* [METRICS SDK] Add InstrumentationInfo and Resource to the metrics data to be + exported. + ([#1299](https://github.com/open-telemetry/opentelemetry-cpp/pull/1299)) +* [TESTS] Add building test without RTTI ([#1294](https://github.com/open-telemetry/opentelemetry-cpp/pull/1294)) +* [METRICS SDK] Implement periodic exporting metric reader ([#1286](https://github.com/open-telemetry/opentelemetry-cpp/pull/1286)) * [SDK] Bugfix: span SetAttribute crash ([#1283](https://github.com/open-telemetry/opentelemetry-cpp/pull/1283)) +* [BUG] Remove implicitly deleted default constructor ([#1267](https://github.com/open-telemetry/opentelemetry-cpp/pull/1267)) +* [METRICS SDK] Synchronous Metric collection (Delta , Cumulative) ([#1265](https://github.com/open-telemetry/opentelemetry-cpp/pull/1265)) +* [METRICS SDK] Metrics exemplar round 1 ([#1264](https://github.com/open-telemetry/opentelemetry-cpp/pull/1264)) +* [EXPORTER] Fix: use CURLOPT_TIMEOUT_MS to config OtlpHttpExporter's timeout + instead of CURLOPT_TIMEOUT + ([#1261](https://github.com/open-telemetry/opentelemetry-cpp/pull/1261)) * [EXPORTER] Jaeger Exporter - Populate Span Links ([#1251](https://github.com/open-telemetry/opentelemetry-cpp/pull/1251)) +* [SDK] Reorder the destructor of members in LoggerProvider and TracerProvider ([#1245](https://github.com/open-telemetry/opentelemetry-cpp/pull/1245)) +* [METRICS SDK] Enable metric collection from MetricReader ([#1241](https://github.com/open-telemetry/opentelemetry-cpp/pull/1241)) +* [METRICS SDK] Asynchronous Aggregation storage ([#1232](https://github.com/open-telemetry/opentelemetry-cpp/pull/1232)) +* [METRICS SDK] Synchronous Instruments - Aggregation Storage(s) creation for + configured views + ([#1219](https://github.com/open-telemetry/opentelemetry-cpp/pull/1219)) +* [BUILD] Added s390x arch into CMake build. ([#1216](https://github.com/open-telemetry/opentelemetry-cpp/pull/1216)) +* [API] Allow extension of the lifetime of ContextStorage. ([#1214](https://github.com/open-telemetry/opentelemetry-cpp/pull/1214)) +* [METRICS SDK] Add Aggregation storage ([#1213](https://github.com/open-telemetry/opentelemetry-cpp/pull/1213)) +* [TESTS] Fix ostream_log_test Mac ([#1208](https://github.com/open-telemetry/opentelemetry-cpp/pull/1208)) +* [BUILD] Update grpc to v1.43.2 to support VS2022/MSVC 19.30 and bazel 5.0 ([#1207](https://github.com/open-telemetry/opentelemetry-cpp/pull/1207)) +* [DOCS] Benchmark documentation ([#1205](https://github.com/open-telemetry/opentelemetry-cpp/pull/1205)) +* [DOCS] Fix errors in SDK documentation ([#1201](https://github.com/open-telemetry/opentelemetry-cpp/pull/1201)) +* [METRICS EXPORTER] Ostream metric exporter ([#1196](https://github.com/open-telemetry/opentelemetry-cpp/pull/1196)) +* [Metrics SDK] Filtering metrics attributes ([#1191](https://github.com/open-telemetry/opentelemetry-cpp/pull/1191)) +* [Metrics SDK] Sync and Async Instruments SDK ([#1184](https://github.com/open-telemetry/opentelemetry-cpp/pull/1184)) +* [Metrics SDK] Add Aggregation as part of metrics SDK. ([#1178](https://github.com/open-telemetry/opentelemetry-cpp/pull/1178)) +* [BUILD] Cmake: thrift requires boost headers, include them as + Boost_INCLUDE_DIRS + ([#1100](https://github.com/open-telemetry/opentelemetry-cpp/pull/1100)) + +Notes: + +[#1301](https://github.com/open-telemetry/opentelemetry-cpp/pull/1301) added +`opentelemetry_` as prefix to http_client_curl library for resolving potential +naming conflict, this could break existing cmake build if http_client_curl is +listed as explicit dependency in user's cmake file. ## [1.2.0] 2022-01-31 diff --git a/api/include/opentelemetry/version.h b/api/include/opentelemetry/version.h index 2fe333f3d4..1e01e242ed 100644 --- a/api/include/opentelemetry/version.h +++ b/api/include/opentelemetry/version.h @@ -6,7 +6,7 @@ #include "opentelemetry/detail/preprocessor.h" #define OPENTELEMETRY_ABI_VERSION_NO 1 -#define OPENTELEMETRY_VERSION "1.2.0" +#define OPENTELEMETRY_VERSION "1.3.0" #define OPENTELEMETRY_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_ABI_VERSION_NO) // clang-format off diff --git a/docs/public/conf.py b/docs/public/conf.py index cd6c7ec6df..910cfc6346 100644 --- a/docs/public/conf.py +++ b/docs/public/conf.py @@ -21,7 +21,7 @@ author = 'OpenTelemetry authors' # The full version, including alpha/beta/rc tags -release = '1.2.0' +release = '1.3.0' # Run sphinx on subprojects and copy output # ----------------------------------------- diff --git a/sdk/include/opentelemetry/sdk/version/version.h b/sdk/include/opentelemetry/sdk/version/version.h index 3155ea8e0b..155cba3f87 100644 --- a/sdk/include/opentelemetry/sdk/version/version.h +++ b/sdk/include/opentelemetry/sdk/version/version.h @@ -5,7 +5,7 @@ #include "opentelemetry/detail/preprocessor.h" -#define OPENTELEMETRY_SDK_VERSION "1.2.0" +#define OPENTELEMETRY_SDK_VERSION "1.3.0" #include "opentelemetry/version.h" diff --git a/sdk/src/version/version.cc b/sdk/src/version/version.cc index 9c4aadf1c9..a153196514 100644 --- a/sdk/src/version/version.cc +++ b/sdk/src/version/version.cc @@ -9,7 +9,7 @@ namespace sdk namespace version { const int MAJOR_VERSION = 1; -const int MINOR_VERSION = 2; +const int MINOR_VERSION = 3; const int PATCH_VERSION = 0; const char *PRE_RELEASE = ""; const char *BUILD_METADATA = ""; From 75c2a8f7a6bf81d9799e76804473609cc236b7be Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 12 Apr 2022 14:33:39 -0700 Subject: [PATCH 24/69] Update yield logic for ARM processor (#1325) --- api/include/opentelemetry/common/spin_lock_mutex.h | 4 +--- api/test/common/spinlock_benchmark.cc | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/api/include/opentelemetry/common/spin_lock_mutex.h b/api/include/opentelemetry/common/spin_lock_mutex.h index b35f54081a..d38d5791d5 100644 --- a/api/include/opentelemetry/common/spin_lock_mutex.h +++ b/api/include/opentelemetry/common/spin_lock_mutex.h @@ -101,9 +101,7 @@ class SpinLockMutex __builtin_ia32_pause(); # endif #elif defined(__arm__) - // This intrinsic should fail to be found if YIELD is not supported on the current - // processor. - __yield(); + __asm__ volatile("yield" ::: "memory"); #else // TODO: Issue PAGE/YIELD on other architectures. #endif diff --git a/api/test/common/spinlock_benchmark.cc b/api/test/common/spinlock_benchmark.cc index 28692bee56..07579579c7 100644 --- a/api/test/common/spinlock_benchmark.cc +++ b/api/test/common/spinlock_benchmark.cc @@ -93,7 +93,7 @@ static void BM_ProcYieldSpinLockThrashing(benchmark::State &s) __builtin_ia32_pause(); # endif #elif defined(__arm__) - __yield(); + __asm__ volatile("yield" ::: "memory"); #endif } }, From e7f051edf72c6b162ba27fe624d2a6a05e2210d6 Mon Sep 17 00:00:00 2001 From: jmanjon <67091862+juandemanjon@users.noreply.github.com> Date: Wed, 13 Apr 2022 21:21:47 -0700 Subject: [PATCH 25/69] Fix for #1292 (#1326) --- tools/build.cmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build.cmd b/tools/build.cmd index 7558f4efff..5a47d87764 100644 --- a/tools/build.cmd +++ b/tools/build.cmd @@ -170,5 +170,5 @@ REM REM ########################################################################################## :build_config_ninja cmake -G "Ninja" -DCMAKE_MAKE_PROGRAM="!NINJA!" -DCMAKE_TOOLCHAIN_FILE="!VCPKG_CMAKE!" !CONFIG! "!ROOT!" -%NINJA% +"%NINJA%" exit /b From 29d68f1146e0082bf774685a41ad201883461d88 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 14 Apr 2022 22:23:09 +0530 Subject: [PATCH 26/69] Implement Merge and Diff operation for Histogram Aggregation (#1303) --- .../aggregation/histogram_aggregation.h | 39 +++++++++++ .../aggregation/histogram_aggregation.cc | 33 +++++++--- sdk/test/metrics/aggregation_test.cc | 64 ++++++++++++++++++- 3 files changed, 126 insertions(+), 10 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h index 8f33fa27b4..b5cc2c349e 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h @@ -24,8 +24,15 @@ class LongHistogramAggregation : public Aggregation void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} + /* Returns the result of merge of the existing aggregation with delta aggregation with same + * boundaries */ virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + /* Returns the new delta aggregation by comparing existing aggregation with next aggregation with + * same boundaries. Data points for `next` aggregation (sum , bucket-counts) should be more than + * the current aggregation - which is the normal scenario as measurements values are monotonic + * increasing. + */ virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; @@ -45,8 +52,15 @@ class DoubleHistogramAggregation : public Aggregation void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; + /* Returns the result of merge of the existing aggregation with delta aggregation with same + * boundaries */ virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + /* Returns the new delta aggregation by comparing existing aggregation with next aggregation with + * same boundaries. Data points for `next` aggregation (sum , bucket-counts) should be more than + * the current aggregation - which is the normal scenario as measurements values are monotonic + * increasing. + */ virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; @@ -56,6 +70,31 @@ class DoubleHistogramAggregation : public Aggregation mutable HistogramPointData point_data_; }; +template +void HistogramMerge(HistogramPointData ¤t, + HistogramPointData &delta, + HistogramPointData &merge) +{ + for (size_t i = 0; i < current.counts_.size(); i++) + { + merge.counts_[i] = current.counts_[i] + delta.counts_[i]; + } + merge.boundaries_ = current.boundaries_; + merge.sum_ = nostd::get(current.sum_) + nostd::get(delta.sum_); + merge.count_ = current.count_ + delta.count_; +} + +template +void HistogramDiff(HistogramPointData ¤t, HistogramPointData &next, HistogramPointData &diff) +{ + for (size_t i = 0; i < current.counts_.size(); i++) + { + diff.counts_[i] = next.counts_[i] - current.counts_[i]; + } + diff.boundaries_ = current.boundaries_; + diff.count_ = next.count_ - current.count_; +} + } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/metrics/aggregation/histogram_aggregation.cc b/sdk/src/metrics/aggregation/histogram_aggregation.cc index 60f65c51b1..27405999c9 100644 --- a/sdk/src/metrics/aggregation/histogram_aggregation.cc +++ b/sdk/src/metrics/aggregation/histogram_aggregation.cc @@ -14,7 +14,6 @@ namespace metrics LongHistogramAggregation::LongHistogramAggregation() { - point_data_.boundaries_ = std::list{0l, 5l, 10l, 25l, 50l, 75l, 100l, 250l, 500l, 1000l}; point_data_.counts_ = std::vector(nostd::get>(point_data_.boundaries_).size() + 1, 0); @@ -47,12 +46,22 @@ void LongHistogramAggregation::Aggregate(long value, const PointAttributes &attr std::unique_ptr LongHistogramAggregation::Merge( const Aggregation &delta) const noexcept { - return nullptr; + auto curr_value = nostd::get(ToPoint()); + auto delta_value = nostd::get( + (static_cast(delta).ToPoint())); + LongHistogramAggregation *aggr = new LongHistogramAggregation(); + HistogramMerge(curr_value, delta_value, aggr->point_data_); + return std::unique_ptr(aggr); } std::unique_ptr LongHistogramAggregation::Diff(const Aggregation &next) const noexcept { - return nullptr; + auto curr_value = nostd::get(ToPoint()); + auto next_value = nostd::get( + (static_cast(next).ToPoint())); + LongHistogramAggregation *aggr = new LongHistogramAggregation(); + HistogramDiff(curr_value, next_value, aggr->point_data_); + return std::unique_ptr(aggr); } PointType LongHistogramAggregation::ToPoint() const noexcept @@ -62,7 +71,6 @@ PointType LongHistogramAggregation::ToPoint() const noexcept DoubleHistogramAggregation::DoubleHistogramAggregation() { - point_data_.boundaries_ = std::list{0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0}; point_data_.counts_ = @@ -96,20 +104,27 @@ void DoubleHistogramAggregation::Aggregate(double value, const PointAttributes & std::unique_ptr DoubleHistogramAggregation::Merge( const Aggregation &delta) const noexcept { - // TODO - Implement me - return nullptr; + auto curr_value = nostd::get(ToPoint()); + auto delta_value = nostd::get( + (static_cast(delta).ToPoint())); + DoubleHistogramAggregation *aggr = new DoubleHistogramAggregation(); + HistogramMerge(curr_value, delta_value, aggr->point_data_); + return std::unique_ptr(aggr); } std::unique_ptr DoubleHistogramAggregation::Diff( const Aggregation &next) const noexcept { - // TODO - Implement me - return nullptr; + auto curr_value = nostd::get(ToPoint()); + auto next_value = nostd::get( + (static_cast(next).ToPoint())); + DoubleHistogramAggregation *aggr = new DoubleHistogramAggregation(); + HistogramDiff(curr_value, next_value, aggr->point_data_); + return std::unique_ptr(aggr); } PointType DoubleHistogramAggregation::ToPoint() const noexcept { - // TODO Implement me return point_data_; } diff --git a/sdk/test/metrics/aggregation_test.cc b/sdk/test/metrics/aggregation_test.cc index a32826b145..f8051776d1 100644 --- a/sdk/test/metrics/aggregation_test.cc +++ b/sdk/test/metrics/aggregation_test.cc @@ -90,6 +90,37 @@ TEST(Aggregation, LongHistogramAggregation) EXPECT_EQ(histogram_data.count_, 4); EXPECT_EQ(histogram_data.counts_[3], 2); EXPECT_EQ(histogram_data.counts_[8], 1); + + // Merge + LongHistogramAggregation aggr1; + aggr1.Aggregate(1l, {}); + aggr1.Aggregate(11l, {}); + aggr1.Aggregate(26l, {}); + + LongHistogramAggregation aggr2; + aggr2.Aggregate(2l, {}); + aggr2.Aggregate(3l, {}); + aggr2.Aggregate(13l, {}); + aggr2.Aggregate(28l, {}); + aggr2.Aggregate(105l, {}); + + auto aggr3 = aggr1.Merge(aggr2); + histogram_data = nostd::get(aggr3->ToPoint()); + + EXPECT_EQ(histogram_data.count_, 8); // 3 each from aggr1 and aggr2 + EXPECT_EQ(histogram_data.counts_[1], 3); // 1, 2, 3 + EXPECT_EQ(histogram_data.counts_[3], 2); // 11, 13 + EXPECT_EQ(histogram_data.counts_[4], 2); // 25, 28 + EXPECT_EQ(histogram_data.counts_[7], 1); // 105 + + // Diff + auto aggr4 = aggr1.Diff(aggr2); + histogram_data = nostd::get(aggr4->ToPoint()); + EXPECT_EQ(histogram_data.count_, 2); // aggr2:5 - aggr1:3 + EXPECT_EQ(histogram_data.counts_[1], 1); // aggr2(2, 3) - aggr1(1) + EXPECT_EQ(histogram_data.counts_[3], 0); // aggr2(13) - aggr1(11) + EXPECT_EQ(histogram_data.counts_[4], 0); // aggr2(28) - aggr1(25) + EXPECT_EQ(histogram_data.counts_[7], 1); // aggr2(105) - aggr1(0) } TEST(Aggregation, DoubleHistogramAggregation) @@ -116,5 +147,36 @@ TEST(Aggregation, DoubleHistogramAggregation) EXPECT_EQ(histogram_data.counts_[3], 2); EXPECT_EQ(histogram_data.counts_[8], 1); EXPECT_EQ(nostd::get(histogram_data.sum_), 377); + + // Merge + DoubleHistogramAggregation aggr1; + aggr1.Aggregate(1.0, {}); + aggr1.Aggregate(11.0, {}); + aggr1.Aggregate(25.1, {}); + + DoubleHistogramAggregation aggr2; + aggr2.Aggregate(2.0, {}); + aggr2.Aggregate(3.0, {}); + aggr2.Aggregate(13.0, {}); + aggr2.Aggregate(28.1, {}); + aggr2.Aggregate(105.0, {}); + + auto aggr3 = aggr1.Merge(aggr2); + histogram_data = nostd::get(aggr3->ToPoint()); + + EXPECT_EQ(histogram_data.count_, 8); // 3 each from aggr1 and aggr2 + EXPECT_EQ(histogram_data.counts_[1], 3); // 1.0, 2.0, 3.0 + EXPECT_EQ(histogram_data.counts_[3], 2); // 11.0, 13.0 + EXPECT_EQ(histogram_data.counts_[4], 2); // 25.1, 28.1 + EXPECT_EQ(histogram_data.counts_[7], 1); // 105.0 + + // Diff + auto aggr4 = aggr1.Diff(aggr2); + histogram_data = nostd::get(aggr4->ToPoint()); + EXPECT_EQ(histogram_data.count_, 2); // aggr2:5 - aggr1:3 + EXPECT_EQ(histogram_data.counts_[1], 1); // aggr2(2.0, 3.0) - aggr1(1.0) + EXPECT_EQ(histogram_data.counts_[3], 0); // aggr2(13.0) - aggr1(11.0) + EXPECT_EQ(histogram_data.counts_[4], 0); // aggr2(28.1) - aggr1(25.1) + EXPECT_EQ(histogram_data.counts_[7], 1); // aggr2(105.0) - aggr1(0) } -#endif \ No newline at end of file +#endif From e3304d7897fe72f628da5a567166970b103e17b6 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Fri, 15 Apr 2022 09:20:47 +0200 Subject: [PATCH 27/69] fix metrics compiler warnings (#1328) --- .../opentelemetry/sdk/metrics/view/attributes_processor.h | 2 ++ sdk/src/metrics/meter.cc | 2 +- sdk/test/metrics/attributes_hashmap_benchmark.cc | 5 ++--- sdk/test/metrics/attributes_hashmap_test.cc | 3 +-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index fdc4e35c53..d82607357f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -23,6 +23,8 @@ class AttributesProcessor // @returns The processed attributes virtual MetricAttributes process( const opentelemetry::common::KeyValueIterable &attributes) const noexcept = 0; + + virtual ~AttributesProcessor() = default; }; /** diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index e7ca822b6d..d5af7f9ec9 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -206,7 +206,7 @@ std::unique_ptr Meter::RegisterMetricStorage( "[Meter::RegisterMetricStorage] - Error during finding matching views." << "Some of the matching view configurations mayn't be used for metric collection"); } - return std::move(storages); + return storages; } /** collect metrics across all the meters **/ diff --git a/sdk/test/metrics/attributes_hashmap_benchmark.cc b/sdk/test/metrics/attributes_hashmap_benchmark.cc index 68160aa579..38d515a7ea 100644 --- a/sdk/test/metrics/attributes_hashmap_benchmark.cc +++ b/sdk/test/metrics/attributes_hashmap_benchmark.cc @@ -27,13 +27,12 @@ void BM_AttributseHashMap(benchmark::State &state) std::function()> create_default_aggregation = []() -> std::unique_ptr { - auto agg = std::unique_ptr(new DropAggregation); - return std::move(agg); + return std::unique_ptr(new DropAggregation); }; while (state.KeepRunning()) { - for (int i = 0; i < MAX_THREADS; i++) + for (size_t i = 0; i < MAX_THREADS; i++) { workers.push_back(std::thread([&]() { hash_map.GetOrSetDefault(attributes[i % 2], create_default_aggregation)->Aggregate(1l); diff --git a/sdk/test/metrics/attributes_hashmap_test.cc b/sdk/test/metrics/attributes_hashmap_test.cc index 454ece1ea0..610744c8e1 100644 --- a/sdk/test/metrics/attributes_hashmap_test.cc +++ b/sdk/test/metrics/attributes_hashmap_test.cc @@ -49,8 +49,7 @@ TEST(AttributesHashMap, BasicTests) // GetOrSetDefault std::function()> create_default_aggregation = []() -> std::unique_ptr { - auto agg = std::unique_ptr(new DropAggregation); - return std::move(agg); + return std::unique_ptr(new DropAggregation); }; MetricAttributes m4 = {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}; EXPECT_NO_THROW(hash_map.GetOrSetDefault(m4, create_default_aggregation)->Aggregate(1l)); From defdfd2ca7b641beb4462aa0d55331938fada38c Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 15 Apr 2022 09:08:26 -0700 Subject: [PATCH 28/69] Replace deprecated googletest API (#1327) --- sdk/test/metrics/sync_metric_storage_test.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk/test/metrics/sync_metric_storage_test.cc b/sdk/test/metrics/sync_metric_storage_test.cc index b0440fdbb3..7dfc4f9475 100644 --- a/sdk/test/metrics/sync_metric_storage_test.cc +++ b/sdk/test/metrics/sync_metric_storage_test.cc @@ -130,10 +130,10 @@ TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) return true; }); } -INSTANTIATE_TEST_CASE_P(WritableMetricStorageTestLong, - WritableMetricStorageTestFixture, - ::testing::Values(AggregationTemporality::kCumulative, - AggregationTemporality::kDelta)); +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) { @@ -238,9 +238,9 @@ TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) return true; }); } -INSTANTIATE_TEST_CASE_P(WritableMetricStorageTestDouble, - WritableMetricStorageTestFixture, - ::testing::Values(AggregationTemporality::kCumulative, - AggregationTemporality::kDelta)); +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestDouble, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); #endif From 2e9b7a1867d3700c789fe7f39d2747df9af65a33 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 15 Apr 2022 23:49:53 -0700 Subject: [PATCH 29/69] Remove redundant tail / in CMake install (#1329) --- exporters/elasticsearch/CMakeLists.txt | 2 +- exporters/etw/CMakeLists.txt | 2 +- exporters/jaeger/CMakeLists.txt | 2 +- exporters/memory/CMakeLists.txt | 2 +- exporters/ostream/CMakeLists.txt | 6 +++--- exporters/otlp/CMakeLists.txt | 2 +- exporters/prometheus/CMakeLists.txt | 2 +- exporters/zipkin/CMakeLists.txt | 2 +- sdk/CMakeLists.txt | 14 ++++---------- 9 files changed, 14 insertions(+), 20 deletions(-) diff --git a/exporters/elasticsearch/CMakeLists.txt b/exporters/elasticsearch/CMakeLists.txt index 9b2833854e..b21dae400a 100644 --- a/exporters/elasticsearch/CMakeLists.txt +++ b/exporters/elasticsearch/CMakeLists.txt @@ -21,7 +21,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/elasticsearch - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h" PATTERN "es_log_recordable.h" EXCLUDE) diff --git a/exporters/etw/CMakeLists.txt b/exporters/etw/CMakeLists.txt index 0489b41af6..47791b4abf 100644 --- a/exporters/etw/CMakeLists.txt +++ b/exporters/etw/CMakeLists.txt @@ -23,7 +23,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/etw - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h") diff --git a/exporters/jaeger/CMakeLists.txt b/exporters/jaeger/CMakeLists.txt index 6d3d8b88fb..a95c0cc941 100644 --- a/exporters/jaeger/CMakeLists.txt +++ b/exporters/jaeger/CMakeLists.txt @@ -52,7 +52,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/jaeger - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h" PATTERN "recordable.h" EXCLUDE) diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index a4b8d837fd..d489ec1606 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -17,7 +17,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/memory - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h") diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index e83719cce3..31f1e9b0d0 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -19,7 +19,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/ostream - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters PATTERN "*.h" PATTERN "metrics_exporter.h" EXCLUDE PATTERN "log_Exporter.h" EXCLUDE) @@ -52,7 +52,7 @@ if(WITH_METRICS_PREVIEW) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install( DIRECTORY include/opentelemetry/exporters/ostream - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters PATTERN "metrics_exporter.h") if(BUILD_TESTING) add_executable(ostream_metrics_test test/ostream_metrics_test.cc) @@ -82,7 +82,7 @@ if(WITH_LOGS_PREVIEW) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install( DIRECTORY include/opentelemetry/exporters/ostream - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters PATTERN "log_exporter.h") if(BUILD_TESTING) add_executable(ostream_log_test test/ostream_log_test.cc) diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 1dba7ea1c7..1b1b200504 100755 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -98,7 +98,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/otlp - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h" PATTERN "otlp_recordable.h" EXCLUDE) diff --git a/exporters/prometheus/CMakeLists.txt b/exporters/prometheus/CMakeLists.txt index 9b2c92ef73..753fa18cac 100755 --- a/exporters/prometheus/CMakeLists.txt +++ b/exporters/prometheus/CMakeLists.txt @@ -46,7 +46,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/prometheus - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h") diff --git a/exporters/zipkin/CMakeLists.txt b/exporters/zipkin/CMakeLists.txt index b82339f1ee..559e8d5001 100644 --- a/exporters/zipkin/CMakeLists.txt +++ b/exporters/zipkin/CMakeLists.txt @@ -32,7 +32,7 @@ install( install( DIRECTORY include/opentelemetry/exporters/zipkin - DESTINATION include/opentelemetry/exporters/ + DESTINATION include/opentelemetry/exporters FILES_MATCHING PATTERN "*.h" PATTERN "recordable.h" EXCLUDE) diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index 6421e3ad15..1a824fe09b 100644 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -14,8 +14,8 @@ install( ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install( - DIRECTORY include/opentelemetry/ - DESTINATION include/opentelemetry/ + DIRECTORY include/opentelemetry + DESTINATION include/opentelemetry FILES_MATCHING PATTERN "*config.h") @@ -31,16 +31,10 @@ endif() install( DIRECTORY include/opentelemetry/sdk - DESTINATION include/opentelemetry/ - FILES_MATCHING - PATTERN "*.h" - PATTERN "${METRICS_EXCLUDE_PATTERN}" EXCLUDE) - -install( - DIRECTORY include/opentelemetry/sdk - DESTINATION include/opentelemetry/ + DESTINATION include/opentelemetry FILES_MATCHING PATTERN "*.h" + PATTERN "${METRICS_EXCLUDE_PATTERN}" EXCLUDE PATTERN "${LOGS_EXCLUDE_PATTERN}" EXCLUDE) add_subdirectory(src) From 1d2cd4225da38cb8e7e95bb5c8e33b614555c0d1 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 18 Apr 2022 17:39:02 +0200 Subject: [PATCH 30/69] dependencies image as artifact (#1333) Co-authored-by: Lalit Kumar Bhasin --- .github/workflows/dependencies_image.yml | 46 ++++++++++++++++++++++++ ci/setup_grpc.sh | 10 ++++-- ci/setup_thrift.sh | 15 +++++++- docker/Dockerfile.debian.deps | 43 ++++++++++++++++++++++ 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/dependencies_image.yml create mode 100644 docker/Dockerfile.debian.deps diff --git a/.github/workflows/dependencies_image.yml b/.github/workflows/dependencies_image.yml new file mode 100644 index 0000000000..aa7d923071 --- /dev/null +++ b/.github/workflows/dependencies_image.yml @@ -0,0 +1,46 @@ +name: 'OpenTelemetry-cpp dependencies image' +on: + schedule: + - cron: "0 3 * * 6" + +jobs: + docker_image: + name: Docker Image + runs-on: ubuntu-latest + timeout-minutes: 300 + steps: + - + name: checkout + uses: actions/checkout@v2 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + - + name: Build Image + uses: docker/build-push-action@v2 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ci/ + file: ./docker/Dockerfile + build-args: BASE_IMAGE=ubuntu:latest + platforms: linux/amd64 + # platforms: linux/amd64,linux/arm64 + push: false + tags: otel-cpp-deps + load: true + - + name: Save Image + run: | + docker images + docker save -o /opt/otel-cpp-deps-debian.tar otel-cpp-deps + - + name: Upload Image + uses: actions/upload-artifact@v3 + with: + name: otel-cpp-deps + path: /opt/otel-cpp-deps-debian.tar + retention-days: 14 diff --git a/ci/setup_grpc.sh b/ci/setup_grpc.sh index 2995f7b4ba..d42fbb7d2e 100755 --- a/ci/setup_grpc.sh +++ b/ci/setup_grpc.sh @@ -10,13 +10,17 @@ new_grpc_version='v1.43.2' gcc_version_for_new_grpc='5.1' install_grpc_version=${new_grpc_version} grpc_version='v1.39.0' -usage() { echo "Usage: $0 -v " 1>&2; exit 1; } +install_dir='/usr/local/' +usage() { echo "Usage: $0 [-v ] [-i "] 1>&2; exit 1;} -while getopts ":v:" o; do +while getopts ":v:i:" o; do case "${o}" in v) gcc_version=${OPTARG} ;; + i) + install_dir=${OPTARG} + ;; *) usage ;; @@ -34,7 +38,7 @@ if ! type cmake > /dev/null; then exit 1 fi export BUILD_DIR=/tmp/ -export INSTALL_DIR=/usr/local/ +export INSTALL_DIR=${install_dir} pushd $BUILD_DIR echo "installing grpc version: ${install_grpc_version}" git clone --depth=1 -b ${install_grpc_version} https://github.com/grpc/grpc diff --git a/ci/setup_thrift.sh b/ci/setup_thrift.sh index af8cc3ffc8..98e14d5e71 100755 --- a/ci/setup_thrift.sh +++ b/ci/setup_thrift.sh @@ -4,6 +4,17 @@ set -e export DEBIAN_FRONTEND=noninteractive export THRIFT_VERSION=0.14.1 +install_dir='/usr/local/' +while getopts ":i:" o; do + case "${o}" in + i) + install_dir=${OPTARG} + ;; + *) + ;; + esac +done + apt update if ! type cmake > /dev/null; then @@ -11,7 +22,7 @@ if ! type cmake > /dev/null; then exit 1 fi export BUILD_DIR=/tmp/ -export INSTALL_DIR=/usr/local/ +export INSTALL_DIR=${install_dir} apt install -y --no-install-recommends \ libboost-locale-dev \ @@ -44,6 +55,8 @@ cmake -G Ninja .. \ -DWITH_BOOSTTHREADS=OFF \ -DWITH_BOOST_FUNCTIONAL=OFF \ -DWITH_BOOST_SMART_PTR=OFF \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ + -DCMAKE_PREFIX_PATH=$INSTALL_DIR \ .. ninja -j $(nproc) diff --git a/docker/Dockerfile.debian.deps b/docker/Dockerfile.debian.deps new file mode 100644 index 0000000000..0634c11970 --- /dev/null +++ b/docker/Dockerfile.debian.deps @@ -0,0 +1,43 @@ +ARG BASE_IMAGE=ubuntu:latest +ARG CORES=${nproc} + +FROM ${BASE_IMAGE} as base + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y build-essential autoconf \ + libtool pkg-config cmake git libssl-dev curl \ + libcurl4-openssl-dev libgtest-dev libgmock-dev libbenchmark-dev + +WORKDIR /work +RUN mkdir -p /opt/otel-cpp + +FROM base as grpc +# install grpc, protobuf and abseil +ARG GRPC_VERSION=1.43.2 + +ADD setup_grpc.sh . +RUN ./setup_grpc.sh -i "/opt/otel-cpp" -v ${GRPC_VERSION} + +FROM base as thrift +RUN apt-get install -y --no-install-recommends wget + +# install thrift +ARG THRIFT_VERSION=0.14.1 +ADD setup_thrift.sh . +RUN ./setup_thrift.sh -i "/opt/otel-cpp" + +FROM scratch as final + +COPY --from=grpc /opt/otel-cpp / +COPY --from=thrift /opt/otel-cpp / + +# how to use: +# +# docker create -ti --name deps otel-cpp-deps bash +# docker cp deps:/ ./ +# docker rm -f deps +# +# or: +# +# COPY --from=otel-cpp-deps /usr From b33dd0920ad71f3c04f40e753d3167beabca9dcb Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 18 Apr 2022 18:37:01 +0200 Subject: [PATCH 31/69] metrics histogram example (#1330) --- .../common/metrics_foo_library/foo_library.cc | 53 +++++++++++++++---- .../common/metrics_foo_library/foo_library.h | 7 ++- examples/metrics_simple/metrics_ostream.cc | 47 ++++++++++++++-- exporters/ostream/src/metric_exporter.cc | 2 + 4 files changed, 94 insertions(+), 15 deletions(-) diff --git a/examples/common/metrics_foo_library/foo_library.cc b/examples/common/metrics_foo_library/foo_library.cc index 344f51c082..cd15adad5b 100644 --- a/examples/common/metrics_foo_library/foo_library.cc +++ b/examples/common/metrics_foo_library/foo_library.cc @@ -2,24 +2,59 @@ // SPDX-License-Identifier: Apache-2.0 #ifndef ENABLE_METRICS_PREVIEW +# include "foo_library.h" # include +# include # include # include "opentelemetry/metrics/provider.h" namespace nostd = opentelemetry::nostd; namespace metrics_api = opentelemetry::metrics; -void foo_library(const std::string &name) +namespace { - // Get the Meter from the MeterProvider +std::map get_random_attr() +{ + static const std::vector> labels = {{"key1", "value1"}, + {"key2", "value2"}, + {"key3", "value3"}, + {"key4", "value4"}, + {"key5", "value5"}}; + return std::map{labels[rand() % (labels.size() - 1)], + labels[rand() % (labels.size() - 1)]}; +} +} // namespace + +void foo_library::counter_example(const std::string &name) +{ + std::string counter_name = name + "_counter"; auto provider = metrics_api::Provider::GetMeterProvider(); nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); - auto double_counter = meter->CreateDoubleCounter(name); - double_counter->Add(28.5); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - double_counter->Add(3.14); - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - double_counter->Add(23.5); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + auto double_counter = meter->CreateDoubleCounter(counter_name); + + while (true) + { + double val = (rand() % 700) + 1.1; + double_counter->Add(val); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } } + +void foo_library::histogram_example(const std::string &name) +{ + std::string histogram_name = name + "_histogram"; + auto provider = metrics_api::Provider::GetMeterProvider(); + nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); + auto histogram_counter = meter->CreateDoubleHistogram(histogram_name); + auto context = opentelemetry::context::Context{}; + while (true) + { + double val = (rand() % 700) + 1.1; + std::map labels = get_random_attr(); + auto labelkv = opentelemetry::common::KeyValueIterableView{labels}; + histogram_counter->Record(val, labelkv, context); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } +} + #endif diff --git a/examples/common/metrics_foo_library/foo_library.h b/examples/common/metrics_foo_library/foo_library.h index 662646a6a4..73cd30d2d5 100644 --- a/examples/common/metrics_foo_library/foo_library.h +++ b/examples/common/metrics_foo_library/foo_library.h @@ -5,5 +5,10 @@ #ifndef ENABLE_METRICS_PREVIEW # include -void foo_library(const std::string &name); +class foo_library +{ +public: + static void counter_example(const std::string &name); + static void histogram_example(const std::string &name); +}; #endif diff --git a/examples/metrics_simple/metrics_ostream.cc b/examples/metrics_simple/metrics_ostream.cc index 9fae5f07b7..d0e4dccfeb 100644 --- a/examples/metrics_simple/metrics_ostream.cc +++ b/examples/metrics_simple/metrics_ostream.cc @@ -3,6 +3,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include +# include # include "opentelemetry/exporters/ostream/metric_exporter.h" # include "opentelemetry/metrics/provider.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" @@ -44,21 +45,57 @@ void initMetrics(const std::string &name) new metric_sdk::MeterProvider(std::move(exporters))); auto p = std::static_pointer_cast(provider); p->AddMetricReader(std::move(reader)); + + // counter view + std::string counter_name = name + "_counter"; std::unique_ptr instrument_selector{ - new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, name)}; + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, counter_name)}; std::unique_ptr meter_selector{ new metric_sdk::MeterSelector(name, version, schema)}; - std::unique_ptr view{ + std::unique_ptr sum_view{ new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; - p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + + // histogram view + std::string histogram_name = name + "_histogram"; + std::unique_ptr histogram_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, histogram_name)}; + std::unique_ptr histogram_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr histogram_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}}; + p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); metrics_api::Provider::SetMeterProvider(provider); } } // namespace -int main() + +int main(int argc, char **argv) { + std::string example_type; + if (argc >= 2) + { + example_type = argv[1]; + } + std::string name{"ostream_metric_example"}; initMetrics(name); - foo_library(name); + + if (example_type == "counter") + { + foo_library::counter_example(name); + } + else if (example_type == "histogram") + { + foo_library::histogram_example(name); + } + else + { + std::thread counter_example{&foo_library::counter_example, name}; + std::thread histogram_example{&foo_library::histogram_example, name}; + counter_example.join(); + histogram_example.join(); + } } #else int main() {} diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index fad9e03d49..5cdd3fe78d 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -59,6 +59,8 @@ sdk::common::ExportResult OStreamMetricExporter::Export( void OStreamMetricExporter::printInstrumentationInfoMetricData( const sdk::metrics::InstrumentationInfoMetrics &info_metric) { + // sout_ is shared + const std::lock_guard locked(lock_); sout_ << "{"; sout_ << "\n name\t\t: " << info_metric.instrumentation_library_->GetName() << "\n schema url\t: " << info_metric.instrumentation_library_->GetSchemaURL() From 7fde3bc7928a4ae55e5502ff6934454a23c3a384 Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Fri, 22 Apr 2022 00:46:29 +0800 Subject: [PATCH 32/69] Link `opentelemetry_ext` with `opentelemetry_api` (#1336) --- ext/CMakeLists.txt | 1 + ext/src/http/client/nosend/CMakeLists.txt | 2 +- ext/src/zpages/CMakeLists.txt | 5 ++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index a2baa47a32..034328eaa5 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -5,6 +5,7 @@ target_include_directories( "$") set_target_properties(opentelemetry_ext PROPERTIES EXPORT_NAME "ext") +target_link_libraries(opentelemetry_ext INTERFACE opentelemetry_api) install( TARGETS opentelemetry_ext diff --git a/ext/src/http/client/nosend/CMakeLists.txt b/ext/src/http/client/nosend/CMakeLists.txt index 9118abbfb5..497daeb342 100644 --- a/ext/src/http/client/nosend/CMakeLists.txt +++ b/ext/src/http/client/nosend/CMakeLists.txt @@ -25,7 +25,7 @@ if(${BUILD_TESTING}) endif() target_link_libraries(http_client_nosend ${GTEST_BOTH_LIBRARIES} ${GMOCK_LIB} - opentelemetry_api opentelemetry_ext) + opentelemetry_ext) install( TARGETS http_client_nosend diff --git a/ext/src/zpages/CMakeLists.txt b/ext/src/zpages/CMakeLists.txt index 64d9c73728..e3fd480df6 100644 --- a/ext/src/zpages/CMakeLists.txt +++ b/ext/src/zpages/CMakeLists.txt @@ -10,9 +10,8 @@ add_library( set_target_properties(opentelemetry_zpages PROPERTIES EXPORT_NAME zpages) -target_link_libraries( - opentelemetry_zpages PUBLIC opentelemetry_ext opentelemetry_api - opentelemetry_trace) +target_link_libraries(opentelemetry_zpages PUBLIC opentelemetry_ext + opentelemetry_trace) install( TARGETS opentelemetry_zpages From bf8f433cae41ad682cf9e390650158a2751373c1 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Thu, 21 Apr 2022 23:27:19 +0200 Subject: [PATCH 33/69] ostream metrics cmake (#1344) --- examples/CMakeLists.txt | 4 +-- examples/common/CMakeLists.txt | 1 + .../common/metrics_foo_library/CMakeLists.txt | 2 ++ examples/metrics_simple/CMakeLists.txt | 17 +++++++---- exporters/ostream/CMakeLists.txt | 29 +++++++++++++++++++ 5 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 examples/common/metrics_foo_library/CMakeLists.txt diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 70bca10221..db0fe159be 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -18,9 +18,7 @@ endif() add_subdirectory(plugin) add_subdirectory(simple) add_subdirectory(batch) -if(WITH_METRICS_PREVIEW) - add_subdirectory(metrics_simple) -endif() +add_subdirectory(metrics_simple) add_subdirectory(multithreaded) add_subdirectory(multi_processor) add_subdirectory(http) diff --git a/examples/common/CMakeLists.txt b/examples/common/CMakeLists.txt index f89faf4a2f..c2fdca2594 100644 --- a/examples/common/CMakeLists.txt +++ b/examples/common/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(foo_library) if(WITH_LOGS_PREVIEW) add_subdirectory(logs_foo_library) endif() +add_subdirectory(metrics_foo_library) diff --git a/examples/common/metrics_foo_library/CMakeLists.txt b/examples/common/metrics_foo_library/CMakeLists.txt new file mode 100644 index 0000000000..4f2bca2a0b --- /dev/null +++ b/examples/common/metrics_foo_library/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(common_metrics_foo_library foo_library.h foo_library.cc) +target_link_libraries(common_metrics_foo_library PUBLIC opentelemetry_api) diff --git a/examples/metrics_simple/CMakeLists.txt b/examples/metrics_simple/CMakeLists.txt index 94b441061b..a2088fd510 100644 --- a/examples/metrics_simple/CMakeLists.txt +++ b/examples/metrics_simple/CMakeLists.txt @@ -1,6 +1,13 @@ include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include) - -add_executable(simple_metrics main.cc) -target_link_libraries( - simple_metrics ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics_deprecated - opentelemetry_exporter_ostream_metrics_deprecated) +if(WITH_METRICS_PREVIEW) + add_executable(simple_metrics main.cc) + target_link_libraries( + simple_metrics ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics_deprecated + opentelemetry_exporter_ostream_metrics_deprecated) +else() + add_executable(metrics_ostream_example metrics_ostream.cc) + target_link_libraries( + metrics_ostream_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics + opentelemetry_exporter_ostream_metrics opentelemetry_resources + common_metrics_foo_library) +endif() diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index 31f1e9b0d0..db2562ddde 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -63,6 +63,35 @@ if(WITH_METRICS_PREVIEW) TEST_PREFIX exporter. TEST_LIST ostream_metrics_test) endif() +else() + add_library(opentelemetry_exporter_ostream_metrics src/metric_exporter.cc) + set_target_properties(opentelemetry_exporter_ostream_metrics + PROPERTIES EXPORT_NAME ostream_metrics_exporter) + target_include_directories( + opentelemetry_exporter_ostream_metrics + PUBLIC "$") + target_link_libraries(opentelemetry_exporter_ostream_metrics + PUBLIC opentelemetry_metrics) + install( + TARGETS opentelemetry_exporter_ostream_metrics + EXPORT "${PROJECT_NAME}-target" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install( + DIRECTORY include/opentelemetry/exporters/ostream + DESTINATION include/opentelemetry/exporters + PATTERN "metric_exporter.h") + if(BUILD_TESTING) + add_executable(ostream_metric_test test/ostream_metric_test.cc) + target_link_libraries( + ostream_metric_test ${GTEST_BOTH_LIBRARIES} + opentelemetry_exporter_ostream_metrics opentelemetry_resources) + gtest_add_tests( + TARGET ostream_metric_test + TEST_PREFIX exporter. + TEST_LIST ostream_metric_test) + endif() endif() if(WITH_LOGS_PREVIEW) From e6fb935f75c9c5a34ca3422ebdb47bb7e620f405 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 25 Apr 2022 18:48:11 +0200 Subject: [PATCH 34/69] prometheus exporter (#1331) --- exporters/CMakeLists.txt | 2 +- exporters/prometheus/BUILD | 73 +++- exporters/prometheus/CMakeLists.txt | 99 ++++-- .../exporters/prometheus/collector.h | 87 +++++ .../exporters/prometheus/exporter.h | 126 +++++++ .../exporters/prometheus/exporter_utils.h | 129 +++++++ exporters/prometheus/src/collector.cc | 89 +++++ exporters/prometheus/src/exporter.cc | 100 ++++++ exporters/prometheus/src/exporter_utils.cc | 327 ++++++++++++++++++ 9 files changed, 991 insertions(+), 41 deletions(-) create mode 100644 exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h create mode 100644 exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h create mode 100644 exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h create mode 100644 exporters/prometheus/src/collector.cc create mode 100644 exporters/prometheus/src/exporter.cc create mode 100644 exporters/prometheus/src/exporter_utils.cc diff --git a/exporters/CMakeLists.txt b/exporters/CMakeLists.txt index 2ae8fd92bb..862d2c779e 100644 --- a/exporters/CMakeLists.txt +++ b/exporters/CMakeLists.txt @@ -19,7 +19,7 @@ endif() add_subdirectory(ostream) add_subdirectory(memory) -if(WITH_PROMETHEUS AND WITH_METRICS_PREVIEW) +if(WITH_PROMETHEUS) add_subdirectory(prometheus) endif() diff --git a/exporters/prometheus/BUILD b/exporters/prometheus/BUILD index e92f9412eb..47c9bbab16 100644 --- a/exporters/prometheus/BUILD +++ b/exporters/prometheus/BUILD @@ -15,7 +15,7 @@ package(default_visibility = ["//visibility:public"]) cc_library( - name = "prometheus_exporter", + name = "prometheus_exporter_deprecated", srcs = [ "src/prometheus_exporter.cc", ], @@ -25,8 +25,8 @@ cc_library( strip_include_prefix = "include", tags = ["prometheus"], deps = [ - ":prometheus_collector", - ":prometheus_exporter_utils", + ":prometheus_collector_deprecated", + ":prometheus_exporter_utils_deprecated", "//api", "//sdk:headers", "@com_github_jupp0r_prometheus_cpp//core", @@ -35,7 +35,7 @@ cc_library( ) cc_library( - name = "prometheus_exporter_utils", + name = "prometheus_exporter_utils_deprecated", srcs = [ "src/prometheus_exporter_utils.cc", ], @@ -53,7 +53,7 @@ cc_library( ) cc_library( - name = "prometheus_collector", + name = "prometheus_collector_deprecated", srcs = [ "src/prometheus_collector.cc", ], @@ -63,7 +63,7 @@ cc_library( strip_include_prefix = "include", tags = ["prometheus"], deps = [ - ":prometheus_exporter_utils", + ":prometheus_exporter_utils_deprecated", "//api", "//sdk:headers", "@com_github_jupp0r_prometheus_cpp//core", @@ -72,7 +72,7 @@ cc_library( ) cc_test( - name = "prometheus_exporter_test", + name = "prometheus_exporter_test_deprecated", srcs = [ "test/prometheus_exporter_test.cc", ], @@ -81,7 +81,64 @@ cc_test( "test", ], deps = [ - ":prometheus_exporter", + ":prometheus_exporter_deprecated", "@com_google_googletest//:gtest_main", ], ) + +cc_library( + name = "prometheus_exporter", + srcs = [ + "src/exporter.cc", + ], + hdrs = [ + "include/opentelemetry/exporters/prometheus/exporter.h", + ], + strip_include_prefix = "include", + tags = ["prometheus"], + deps = [ + ":prometheus_collector", + ":prometheus_exporter_utils", + "//api", + "//sdk:headers", + "@com_github_jupp0r_prometheus_cpp//core", + "@com_github_jupp0r_prometheus_cpp//pull", + ], +) + +cc_library( + name = "prometheus_exporter_utils", + srcs = [ + "src/exporter_utils.cc", + ], + hdrs = [ + "include/opentelemetry/exporters/prometheus/exporter_utils.h", + ], + strip_include_prefix = "include", + tags = ["prometheus"], + deps = [ + "//api", + "//sdk:headers", + "@com_github_jupp0r_prometheus_cpp//core", + "@com_github_jupp0r_prometheus_cpp//pull", + ], +) + +cc_library( + name = "prometheus_collector", + srcs = [ + "src/collector.cc", + ], + hdrs = [ + "include/opentelemetry/exporters/prometheus/collector.h", + ], + strip_include_prefix = "include", + tags = ["prometheus"], + deps = [ + ":prometheus_exporter_utils", + "//api", + "//sdk:headers", + "@com_github_jupp0r_prometheus_cpp//core", + "@com_github_jupp0r_prometheus_cpp//pull", + ], +) diff --git a/exporters/prometheus/CMakeLists.txt b/exporters/prometheus/CMakeLists.txt index 753fa18cac..56523ec848 100755 --- a/exporters/prometheus/CMakeLists.txt +++ b/exporters/prometheus/CMakeLists.txt @@ -16,40 +16,75 @@ include_directories(include) if(NOT TARGET prometheus-cpp::core) find_package(prometheus-cpp CONFIG REQUIRED) endif() +if(WITH_METRICS_PREVIEW) + add_library( + prometheus_exporter_deprecated + src/prometheus_exporter.cc src/prometheus_collector.cc + src/prometheus_exporter_utils.cc) + target_include_directories( + prometheus_exporter_deprecated + PUBLIC "$" + "$") -add_library( - prometheus_exporter_deprecated - src/prometheus_exporter.cc src/prometheus_collector.cc - src/prometheus_exporter_utils.cc) -target_include_directories( - prometheus_exporter_deprecated - PUBLIC "$" - "$") + set(PROMETHEUS_EXPORTER_TARGETS_DEPRECATED prometheus_exporter_deprecated) + if(TARGET pull) + list(APPEND PROMETHEUS_EXPORTER_TARGETS_DEPRECATED pull) + endif() + if(TARGET core) + list(APPEND PROMETHEUS_EXPORTER_TARGETS_DEPRECATED core) + endif() + target_link_libraries( + prometheus_exporter_deprecated + PUBLIC opentelemetry_metrics_deprecated prometheus-cpp::pull + prometheus-cpp::core) + install( + TARGETS ${PROMETHEUS_EXPORTER_TARGETS_DEPRECATED} + EXPORT "${PROJECT_NAME}-target" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -set(PROMETHEUS_EXPORTER_TARGETS prometheus_exporter_deprecated) -if(TARGET pull) - list(APPEND PROMETHEUS_EXPORTER_TARGETS pull) -endif() -if(TARGET core) - list(APPEND PROMETHEUS_EXPORTER_TARGETS core) -endif() -target_link_libraries( - prometheus_exporter_deprecated - PUBLIC opentelemetry_metrics_deprecated prometheus-cpp::pull - prometheus-cpp::core) -install( - TARGETS ${PROMETHEUS_EXPORTER_TARGETS} - EXPORT "${PROJECT_NAME}-target" - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install( + DIRECTORY include/opentelemetry/exporters/prometheus + DESTINATION include/opentelemetry/exporters/ + FILES_MATCHING + PATTERN "*.h") + if(BUILD_TESTING) + add_subdirectory(test) + endif() +else() + + add_library(prometheus_exporter src/exporter.cc src/collector.cc + src/exporter_utils.cc) + target_include_directories( + prometheus_exporter + PUBLIC "$" + "$") + + set(PROMETHEUS_EXPORTER_TARGETS prometheus_exporter) + if(TARGET pull) + list(APPEND PROMETHEUS_EXPORTER_TARGETS pull) + endif() + if(TARGET core) + list(APPEND PROMETHEUS_EXPORTER_TARGETS core) + endif() + target_link_libraries( + prometheus_exporter PUBLIC opentelemetry_metrics prometheus-cpp::pull + prometheus-cpp::core) + install( + TARGETS ${PROMETHEUS_EXPORTER_TARGETS} + EXPORT "${PROJECT_NAME}-target" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install( - DIRECTORY include/opentelemetry/exporters/prometheus - DESTINATION include/opentelemetry/exporters - FILES_MATCHING - PATTERN "*.h") + install( + DIRECTORY include/opentelemetry/exporters/prometheus + DESTINATION include/opentelemetry/exporters/ + FILES_MATCHING + PATTERN "*.h") -if(BUILD_TESTING) - add_subdirectory(test) + if(BUILD_TESTING) + add_subdirectory(test) + endif() endif() diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h new file mode 100644 index 0000000000..68f50d29fa --- /dev/null +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h @@ -0,0 +1,87 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW + +# include +# include +# include + +# include +# include +# include "opentelemetry/exporters/prometheus/exporter_utils.h" + +namespace prometheus_client = ::prometheus; + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace metrics +{ +/** + * The Prometheus Collector maintains the intermediate collection in Prometheus Exporter + */ +class PrometheusCollector : public prometheus_client::Collectable +{ +public: + /** + * Default Constructor. + * + * This constructor initializes the collection for metrics to export + * in this class with default capacity + */ + explicit PrometheusCollector(size_t max_collection_size = 2048); + + /** + * Collects all metrics data from metricsToCollect collection. + * + * @return all metrics in the metricsToCollect snapshot + */ + std::vector Collect() const override; + + /** + * This function is called by export() function and add the collection of + * records to the metricsToCollect collection + * + * @param records a collection of records to add to the metricsToCollect collection + */ + void AddMetricData(const sdk::metrics::ResourceMetrics &data); + + /** + * Get the current collection in the collector. + * + * @return the current metricsToCollect collection + */ + std::vector> &GetCollection(); + + /** + * Gets the maximum size of the collection. + * + * @return max collection size + */ + int GetMaxCollectionSize() const; + +private: + /** + * Collection of metrics data from the export() function, and to be export + * to user when they send a pull request. This collection is a pointer + * to a collection so Collect() is able to clear the collection, even + * though it is a const function. + */ + mutable std::vector> metrics_to_collect_; + + /** + * Maximum size of the metricsToCollect collection. + */ + size_t max_collection_size_; + + /* + * Lock when operating the metricsToCollect collection + */ + mutable std::mutex collection_lock_; +}; +} // namespace metrics +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h new file mode 100644 index 0000000000..6945f09bb9 --- /dev/null +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h @@ -0,0 +1,126 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include + +# include +# include "opentelemetry/common/spin_lock_mutex.h" +# include "opentelemetry/exporters/prometheus/collector.h" +# include "opentelemetry/nostd/span.h" +# include "opentelemetry/sdk/common/env_variables.h" +# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/version.h" + +/** + * This class is an implementation of the MetricsExporter interface and + * exports Prometheus metrics data. Functions in this class should be + * called by the Controller in our data pipeline. + */ + +OPENTELEMETRY_BEGIN_NAMESPACE + +namespace exporter +{ +namespace metrics +{ + +inline const std::string GetOtlpDefaultHttpEndpoint() +{ + constexpr char kPrometheusEndpointEnv[] = "PROMETHEUS_EXPORTER_ENDPOINT"; + constexpr char kPrometheusEndpointDefault[] = "http://localhost:8080"; + + auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kPrometheusEndpointEnv); + return endpoint.size() ? endpoint : kPrometheusEndpointDefault; +} + +/** + * Struct to hold Prometheus exporter options. + */ +struct PrometheusExporterOptions +{ + // The endpoint the Prometheus backend can collect metrics from + std::string url = GetOtlpDefaultHttpEndpoint(); +}; + +class PrometheusExporter : public sdk::metrics::MetricExporter +{ +public: + /** + * Constructor - binds an exposer and collector to the exporter + * @param options: options for an exposer that exposes + * an HTTP endpoint for the exporter to connect to + */ + PrometheusExporter(const PrometheusExporterOptions &options); + + /** + * Exports a batch of Metric Records. + * @param records: a collection of records to export + * @return: returns a ReturnCode detailing a success, or type of failure + */ + sdk::common::ExportResult Export(const sdk::metrics::ResourceMetrics &data) noexcept override; + + /** + * Force flush the exporter. + */ + bool ForceFlush( + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; + + /** + * Shuts down the exporter and does cleanup. + * Since Prometheus is a pull based interface, + * we cannot serve data remaining in the intermediate + * collection to to client an HTTP request being sent, + * so we flush the data. + */ + bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept override; + + /** + * @return: returns a shared_ptr to + * the PrometheusCollector instance + */ + std::shared_ptr &GetCollector(); + + /** + * @return: Gets the shutdown status of the exporter + */ + bool IsShutdown() const; + +private: + // The configuration options associated with this exporter. + const PrometheusExporterOptions options_; + /** + * exporter shutdown status + */ + bool is_shutdown_; + + /** + * Pointer to a + * PrometheusCollector instance + */ + std::shared_ptr collector_; + + /** + * Pointer to an + * Exposer instance + */ + std::unique_ptr<::prometheus::Exposer> exposer_; + + /** + * friend class for testing + */ + friend class PrometheusExporterTest; + + /** + * PrometheusExporter constructor with no parameters + * Used for testing only + */ + PrometheusExporter(); +}; +} // namespace metrics +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE +#endif // ENABLE_METRICS_PREVIEW diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h new file mode 100644 index 0000000000..1cb7202ce5 --- /dev/null +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h @@ -0,0 +1,129 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#ifndef ENABLE_METRICS_PREVIEW + +# include +# include +# include +# include "opentelemetry/metrics/provider.h" +# include "opentelemetry/sdk/metrics/meter.h" +# include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace metrics +{ +/** + * The Prometheus Utils contains utility functions for Prometheus Exporter + */ +class PrometheusExporterUtils +{ +public: + /** + * Helper function to convert OpenTelemetry metrics data collection + * to Prometheus metrics data collection + * + * @param records a collection of metrics in OpenTelemetry + * @return a collection of translated metrics that is acceptable by Prometheus + */ + static std::vector<::prometheus::MetricFamily> TranslateToPrometheus( + const std::vector> &data); + +private: + /** + * Set value to metric family according to record + */ + static void SetMetricFamily(sdk::metrics::ResourceMetrics &data, + ::prometheus::MetricFamily *metric_family); + + /** + * Sanitize the given metric name or label according to Prometheus rule. + * + * This function is needed because names in OpenTelemetry can contain + * alphanumeric characters, '_', '.', and '-', whereas in Prometheus the + * name should only contain alphanumeric characters and '_'. + */ + static std::string SanitizeNames(std::string name); + + /** + * Set value to metric family for different aggregator + */ + static void SetMetricFamilyByAggregator(const sdk::metrics::ResourceMetrics &data, + std::string labels_str, + ::prometheus::MetricFamily *metric_family); + + static opentelemetry::sdk::metrics::AggregationType getAggregationType( + const opentelemetry::sdk::metrics::PointType &point_type); + + /** + * Translate the OTel metric type to Prometheus metric type + */ + static ::prometheus::MetricType TranslateType(opentelemetry::sdk::metrics::AggregationType kind); + + /** + * Set metric data for: + * Counter => Prometheus Counter + */ + template + static void SetData(std::vector values, + const std::string &labels, + ::prometheus::MetricType type, + std::chrono::nanoseconds time, + ::prometheus::MetricFamily *metric_family); + + /** + * Set metric data for: + * Histogram => Prometheus Histogram + */ + template + static void SetData(std::vector values, + const opentelemetry::sdk::metrics::ListType &boundaries, + const std::vector &counts, + const std::string &labels, + std::chrono::nanoseconds time, + ::prometheus::MetricFamily *metric_family); + + /** + * Set time and labels to metric data + */ + static void SetMetricBasic(::prometheus::ClientMetric &metric, + std::chrono::nanoseconds time, + const std::string &labels); + + /** + * Parse a string of labels (key:value) into a vector of pairs + * {,} + * {l1:v1,l2:v2,...,} + */ + static std::vector> ParseLabel(std::string labels); + + /** + * Handle Counter and Gauge. + */ + template + static void SetValue(std::vector values, + ::prometheus::MetricType type, + ::prometheus::ClientMetric *metric); + + /** + * Handle Gauge from MinMaxSumCount + */ + static void SetValue(double value, ::prometheus::ClientMetric *metric); + + /** + * Handle Histogram + */ + template + static void SetValue(std::vector values, + const std::list &boundaries, + const std::vector &counts, + ::prometheus::ClientMetric *metric); +}; +} // namespace metrics +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/exporters/prometheus/src/collector.cc b/exporters/prometheus/src/collector.cc new file mode 100644 index 0000000000..03793a8eed --- /dev/null +++ b/exporters/prometheus/src/collector.cc @@ -0,0 +1,89 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/exporters/prometheus/collector.h" + +namespace metric_sdk = opentelemetry::sdk::metrics; + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace metrics +{ +/** + * Default Constructor. + * + * This constructor initializes the collection for metrics to export + * in this class with default capacity + */ +PrometheusCollector::PrometheusCollector(size_t max_collection_size) + : max_collection_size_(max_collection_size) +{} + +/** + * Collects all metrics data from metricsToCollect collection. + * + * @return all metrics in the metricsToCollect snapshot + */ +std::vector PrometheusCollector::Collect() const +{ + this->collection_lock_.lock(); + if (metrics_to_collect_.empty()) + { + this->collection_lock_.unlock(); + return {}; + } + + std::vector result; + + // copy the intermediate collection, and then clear it + std::vector> copied_data; + copied_data.swap(metrics_to_collect_); + this->collection_lock_.unlock(); + + result = PrometheusExporterUtils::TranslateToPrometheus(copied_data); + return result; +} + +/** + * This function is called by export() function and add the collection of + * records to the metricsToCollect collection + * + * @param records a collection of records to add to the metricsToCollect collection + */ +void PrometheusCollector::AddMetricData(const sdk::metrics::ResourceMetrics &data) +{ + collection_lock_.lock(); + if (metrics_to_collect_.size() + 1 <= max_collection_size_) + { + metrics_to_collect_.emplace_back(new sdk::metrics::ResourceMetrics{data}); + } + collection_lock_.unlock(); +} + +/** + * Get the current collection in the collector. + * + * @return the current metrics_to_collect collection + */ +std::vector> &PrometheusCollector::GetCollection() +{ + return metrics_to_collect_; +} + +/** + * Gets the maximum size of the collection. + * + * @return max collection size + */ +int PrometheusCollector::GetMaxCollectionSize() const +{ + return max_collection_size_; +} + +} // namespace metrics +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/exporters/prometheus/src/exporter.cc b/exporters/prometheus/src/exporter.cc new file mode 100644 index 0000000000..a0bd9e27ab --- /dev/null +++ b/exporters/prometheus/src/exporter.cc @@ -0,0 +1,100 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/exporters/prometheus/exporter.h" + +OPENTELEMETRY_BEGIN_NAMESPACE + +namespace exporter +{ +namespace metrics +{ +/** + * Constructor - binds an exposer and collector to the exporter + * @param address: an address for an exposer that exposes + * an HTTP endpoint for the exporter to connect to + */ +PrometheusExporter::PrometheusExporter(const PrometheusExporterOptions &options) + : options_(options), is_shutdown_(false) +{ + exposer_ = std::unique_ptr<::prometheus::Exposer>(new ::prometheus::Exposer{options_.url}); + collector_ = std::shared_ptr(new PrometheusCollector); + + exposer_->RegisterCollectable(collector_); +} + +/** + * PrometheusExporter constructor with no parameters + * Used for testing only + */ +PrometheusExporter::PrometheusExporter() : is_shutdown_(false) +{ + collector_ = std::unique_ptr(new PrometheusCollector); +} + +/** + * Exports a batch of Metric Records. + * @param records: a collection of records to export + * @return: returns a ReturnCode detailing a success, or type of failure + */ +sdk::common::ExportResult PrometheusExporter::Export( + const sdk::metrics::ResourceMetrics &data) noexcept +{ + if (is_shutdown_) + { + return sdk::common::ExportResult::kFailure; + } + else if (collector_->GetCollection().size() + 1 > (size_t)collector_->GetMaxCollectionSize()) + { + return sdk::common::ExportResult::kFailureFull; + } + else + { + collector_->AddMetricData(data); + return sdk::common::ExportResult::kSuccess; + } + return sdk::common::ExportResult::kSuccess; +} + +bool PrometheusExporter::ForceFlush(std::chrono::microseconds timeout) noexcept +{ + return true; +} + +/** + * Shuts down the exporter and does cleanup. + * Since Prometheus is a pull based interface, + * we cannot serve data remaining in the intermediate + * collection to to client an HTTP request being sent, + * so we flush the data. + */ +bool PrometheusExporter::Shutdown(std::chrono::microseconds timeout) noexcept +{ + is_shutdown_ = true; + return true; + + collector_->GetCollection().clear(); +} + +/** + * @return: returns a shared_ptr to + * the PrometheusCollector instance + */ +std::shared_ptr &PrometheusExporter::GetCollector() +{ + return collector_; +} + +/** + * @return: Gets the shutdown status of the exporter + */ +bool PrometheusExporter::IsShutdown() const +{ + return is_shutdown_; +} + +} // namespace metrics +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE +#endif // ENABLE_METRICS_PREVIEW diff --git a/exporters/prometheus/src/exporter_utils.cc b/exporters/prometheus/src/exporter_utils.cc new file mode 100644 index 0000000000..39131e210f --- /dev/null +++ b/exporters/prometheus/src/exporter_utils.cc @@ -0,0 +1,327 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include + +# include +# include "opentelemetry/exporters/prometheus/exporter_utils.h" +# include "opentelemetry/sdk/metrics/export/metric_producer.h" + +namespace prometheus_client = ::prometheus; +namespace metric_sdk = opentelemetry::sdk::metrics; + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace metrics +{ +/** + * Helper function to convert OpenTelemetry metrics data collection + * to Prometheus metrics data collection + * + * @param records a collection of metrics in OpenTelemetry + * @return a collection of translated metrics that is acceptable by Prometheus + */ +std::vector PrometheusExporterUtils::TranslateToPrometheus( + const std::vector> &data) +{ + if (data.empty()) + { + return {}; + } + + // initialize output vector + std::vector output(data.size()); + + // iterate through the vector and set result data into it + int i = 0; + for (const auto &r : data) + { + SetMetricFamily(*r, &output[i]); + i++; + } + + return output; +} + +/** + * Set value to metric family according to record + */ +void PrometheusExporterUtils::SetMetricFamily(sdk::metrics::ResourceMetrics &data, + prometheus_client::MetricFamily *metric_family) +{ + SetMetricFamilyByAggregator(data, "", metric_family); +} + +/** + * Sanitize the given metric name or label according to Prometheus rule. + * + * This function is needed because names in OpenTelemetry can contain + * alphanumeric characters, '_', '.', and '-', whereas in Prometheus the + * name should only contain alphanumeric characters and '_'. + */ +std::string PrometheusExporterUtils::SanitizeNames(std::string name) +{ + // replace all '.' and '-' with '_' + std::replace(name.begin(), name.end(), '.', '_'); + std::replace(name.begin(), name.end(), '-', '_'); + + return name; +} + +/** + * Set value to metric family for different aggregator + */ +void PrometheusExporterUtils::SetMetricFamilyByAggregator( + const sdk::metrics::ResourceMetrics &data, + std::string labels_str, + prometheus_client::MetricFamily *metric_family) +{ + for (const auto &instrumentation_info : data.instrumentation_info_metric_data_) + { + auto origin_name = instrumentation_info.instrumentation_library_->GetName(); + auto sanitized = SanitizeNames(origin_name); + metric_family->name = sanitized; + for (const auto &metric_data : instrumentation_info.metric_data_) + { + auto time = metric_data.start_ts.time_since_epoch(); + for (const auto &point_data_attr : metric_data.point_data_attr_) + { + auto kind = getAggregationType(point_data_attr.point_data); + const prometheus_client::MetricType type = TranslateType(kind); + metric_family->type = type; + if (type == prometheus_client::MetricType::Histogram) // Histogram + { + auto histogram_point_data = + nostd::get(point_data_attr.point_data); + auto boundaries = histogram_point_data.boundaries_; + auto counts = histogram_point_data.counts_; + SetData(std::vector{nostd::get(histogram_point_data.sum_), + (double)histogram_point_data.count_}, + boundaries, counts, labels_str, time, metric_family); + } + else // Counter, Untyped + { + auto sum_point_data = nostd::get(point_data_attr.point_data); + std::vector values{sum_point_data.value_}; + SetData(values, labels_str, type, time, metric_family); + } + } + } + } +} + +metric_sdk::AggregationType PrometheusExporterUtils::getAggregationType( + const metric_sdk::PointType &point_type) +{ + if (nostd::holds_alternative(point_type)) + { + return metric_sdk::AggregationType::kSum; + } + else if (nostd::holds_alternative(point_type)) + { + return metric_sdk::AggregationType::kDrop; + } + else if (nostd::holds_alternative(point_type)) + { + return metric_sdk::AggregationType::kHistogram; + } + else if (nostd::holds_alternative(point_type)) + { + return metric_sdk::AggregationType::kLastValue; + } + return metric_sdk::AggregationType::kDefault; +} + +/** + * Translate the OTel metric type to Prometheus metric type + */ +prometheus_client::MetricType PrometheusExporterUtils::TranslateType( + metric_sdk::AggregationType kind) +{ + switch (kind) + { + case metric_sdk::AggregationType::kSum: + return prometheus_client::MetricType::Counter; + case metric_sdk::AggregationType::kHistogram: + return prometheus_client::MetricType::Histogram; + default: + return prometheus_client::MetricType::Untyped; + } +} + +/** + * Set metric data for: + * sum => Prometheus Counter + */ +template +void PrometheusExporterUtils::SetData(std::vector values, + const std::string &labels, + prometheus_client::MetricType type, + std::chrono::nanoseconds time, + prometheus_client::MetricFamily *metric_family) +{ + metric_family->metric.emplace_back(); + prometheus_client::ClientMetric &metric = metric_family->metric.back(); + SetMetricBasic(metric, time, labels); + SetValue(values, type, &metric); +} + +/** + * Set metric data for: + * Histogram => Prometheus Histogram + */ +template +void PrometheusExporterUtils::SetData(std::vector values, + const opentelemetry::sdk::metrics::ListType &boundaries, + const std::vector &counts, + const std::string &labels, + std::chrono::nanoseconds time, + prometheus_client::MetricFamily *metric_family) +{ + metric_family->metric.emplace_back(); + prometheus_client::ClientMetric &metric = metric_family->metric.back(); + SetMetricBasic(metric, time, labels); + if (nostd::holds_alternative>(boundaries)) + { + SetValue(values, nostd::get>(boundaries), counts, &metric); + } + else + { + SetValue(values, nostd::get>(boundaries), counts, &metric); + } +} + +/** + * Set time and labels to metric data + */ +void PrometheusExporterUtils::SetMetricBasic(prometheus_client::ClientMetric &metric, + std::chrono::nanoseconds time, + const std::string &labels) +{ + metric.timestamp_ms = time.count() / 1000000; + + auto label_pairs = ParseLabel(labels); + if (!label_pairs.empty()) + { + metric.label.resize(label_pairs.size()); + for (size_t i = 0; i < label_pairs.size(); ++i) + { + auto origin_name = label_pairs[i].first; + auto sanitized = SanitizeNames(origin_name); + metric.label[i].name = sanitized; + metric.label[i].value = label_pairs[i].second; + } + } +}; + +/** + * Parse a string of labels (key:value) into a vector of pairs + * {,} + * {l1:v1,l2:v2,...,} + */ +std::vector> PrometheusExporterUtils::ParseLabel( + std::string labels) +{ + if (labels.size() < 3) + { + return {}; + } + labels = labels.substr(1, labels.size() - 2); + + std::vector paired_labels; + std::stringstream s_stream(labels); + while (s_stream.good()) + { + std::string substr; + getline(s_stream, substr, ','); // get first string delimited by comma + if (!substr.empty()) + { + paired_labels.push_back(substr); + } + } + + std::vector> result; + for (auto &paired : paired_labels) + { + std::size_t split_index = paired.find(':'); + std::string label = paired.substr(0, split_index); + std::string value = paired.substr(split_index + 1); + result.emplace_back(std::pair(label, value)); + } + + return result; +} + +/** + * Handle Counter. + */ +template +void PrometheusExporterUtils::SetValue(std::vector values, + prometheus_client::MetricType type, + prometheus_client::ClientMetric *metric) +{ + double value = 0.0; + const auto &value_var = values[0]; + if (nostd::holds_alternative(value_var)) + { + value = nostd::get(value_var); + } + else + { + value = nostd::get(value_var); + } + + switch (type) + { + case prometheus_client::MetricType::Counter: { + metric->counter.value = value; + break; + } + case prometheus_client::MetricType::Untyped: { + metric->untyped.value = value; + break; + } + default: + return; + } +} + +/** + * Handle Histogram + */ +template +void PrometheusExporterUtils::SetValue(std::vector values, + const std::list &boundaries, + const std::vector &counts, + prometheus_client::ClientMetric *metric) +{ + metric->histogram.sample_sum = values[0]; + metric->histogram.sample_count = values[1]; + int cumulative = 0; + std::vector buckets; + uint32_t idx = 0; + for (const auto &boundary : boundaries) + { + prometheus_client::ClientMetric::Bucket bucket; + cumulative += counts[idx]; + bucket.cumulative_count = cumulative; + bucket.upper_bound = boundary; + buckets.emplace_back(bucket); + ++idx; + } + prometheus_client::ClientMetric::Bucket bucket; + cumulative += counts[idx]; + bucket.cumulative_count = cumulative; + bucket.upper_bound = std::numeric_limits::infinity(); + buckets.emplace_back(bucket); + metric->histogram.bucket = buckets; +} + +} // namespace metrics +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE +#endif From 0c74e0b93d2e73bae68a08b7d124d13f752f2216 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 26 Apr 2022 01:43:13 +0530 Subject: [PATCH 35/69] remove exporter registration to meter provider (#1350) --- examples/metrics_simple/metrics_ostream.cc | 6 +- .../opentelemetry/sdk/metrics/meter_context.h | 18 +----- .../sdk/metrics/meter_provider.h | 13 ---- sdk/src/metrics/meter_context.cc | 60 +++++++------------ sdk/src/metrics/meter_provider.cc | 11 +--- sdk/test/metrics/async_metric_storage_test.cc | 3 +- sdk/test/metrics/meter_provider_sdk_test.cc | 14 ++--- sdk/test/metrics/metric_reader_test.cc | 5 +- 8 files changed, 36 insertions(+), 94 deletions(-) diff --git a/examples/metrics_simple/metrics_ostream.cc b/examples/metrics_simple/metrics_ostream.cc index d0e4dccfeb..ebb8b34b8a 100644 --- a/examples/metrics_simple/metrics_ostream.cc +++ b/examples/metrics_simple/metrics_ostream.cc @@ -30,7 +30,6 @@ namespace void initMetrics(const std::string &name) { std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; - std::vector> exporters; std::string version{"1.2.0"}; std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; @@ -41,9 +40,8 @@ void initMetrics(const std::string &name) options.export_timeout_millis = std::chrono::milliseconds(500); std::unique_ptr reader{ new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; - auto provider = std::shared_ptr( - new metric_sdk::MeterProvider(std::move(exporters))); - auto p = std::static_pointer_cast(provider); + auto provider = std::shared_ptr(new metric_sdk::MeterProvider()); + auto p = std::static_pointer_cast(provider); p->AddMetricReader(std::move(reader)); // counter view diff --git a/sdk/include/opentelemetry/sdk/metrics/meter_context.h b/sdk/include/opentelemetry/sdk/metrics/meter_context.h index 74f67a1c46..e35700175d 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter_context.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter_context.h @@ -24,7 +24,6 @@ namespace metrics // forward declaration class Meter; -class MetricExporter; class MetricReader; /** @@ -36,13 +35,11 @@ class MeterContext : public std::enable_shared_from_this public: /** * Initialize a new meter provider - * @param exporters The exporters to be configured with meter context * @param readers The readers to be configured with meter context. * @param views The views to be configured with meter context. * @param resource The resource for this meter context. */ MeterContext( - std::vector> &&exporters, std::unique_ptr views = std::unique_ptr(new ViewRegistry()), opentelemetry::sdk::resource::Resource resource = opentelemetry::sdk::resource::Resource::Create({})) noexcept; @@ -77,16 +74,6 @@ class MeterContext : public std::enable_shared_from_this */ opentelemetry::common::SystemTimestamp GetSDKStartTime() noexcept; - /** - * Attaches a metric exporter to list of configured exporters for this Meter context. - * @param exporter The metric exporter for this meter context. This - * must not be a nullptr. - * - * Note: This exporter may not receive any in-flight meter data, but will get newly created meter - * data. Note: This method is not thread safe, and should ideally be called from main thread. - */ - void AddMetricExporter(std::unique_ptr exporter) noexcept; - /** * Attaches a metric reader to list of configured readers for this Meter context. * @param reader The metric reader for this meter context. This @@ -118,20 +105,19 @@ class MeterContext : public std::enable_shared_from_this void AddMeter(std::shared_ptr meter); /** - * Force all active Exporters and Collectors to flush any buffered meter data + * Force all active Collectors to flush any buffered meter data * within the given timeout. */ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; /** - * Shutdown the Exporters and Collectors associated with this meter provider. + * Shutdown the Collectors associated with this meter provider. */ bool Shutdown() noexcept; private: opentelemetry::sdk::resource::Resource resource_; - std::vector> exporters_; std::vector> collectors_; std::unique_ptr views_; opentelemetry::common::SystemTimestamp sdk_start_ts_; diff --git a/sdk/include/opentelemetry/sdk/metrics/meter_provider.h b/sdk/include/opentelemetry/sdk/metrics/meter_provider.h index c6efba6222..685f43e747 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter_provider.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter_provider.h @@ -22,7 +22,6 @@ namespace metrics // forward declaration class MetricCollector; -class MetricExporter; class MetricReader; class MeterProvider final : public opentelemetry::metrics::MeterProvider @@ -30,12 +29,10 @@ class MeterProvider final : public opentelemetry::metrics::MeterProvider public: /** * Initialize a new meter provider - * @param exporters The span exporters for this meter provider * @param views The views for this meter provider * @param resource The resources for this meter provider. */ MeterProvider( - std::vector> &&exporters, std::unique_ptr views = std::unique_ptr(new ViewRegistry()), sdk::resource::Resource resource = sdk::resource::Resource::Create({})) noexcept; @@ -56,16 +53,6 @@ class MeterProvider final : public opentelemetry::metrics::MeterProvider */ const sdk::resource::Resource &GetResource() const noexcept; - /** - * Attaches a metric exporter to list of configured exporters for this Meter provider. - * @param exporter The metric exporter for this meter provider. This - * must not be a nullptr. - * - * Note: This exporter may not receive any in-flight meter data, but will get newly created meter - * data. Note: This method is not thread safe, and should ideally be called from main thread. - */ - void AddMetricExporter(std::unique_ptr exporter) noexcept; - /** * Attaches a metric reader to list of configured readers for this Meter providers. * @param reader The metric reader for this meter provider. This diff --git a/sdk/src/metrics/meter_context.cc b/sdk/src/metrics/meter_context.cc index f23135fa0c..73721e324d 100644 --- a/sdk/src/metrics/meter_context.cc +++ b/sdk/src/metrics/meter_context.cc @@ -4,7 +4,6 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/meter_context.h" # include "opentelemetry/sdk/common/global_log_handler.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" # include "opentelemetry/sdk/metrics/metric_reader.h" # include "opentelemetry/sdk_config.h" # include "opentelemetry/version.h" @@ -15,13 +14,9 @@ namespace sdk namespace metrics { -MeterContext::MeterContext(std::vector> &&exporters, - std::unique_ptr views, +MeterContext::MeterContext(std::unique_ptr views, opentelemetry::sdk::resource::Resource resource) noexcept - : resource_{resource}, - exporters_(std::move(exporters)), - views_(std::move(views)), - sdk_start_ts_{std::chrono::system_clock::now()} + : resource_{resource}, views_(std::move(views)), sdk_start_ts_{std::chrono::system_clock::now()} {} const resource::Resource &MeterContext::GetResource() const noexcept @@ -49,11 +44,6 @@ opentelemetry::common::SystemTimestamp MeterContext::GetSDKStartTime() noexcept return sdk_start_ts_; } -void MeterContext::AddMetricExporter(std::unique_ptr exporter) noexcept -{ - exporters_.push_back(std::move(exporter)); -} - void MeterContext::AddMetricReader(std::unique_ptr reader) noexcept { auto collector = @@ -75,51 +65,41 @@ void MeterContext::AddMeter(std::shared_ptr meter) bool MeterContext::Shutdown() noexcept { - bool return_status = true; + bool result = true; if (!shutdown_latch_.test_and_set(std::memory_order_acquire)) { - bool result_exporter = true; - bool result_reader = true; - bool result_collector = true; - for (auto &exporter : exporters_) - { - bool status = exporter->Shutdown(); - result_exporter = result_exporter && status; - } - if (!result_exporter) - { - OTEL_INTERNAL_LOG_WARN("[MeterContext::Shutdown] Unable to shutdown all metric exporters"); - } for (auto &collector : collectors_) { - bool status = std::static_pointer_cast(collector)->Shutdown(); - result_collector = result_reader && status; + bool status = std::static_pointer_cast(collector)->Shutdown(); + result = result && status; } - if (!result_collector) + if (!result) { OTEL_INTERNAL_LOG_WARN("[MeterContext::Shutdown] Unable to shutdown all metric readers"); } - return_status = result_exporter && result_collector; } - return return_status; + return result; } bool MeterContext::ForceFlush(std::chrono::microseconds timeout) noexcept { // TODO - Implement timeout logic. - const std::lock_guard locked(forceflush_lock_); - bool result_exporter = true; - for (auto &exporter : exporters_) - { - bool status = exporter->ForceFlush(timeout); - result_exporter = result_exporter && status; - } - if (!result_exporter) + bool result = true; + if (!shutdown_latch_.test_and_set(std::memory_order_acquire)) { - OTEL_INTERNAL_LOG_WARN("[MeterContext::ForceFlush] Unable to force-flush all metric exporters"); + + for (auto &collector : collectors_) + { + bool status = std::static_pointer_cast(collector)->ForceFlush(timeout); + result = result && status; + } + if (!result) + { + OTEL_INTERNAL_LOG_WARN("[MeterContext::ForceFlush] Unable to ForceFlush all metric readers"); + } } - return result_exporter; + return result; } } // namespace metrics diff --git a/sdk/src/metrics/meter_provider.cc b/sdk/src/metrics/meter_provider.cc index 8a9572c88c..788811cd61 100644 --- a/sdk/src/metrics/meter_provider.cc +++ b/sdk/src/metrics/meter_provider.cc @@ -4,7 +4,6 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/meter_provider.h" # include "opentelemetry/metrics/meter.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" # include "opentelemetry/sdk/metrics/metric_reader.h" # include "opentelemetry/sdk/common/global_log_handler.h" @@ -23,10 +22,9 @@ namespace metrics_api = opentelemetry::metrics; MeterProvider::MeterProvider(std::shared_ptr context) noexcept : context_{context} {} -MeterProvider::MeterProvider(std::vector> &&exporters, - std::unique_ptr views, +MeterProvider::MeterProvider(std::unique_ptr views, sdk::resource::Resource resource) noexcept - : context_(std::make_shared(std::move(exporters), std::move(views), resource)) + : context_(std::make_shared(std::move(views), resource)) {} nostd::shared_ptr MeterProvider::GetMeter( @@ -61,11 +59,6 @@ const resource::Resource &MeterProvider::GetResource() const noexcept return context_->GetResource(); } -void MeterProvider::AddMetricExporter(std::unique_ptr exporter) noexcept -{ - return context_->AddMetricExporter(std::move(exporter)); -} - void MeterProvider::AddMetricReader(std::unique_ptr reader) noexcept { return context_->AddMetricReader(std::move(reader)); diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index 512e24472c..f939035fb2 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -46,8 +46,7 @@ TEST(AsyncMetricStorageTest, BasicTests) // Some computation here auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5); - std::vector> exporters; - std::shared_ptr meter_context(new MeterContext(std::move(exporters))); + std::shared_ptr meter_context(new MeterContext()); std::unique_ptr metric_reader(new MockMetricReader(AggregationTemporality::kDelta)); std::shared_ptr collector = std::shared_ptr( diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index 4a2792c3a7..b0fabe50bb 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -38,16 +38,19 @@ class MockMetricExporter : public MetricExporter class MockMetricReader : public MetricReader { public: + MockMetricReader(std::unique_ptr exporter) : exporter_(std::move(exporter)) {} virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept override { return true; } virtual void OnInitialized() noexcept override {} + +private: + std::unique_ptr exporter_; }; TEST(MeterProvider, GetMeter) { - std::vector> exporters; - MeterProvider mp1(std::move(exporters)); + MeterProvider mp1; // std::unique_ptr view{std::unique_ptr()}; // MeterProvider mp1(std::move(exporters), std::move(readers), std::move(views); auto m1 = mp1.GetMeter("test"); @@ -74,11 +77,8 @@ TEST(MeterProvider, GetMeter) auto sdkMeter1 = static_cast(m1.get()); # endif ASSERT_NE(nullptr, sdkMeter1); - - std::unique_ptr exporter{new MockMetricExporter()}; - ASSERT_NO_THROW(mp1.AddMetricExporter(std::move(exporter))); - - std::unique_ptr reader{new MockMetricReader()}; + std::unique_ptr exporter(new MockMetricExporter()); + std::unique_ptr reader{new MockMetricReader(std::move(exporter))}; ASSERT_NO_THROW(mp1.AddMetricReader(std::move(reader))); std::unique_ptr view{std::unique_ptr()}; diff --git a/sdk/test/metrics/metric_reader_test.cc b/sdk/test/metrics/metric_reader_test.cc index 61a4364934..c9c30853df 100644 --- a/sdk/test/metrics/metric_reader_test.cc +++ b/sdk/test/metrics/metric_reader_test.cc @@ -27,12 +27,11 @@ TEST(MetricReaderTest, BasicTests) std::unique_ptr metric_reader1(new MockMetricReader(aggr_temporality)); EXPECT_EQ(metric_reader1->GetAggregationTemporality(), aggr_temporality); - std::vector> exporters; - std::shared_ptr meter_context1(new MeterContext(std::move(exporters))); + std::shared_ptr meter_context1(new MeterContext()); EXPECT_NO_THROW(meter_context1->AddMetricReader(std::move(metric_reader1))); std::unique_ptr metric_reader2(new MockMetricReader(aggr_temporality)); - std::shared_ptr meter_context2(new MeterContext(std::move(exporters))); + std::shared_ptr meter_context2(new MeterContext()); MetricProducer *metric_producer = new MetricCollector(std::move(meter_context2), std::move(metric_reader2)); EXPECT_NO_THROW(metric_producer->Collect([](ResourceMetrics &metric_data) { return true; })); From 33cb82714efa460481187bfa136e6a0e3fd84b19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 10:55:34 -0700 Subject: [PATCH 36/69] Bump github/codeql-action from 1 to 2 (#1351) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b40b8e5a73..000a0eb0d0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,10 +23,10 @@ jobs: sudo ./ci/setup_cmake.sh sudo ./ci/setup_ci_environment.sh - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: cpp - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From c917beda3e5af3628020ad8faf58e61924260c8b Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Tue, 26 Apr 2022 12:42:26 -0700 Subject: [PATCH 37/69] Add explicit type cast in baggage UrlDecode (#1353) --- api/include/opentelemetry/baggage/baggage.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/include/opentelemetry/baggage/baggage.h b/api/include/opentelemetry/baggage/baggage.h index 7f904f09a7..259fd7f3b6 100644 --- a/api/include/opentelemetry/baggage/baggage.h +++ b/api/include/opentelemetry/baggage/baggage.h @@ -249,7 +249,9 @@ class Baggage }; auto from_hex = [](char c) -> char { - return std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10; + // c - '0' produces integer type which could trigger error/warning when casting to char, + // but the cast is safe here. + return static_cast(std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10); }; std::string ret; From e2337912f09b9380b0ca8803426a72313fb8d846 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Tue, 26 Apr 2022 22:27:39 -0700 Subject: [PATCH 38/69] Fix scalar delete against array (#1356) --- exporters/etw/include/opentelemetry/exporters/etw/utils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 8b0a015821..22a1c4fffc 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -193,8 +193,8 @@ static inline GUID GetProviderGuid(const char *providerName) guid.Data4[6] = buffer2[14]; guid.Data4[7] = buffer2[15]; - delete buffer; - delete buffer2; + delete[] buffer; + delete[] buffer2; return guid; } From 3b9bfd41e7d547a8e90df47fb0ac36df0c46a713 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 27 Apr 2022 14:20:24 +0530 Subject: [PATCH 39/69] conditional include for codecvt header (#1355) --- exporters/etw/include/opentelemetry/exporters/etw/utils.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 22a1c4fffc..4d38c1fb6f 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -24,6 +23,8 @@ # pragma comment(lib, "Rpcrt4.lib") # include # pragma comment(lib, "Ole32.Lib") +#else +# include #endif OPENTELEMETRY_BEGIN_NAMESPACE From 72360b49f6aa44b5b163e48823952e50933b20f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zsolt=20B=C3=B6l=C3=B6ny?= Date: Wed, 27 Apr 2022 13:18:26 +0200 Subject: [PATCH 40/69] Add missing include guard (#1357) --- .../opentelemetry/context/propagation/composite_propagator.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/include/opentelemetry/context/propagation/composite_propagator.h b/api/include/opentelemetry/context/propagation/composite_propagator.h index 85ad97b0fc..d7a6cbda17 100644 --- a/api/include/opentelemetry/context/propagation/composite_propagator.h +++ b/api/include/opentelemetry/context/propagation/composite_propagator.h @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#pragma once + #include #include #include From 4008da54fa29c71c6e8b32d5ff7b186136a128ff Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 27 Apr 2022 18:08:22 +0530 Subject: [PATCH 41/69] Use latest TraceLoggingDynamic.h (#1354) --- .../opentelemetry/exporters/etw/LICENSE | 23 +++++++++++++++++++ .../exporters/etw/TraceLoggingDynamic.h | 19 +++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 exporters/etw/include/opentelemetry/exporters/etw/LICENSE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/LICENSE b/exporters/etw/include/opentelemetry/exporters/etw/LICENSE new file mode 100644 index 0000000000..cfc21fd2cc --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/LICENSE @@ -0,0 +1,23 @@ +TraceLogging Dynamic for Windows + +Copyright (c) Microsoft Corporation. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h b/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h index 5d493b319a..17ee108c64 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h @@ -691,7 +691,7 @@ namespace tld } void AddBytes( - _In_bytecount_(cb) void const* p, + _In_reads_bytes_(cb) void const* p, unsigned cb) { auto pb = static_cast(p); @@ -2064,7 +2064,7 @@ namespace tld void AddTrait( ProviderTraitType type, - _In_bytecount_(cbData) void const* pData, + _In_reads_bytes_(cbData) void const* pData, unsigned cbData) { this->AddU16(static_cast(cbData + 3)); @@ -2232,6 +2232,7 @@ namespace tld return this->BaseEnd(); } + // Note: Do not create structs with 0 fields. template EventMetadataBuilder AddStruct( _In_z_ CharTy const* szUtfStructName, @@ -2242,6 +2243,7 @@ namespace tld return EventMetadataBuilder(this->GetBuffer(), bookmark); } + // Note: Do not create structs with 0 fields. template UINT32 AddStructRaw( _In_z_ CharTy const* szUtfStructName, @@ -2252,6 +2254,7 @@ namespace tld return bookmark; } + // Note: Do not create structs with 0 fields. template EventMetadataBuilder AddStructArray( _In_z_ CharTy const* szUtfStructName, @@ -2262,6 +2265,8 @@ namespace tld return EventMetadataBuilder(this->GetBuffer(), bookmark); } + // Note: Do not use 0 for itemCount. + // Note: Do not create structs with 0 fields. template EventMetadataBuilder AddStructFixedArray( _In_z_ CharTy const* szUtfStructName, @@ -2294,6 +2299,7 @@ namespace tld AddFieldInfo(InMetaVcount, type, fieldTags); } + // Note: Do not use 0 for itemCount. template void AddFieldFixedArray( _In_z_ CharTy const* szUtfFieldName, @@ -2400,7 +2406,7 @@ namespace tld Note: should only be used for blittable POD types with no padding. */ template - void AddValues(_In_count_(cValues) T const* pValues, unsigned cValues) + void AddValues(_In_reads_(cValues) T const* pValues, unsigned cValues) { AddBytes(pValues, sizeof(T) * cValues); } @@ -2917,6 +2923,7 @@ namespace tld of the nested struct. Note: do not call any Add methods on this builder object until you are done calling Add methods on the nested builder object. + Note: Do not create structs with 0 fields. */ template EventBuilder AddStruct( @@ -2933,6 +2940,7 @@ namespace tld of the nested struct. Note: do not call any Add methods on this builder object until you are done calling Add methods on the nested builder object. + Note: Do not create structs with 0 fields. */ template EventBuilder AddStructArray( @@ -2949,6 +2957,8 @@ namespace tld of the nested struct. Note: do not call any Add methods on this builder object until you are done calling Add methods on the nested builder object. + Note: Do not use 0 for itemCount. + Note: Do not create structs with 0 fields. */ template EventBuilder AddStructFixedArray( @@ -2992,6 +3002,7 @@ namespace tld Adds a fixed-length array field to the event's metadata. The length (item count) is encoded in the metadata, so it does not need to be included in the event's payload. + Note: Do not use 0 for itemCount. */ template void AddFieldFixedArray( @@ -3061,7 +3072,7 @@ namespace tld e.g. INT32, FILETIME, GUID, not for strings or structs. */ template - void AddValues(_In_count_(cValues) T const* pValues, unsigned cValues) + void AddValues(_In_reads_(cValues) T const* pValues, unsigned cValues) { m_dataBuilder.AddValues(pValues, cValues); } From a4bd3b0667b6534876003006d5179cef2772cf31 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Thu, 28 Apr 2022 18:29:26 +0200 Subject: [PATCH 42/69] prometheus example (#1332) --- ci/do_ci.sh | 4 +- examples/CMakeLists.txt | 3 + examples/prometheus/BUILD | 14 +++ examples/prometheus/CMakeLists.txt | 5 + examples/prometheus/main.cc | 118 ++++++++++++++++++ examples/prometheus/prometheus.yml | 16 +++ examples/prometheus/run.sh | 1 + .../exporters/prometheus/exporter.h | 2 +- 8 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 examples/prometheus/BUILD create mode 100644 examples/prometheus/CMakeLists.txt create mode 100644 examples/prometheus/main.cc create mode 100644 examples/prometheus/prometheus.yml create mode 100644 examples/prometheus/run.sh diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 008e983842..14749500ec 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -222,8 +222,8 @@ elif [[ "$1" == "bazel.legacy.test" ]]; then elif [[ "$1" == "bazel.noexcept" ]]; then # there are some exceptions and error handling code from the Prometheus and Jaeger Clients # that make this test always fail. ignore Prometheus and Jaeger exporters in the noexcept here. - bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... - bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... + bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... -//examples/prometheus/... + bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... -//examples/prometheus/... exit 0 elif [[ "$1" == "bazel.nortti" ]]; then # there are some exceptions and error handling code from the Prometheus and Jaeger Clients diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index db0fe159be..2367918c7e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -15,6 +15,9 @@ endif() if(WITH_ZIPKIN) add_subdirectory(zipkin) endif() +if(WITH_PROMETHEUS AND NOT WITH_METRICS_PREVIEW) + add_subdirectory(prometheus) +endif() add_subdirectory(plugin) add_subdirectory(simple) add_subdirectory(batch) diff --git a/examples/prometheus/BUILD b/examples/prometheus/BUILD new file mode 100644 index 0000000000..edbfde61e6 --- /dev/null +++ b/examples/prometheus/BUILD @@ -0,0 +1,14 @@ +cc_binary( + name = "prometheus_example", + srcs = [ + "main.cc", + ], + linkopts = ["-pthread"], + tags = ["ostream"], + deps = [ + "//api", + "//examples/common/metrics_foo_library:common_metrics_foo_library", + "//exporters/prometheus:prometheus_exporter", + "//sdk/src/metrics", + ], +) diff --git a/examples/prometheus/CMakeLists.txt b/examples/prometheus/CMakeLists.txt new file mode 100644 index 0000000000..b377920dee --- /dev/null +++ b/examples/prometheus/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${CMAKE_SOURCE_DIR}/exporters/prometheus/include) +add_executable(prometheus_example main.cc) +target_link_libraries( + prometheus_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics + prometheus_exporter opentelemetry_resources common_metrics_foo_library) diff --git a/examples/prometheus/main.cc b/examples/prometheus/main.cc new file mode 100644 index 0000000000..77a648f55d --- /dev/null +++ b/examples/prometheus/main.cc @@ -0,0 +1,118 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/exporters/prometheus/exporter.h" +# include "opentelemetry/metrics/provider.h" +# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/metrics/meter.h" +# include "opentelemetry/sdk/metrics/meter_provider.h" + +# ifdef BAZEL_BUILD +# include "examples/common/metrics_foo_library/foo_library.h" +# else +# include "metrics_foo_library/foo_library.h" +# endif + +namespace metrics_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace metrics_exporter = opentelemetry::exporter::metrics; +namespace metrics_api = opentelemetry::metrics; + +namespace +{ + +void initMetrics(const std::string &name, const std::string &addr) +{ + metrics_exporter::PrometheusExporterOptions opts; + if (!addr.empty()) + { + opts.url = addr; + } + std::puts("PrometheusExporter example program running ..."); + + std::unique_ptr exporter{ + new metrics_exporter::PrometheusExporter(opts)}; + + std::string version{"1.2.0"}; + std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; + + // Initialize and set the global MeterProvider + metrics_sdk::PeriodicExportingMetricReaderOptions options; + options.export_interval_millis = std::chrono::milliseconds(1000); + options.export_timeout_millis = std::chrono::milliseconds(500); + std::unique_ptr reader{ + new metrics_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + auto provider = std::shared_ptr(new metrics_sdk::MeterProvider()); + auto p = std::static_pointer_cast(provider); + p->AddMetricReader(std::move(reader)); + + // counter view + std::string counter_name = name + "_counter"; + std::unique_ptr instrument_selector{ + new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kCounter, counter_name)}; + std::unique_ptr meter_selector{ + new metrics_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr sum_view{ + new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kSum}}; + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + + // histogram view + std::string histogram_name = name + "_histogram"; + std::unique_ptr histogram_instrument_selector{ + new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kHistogram, histogram_name)}; + std::unique_ptr histogram_meter_selector{ + new metrics_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr histogram_view{ + new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kHistogram}}; + p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); + metrics_api::Provider::SetMeterProvider(provider); +} +} // namespace + +int main(int argc, char **argv) +{ + std::string example_type; + std::string addr{"localhost:8080"}; + if (argc == 1) + { + std::puts("usage: $prometheus_example "); + } + + if (argc >= 2) + { + example_type = argv[1]; + } + if (argc > 2) + { + addr = argv[2]; + } + + std::string name{"prometheus_metric_example"}; + initMetrics(name, addr); + + if (example_type == "counter") + { + foo_library::counter_example(name); + } + else if (example_type == "histogram") + { + foo_library::histogram_example(name); + } + else + { + std::thread counter_example{&foo_library::counter_example, name}; + std::thread histogram_example{&foo_library::histogram_example, name}; + counter_example.join(); + histogram_example.join(); + } +} +#else +int main() {} +#endif diff --git a/examples/prometheus/prometheus.yml b/examples/prometheus/prometheus.yml new file mode 100644 index 0000000000..3f415d39dc --- /dev/null +++ b/examples/prometheus/prometheus.yml @@ -0,0 +1,16 @@ +global: + scrape_interval: 5s + scrape_timeout: 2s + evaluation_interval: 5s +alerting: + alertmanagers: + - follow_redirects: true + scheme: http + timeout: 5s + api_version: v2 + static_configs: + - targets: [localhost:8080] +scrape_configs: + - job_name: otel + static_configs: + - targets: ['localhost:8080'] \ No newline at end of file diff --git a/examples/prometheus/run.sh b/examples/prometheus/run.sh new file mode 100644 index 0000000000..412c6ef454 --- /dev/null +++ b/examples/prometheus/run.sh @@ -0,0 +1 @@ +docker run -p 9090:9090 -v $(pwd):/etc/prometheus --network="host" prom/prometheus \ No newline at end of file diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h index 6945f09bb9..151244928f 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h @@ -31,7 +31,7 @@ namespace metrics inline const std::string GetOtlpDefaultHttpEndpoint() { constexpr char kPrometheusEndpointEnv[] = "PROMETHEUS_EXPORTER_ENDPOINT"; - constexpr char kPrometheusEndpointDefault[] = "http://localhost:8080"; + constexpr char kPrometheusEndpointDefault[] = "localhost:8080"; auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kPrometheusEndpointEnv); return endpoint.size() ? endpoint : kPrometheusEndpointDefault; From 3a4a3a33ffa5b1ee224818e19a3004bdc9bb3c95 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Thu, 28 Apr 2022 15:57:07 -0700 Subject: [PATCH 43/69] Fix output time in metrics OStream exporter (#1346) --- exporters/ostream/src/metric_exporter.cc | 33 +++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index 5cdd3fe78d..bf97db04c2 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -14,7 +14,34 @@ namespace std::string timeToString(opentelemetry::common::SystemTimestamp time_stamp) { std::time_t epoch_time = std::chrono::system_clock::to_time_t(time_stamp); - return std::ctime(&epoch_time); + + struct tm *tm_ptr = nullptr; +# if defined(_MSC_VER) + struct tm buf_tm; + if (!gmtime_s(&buf_tm, &epoch_time)) + { + tm_ptr = &buf_tm; + } +# else + tm_ptr = std::gmtime(&epoch_time); +# endif + + char buf[100]; + char *date_str = nullptr; + if (tm_ptr == nullptr) + { + OTEL_INTERNAL_LOG_ERROR("[OStream Metric] gmtime failed for " << epoch_time); + } + else if (std::strftime(buf, sizeof(buf), "%c", tm_ptr) > 0) + { + date_str = buf; + } + else + { + OTEL_INTERNAL_LOG_ERROR("[OStream Metric] strftime failed for " << epoch_time); + } + + return std::string{date_str}; } } // namespace @@ -68,8 +95,8 @@ void OStreamMetricExporter::printInstrumentationInfoMetricData( for (const auto &record : info_metric.metric_data_) { sout_ << "\n start time\t: " << timeToString(record.start_ts) - << " end time\t: " << timeToString(record.end_ts) - << " description\t: " << record.instrument_descriptor.description_ + << "\n end time\t: " << timeToString(record.end_ts) + << "\n description\t: " << record.instrument_descriptor.description_ << "\n unit\t\t: " << record.instrument_descriptor.unit_; for (const auto &pd : record.point_data_attr_) From f31452286ce4742cb82a3059eaccb96ae8f1b0d2 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Sat, 30 Apr 2022 06:18:49 +0530 Subject: [PATCH 44/69] Simplify SDK Configuration: Use View with default aggregation if no matching View is configured (#1358) --- .../opentelemetry/sdk/metrics/view/view.h | 2 +- .../sdk/metrics/view/view_registry.h | 2 +- sdk/test/metrics/view_registry_test.cc | 16 +++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/view.h b/sdk/include/opentelemetry/sdk/metrics/view/view.h index e88e7126c6..3cd9f850e1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/view.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/view.h @@ -23,7 +23,7 @@ class View public: View(const std::string &name, const std::string &description = "", - AggregationType aggregation_type = AggregationType::kDrop, + AggregationType aggregation_type = AggregationType::kDefault, std::unique_ptr attributes_processor = std::unique_ptr( new opentelemetry::sdk::metrics::DefaultAttributesProcessor())) diff --git a/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h b/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h index 87b842e46a..795049dd9a 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h @@ -64,7 +64,7 @@ class ViewRegistry // return default view if none found; if (!found) { - static View view(""); + static View view("otel-default-view"); if (!callback(view)) { return false; diff --git a/sdk/test/metrics/view_registry_test.cc b/sdk/test/metrics/view_registry_test.cc index c3a9923c50..8151d37545 100644 --- a/sdk/test/metrics/view_registry_test.cc +++ b/sdk/test/metrics/view_registry_test.cc @@ -25,13 +25,15 @@ TEST(ViewRegistry, FindViewsEmptyRegistry) InstrumentationLibrary::Create("default", "1.0.0", "https://opentelemetry.io/schemas/1.7.0"); int count = 0; ViewRegistry registry; - auto status = registry.FindViews(default_instrument_descriptor, - *default_instrumentation_lib.get(), [&count](const View &view) { - count++; - EXPECT_EQ(view.GetName(), ""); - EXPECT_EQ(view.GetDescription(), ""); - return true; - }); + auto status = + registry.FindViews(default_instrument_descriptor, *default_instrumentation_lib.get(), + [&count](const View &view) { + count++; + EXPECT_EQ(view.GetName(), "otel-default-view"); + EXPECT_EQ(view.GetDescription(), ""); + EXPECT_EQ(view.GetAggregationType(), AggregationType::kDefault); + return true; + }); EXPECT_EQ(count, 1); EXPECT_EQ(status, true); } From 8ef6764c2fa15e05f4eaf4f5c397f33740f520bf Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Sat, 30 Apr 2022 07:10:06 +0530 Subject: [PATCH 45/69] Fix class member initialization order (#1360) --- .../etw/include/opentelemetry/exporters/etw/etw_tracer.h | 4 ++-- sdk/src/metrics/meter.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 65fe2770f2..82bd6d726c 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -761,10 +761,10 @@ class Span : public opentelemetry::trace::Span const opentelemetry::trace::StartSpanOptions &options, Span *parent = nullptr) noexcept : opentelemetry::trace::Span(), + start_time_(std::chrono::system_clock::now()), owner_(owner), parent_(parent), - context_(CreateContext()), - start_time_(std::chrono::system_clock::now()) + context_(CreateContext()) { name_ = name; UNREFERENCED_PARAMETER(options); diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index d5af7f9ec9..c0b0ce7a57 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -28,7 +28,7 @@ namespace nostd = opentelemetry::nostd; Meter::Meter(std::shared_ptr meter_context, std::unique_ptr instrumentation_library) noexcept - : meter_context_{meter_context}, instrumentation_library_{std::move(instrumentation_library)} + : instrumentation_library_{std::move(instrumentation_library)}, meter_context_{meter_context} {} nostd::shared_ptr> Meter::CreateLongCounter(nostd::string_view name, From c8bd431be27c71145098a1888dc115ab34997523 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Sat, 30 Apr 2022 19:29:13 +0200 Subject: [PATCH 46/69] codecov ignore (#1364) --- .github/.codecov.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/.codecov.yaml b/.github/.codecov.yaml index 2b3003ff57..62d96e70f1 100644 --- a/.github/.codecov.yaml +++ b/.github/.codecov.yaml @@ -33,3 +33,10 @@ comment: # to coverage report file paths. fixes: - "/home/runner/::" + +ignore: + - "docs/**/*" + - "docker/**/*" + - "examples/**/*" + - "**/test/**/*" + - "**.md" \ No newline at end of file From c1e6e16e7d7d07969e73e7fc9150d69f21bbf5e6 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 2 May 2022 19:12:38 +0200 Subject: [PATCH 47/69] export opentelemetry_otlp_recordable (#1365) --- exporters/otlp/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 1b1b200504..b5dfa1e1ab 100755 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -100,8 +100,7 @@ install( DIRECTORY include/opentelemetry/exporters/otlp DESTINATION include/opentelemetry/exporters FILES_MATCHING - PATTERN "*.h" - PATTERN "otlp_recordable.h" EXCLUDE) + PATTERN "*.h") if(BUILD_TESTING) add_executable(otlp_recordable_test test/otlp_recordable_test.cc) From 13ac5c30b6f8ae996d05f3c4084c58f952734ac6 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Mon, 2 May 2022 12:28:51 -0700 Subject: [PATCH 48/69] Disable test on prometheus-cpp which not need (#1363) --- CMakeLists.txt | 5 ++++- exporters/prometheus/test/CMakeLists.txt | 24 +++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09c21fd678..9840aa19a6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,7 +274,10 @@ if(WITH_PROMETHEUS) if(NOT prometheus-cpp_FOUND) message("Trying to use local prometheus-cpp from submodule") if(EXISTS ${PROJECT_SOURCE_DIR}/third_party/prometheus-cpp/.git) + set(SAVED_ENABLE_TESTING ${ENABLE_TESTING}) + set(ENABLE_TESTING OFF) add_subdirectory(third_party/prometheus-cpp) + set(ENABLE_TESTING ${SAVED_ENABLE_TESTING}) else() message( FATAL_ERROR @@ -361,7 +364,7 @@ if(BUILD_TESTING) ${CMAKE_BINARY_DIR}/lib/libgmock.a) elseif(WIN32) # Make sure we are always bootsrapped with vcpkg on Windows - find_package(GTest) + find_package(GTest REQUIRED) if(NOT (GTEST_FOUND OR GTest_FOUND)) install_windows_deps() find_package(GTest REQUIRED) diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index 6c45e9299c..1a22469792 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -1,11 +1,13 @@ -foreach(testname prometheus_exporter_test prometheus_collector_test - prometheus_exporter_utils_test) - add_executable(${testname} "${testname}.cc") - target_link_libraries( - ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - prometheus_exporter_deprecated prometheus-cpp::pull) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX exporter. - TEST_LIST ${testname}) -endforeach() +if(WITH_METRICS_PREVIEW) + foreach(testname prometheus_exporter_test prometheus_collector_test + prometheus_exporter_utils_test) + add_executable(${testname} "${testname}.cc") + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} + prometheus_exporter_deprecated prometheus-cpp::pull) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX exporter. + TEST_LIST ${testname}) + endforeach() +endif() From 9c734b33ee1f844b05cd0351cfafce14656f3dfd Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 3 May 2022 15:37:32 -0700 Subject: [PATCH 49/69] Enable metric collection for Async Instruments - Delta and Cumulative (#1334) --- .../metrics/aggregation/default_aggregation.h | 48 +++++++ .../metrics/aggregation/drop_aggregation.h | 6 +- .../aggregation/histogram_aggregation.h | 10 +- .../aggregation/lastvalue_aggregation.h | 6 +- .../sdk/metrics/aggregation/sum_aggregation.h | 10 +- .../sdk/metrics/state/async_metric_storage.h | 40 ++++-- .../metrics/state/temporal_metric_storage.h | 50 +++++++ sdk/src/metrics/CMakeLists.txt | 1 + .../aggregation/histogram_aggregation.cc | 8 ++ .../aggregation/lastvalue_aggregation.cc | 10 ++ .../metrics/aggregation/sum_aggregation.cc | 4 + .../metrics/state/temporal_metric_storage.cc | 131 ++++++++++++++++++ sdk/test/metrics/async_metric_storage_test.cc | 115 ++++++++++++--- 13 files changed, 391 insertions(+), 48 deletions(-) create mode 100644 sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h create mode 100644 sdk/src/metrics/state/temporal_metric_storage.cc diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h index b5a1283d26..887e1beb92 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h @@ -28,6 +28,7 @@ class DefaultAggregation { case InstrumentType::kCounter: case InstrumentType::kUpDownCounter: + case InstrumentType::kObservableCounter: case InstrumentType::kObservableUpDownCounter: return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) ? std::move(std::unique_ptr(new LongSumAggregation())) @@ -90,6 +91,53 @@ class DefaultAggregation return DefaultAggregation::CreateAggregation(instrument_descriptor); } } + + static std::unique_ptr CloneAggregation(AggregationType aggregation_type, + InstrumentDescriptor instrument_descriptor, + const Aggregation &to_copy) + { + const PointType point_data = to_copy.ToPoint(); + switch (aggregation_type) + { + case AggregationType::kDrop: + return std::unique_ptr(new DropAggregation()); + case AggregationType::kHistogram: + if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + { + return std::unique_ptr( + new LongHistogramAggregation(nostd::get(point_data))); + } + else + { + return std::unique_ptr( + new DoubleHistogramAggregation(nostd::get(point_data))); + } + case AggregationType::kLastValue: + if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + { + return std::unique_ptr( + new LongLastValueAggregation(nostd::get(point_data))); + } + else + { + return std::unique_ptr( + new DoubleLastValueAggregation(nostd::get(point_data))); + } + case AggregationType::kSum: + if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + { + return std::unique_ptr( + new LongSumAggregation(nostd::get(point_data))); + } + else + { + return std::unique_ptr( + new DoubleSumAggregation(nostd::get(point_data))); + } + default: + return DefaultAggregation::CreateAggregation(instrument_descriptor); + } + } }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h index 4e29fa2e46..6c3d89d247 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h @@ -23,16 +23,18 @@ class DropAggregation : public Aggregation public: DropAggregation() = default; + DropAggregation(const DropPointData &) {} + void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - std::unique_ptr Merge(const Aggregation &delta) const noexcept override + std::unique_ptr Merge(const Aggregation &) const noexcept override { return std::unique_ptr(new DropAggregation()); } - std::unique_ptr Diff(const Aggregation &next) const noexcept override + std::unique_ptr Diff(const Aggregation &) const noexcept override { return std::unique_ptr(new DropAggregation()); } diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h index b5cc2c349e..e2a55fba58 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h @@ -19,6 +19,7 @@ class LongHistogramAggregation : public Aggregation public: LongHistogramAggregation(); LongHistogramAggregation(HistogramPointData &&); + LongHistogramAggregation(const HistogramPointData &); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; @@ -26,14 +27,14 @@ class LongHistogramAggregation : public Aggregation /* Returns the result of merge of the existing aggregation with delta aggregation with same * boundaries */ - virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + std::unique_ptr Merge(const Aggregation &delta) const noexcept override; /* Returns the new delta aggregation by comparing existing aggregation with next aggregation with * same boundaries. Data points for `next` aggregation (sum , bucket-counts) should be more than * the current aggregation - which is the normal scenario as measurements values are monotonic * increasing. */ - virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; @@ -47,6 +48,7 @@ class DoubleHistogramAggregation : public Aggregation public: DoubleHistogramAggregation(); DoubleHistogramAggregation(HistogramPointData &&); + DoubleHistogramAggregation(const HistogramPointData &); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} @@ -54,14 +56,14 @@ class DoubleHistogramAggregation : public Aggregation /* Returns the result of merge of the existing aggregation with delta aggregation with same * boundaries */ - virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + std::unique_ptr Merge(const Aggregation &delta) const noexcept override; /* Returns the new delta aggregation by comparing existing aggregation with next aggregation with * same boundaries. Data points for `next` aggregation (sum , bucket-counts) should be more than * the current aggregation - which is the normal scenario as measurements values are monotonic * increasing. */ - virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h index 7f185d51a1..3b2c08f8ce 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h @@ -18,14 +18,15 @@ class LongLastValueAggregation : public Aggregation public: LongLastValueAggregation(); LongLastValueAggregation(LastValuePointData &&); + LongLastValueAggregation(const LastValuePointData &); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + std::unique_ptr Merge(const Aggregation &delta) const noexcept override; - virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; @@ -39,6 +40,7 @@ class DoubleLastValueAggregation : public Aggregation public: DoubleLastValueAggregation(); DoubleLastValueAggregation(LastValuePointData &&); + DoubleLastValueAggregation(const LastValuePointData &); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h index b0f0169b24..14f13bd727 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h @@ -19,14 +19,15 @@ class LongSumAggregation : public Aggregation public: LongSumAggregation(); LongSumAggregation(SumPointData &&); + LongSumAggregation(const SumPointData &); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override {} - virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + std::unique_ptr Merge(const Aggregation &delta) const noexcept override; - virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; @@ -40,14 +41,15 @@ class DoubleSumAggregation : public Aggregation public: DoubleSumAggregation(); DoubleSumAggregation(SumPointData &&); + DoubleSumAggregation(const SumPointData &); void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; - virtual std::unique_ptr Merge(const Aggregation &delta) const noexcept override; + std::unique_ptr Merge(const Aggregation &delta) const noexcept override; - virtual std::unique_ptr Diff(const Aggregation &next) const noexcept override; + std::unique_ptr Diff(const Aggregation &next) const noexcept override; PointType ToPoint() const noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h index cfbf521538..e4c20e4010 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h @@ -10,6 +10,7 @@ # include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" # include "opentelemetry/sdk/metrics/state/metric_collector.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" +# include "opentelemetry/sdk/metrics/state/temporal_metric_storage.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" # include @@ -32,7 +33,8 @@ class AsyncMetricStorage : public MetricStorage aggregation_type_{aggregation_type}, measurement_collection_callback_{measurement_callback}, attributes_processor_{attributes_processor}, - active_attributes_hashmap_(new AttributesHashMap()) + cumulative_hash_map_(new AttributesHashMap()), + temporal_metric_storage_(instrument_descriptor) {} bool Collect(CollectorHandle *collector, @@ -45,22 +47,33 @@ class AsyncMetricStorage : public MetricStorage // read the measurement using configured callback measurement_collection_callback_(ob_res); - + std::shared_ptr delta_hash_map(new AttributesHashMap()); // process the read measurements - aggregate and store in hashmap for (auto &measurement : ob_res.GetMeasurements()) { - auto agg = DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_); - agg->Aggregate(measurement.second); - active_attributes_hashmap_->Set(measurement.first, std::move(agg)); + auto aggr = DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_); + aggr->Aggregate(measurement.second); + auto prev = cumulative_hash_map_->Get(measurement.first); + if (prev) + { + auto delta = prev->Diff(*aggr); + cumulative_hash_map_->Set(measurement.first, + DefaultAggregation::CloneAggregation( + aggregation_type_, instrument_descriptor_, *delta)); + delta_hash_map->Set(measurement.first, std::move(delta)); + } + else + { + cumulative_hash_map_->Set( + measurement.first, + DefaultAggregation::CloneAggregation(aggregation_type_, instrument_descriptor_, *aggr)); + delta_hash_map->Set(measurement.first, std::move(aggr)); + } } - // TBD -> read aggregation from hashmap, and perform metric collection - MetricData metric_data; - if (metric_collection_callback(std::move(metric_data))) - { - return true; - } - return false; + return temporal_metric_storage_.buildMetrics(collector, collectors, sdk_start_ts, collection_ts, + std::move(delta_hash_map), + metric_collection_callback); } private: @@ -68,7 +81,8 @@ class AsyncMetricStorage : public MetricStorage AggregationType aggregation_type_; void (*measurement_collection_callback_)(opentelemetry::metrics::ObserverResult &); const AttributesProcessor *attributes_processor_; - std::unique_ptr active_attributes_hashmap_; + std::unique_ptr cumulative_hash_map_; + TemporalMetricStorage temporal_metric_storage_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h new file mode 100644 index 0000000000..16659c14f5 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h @@ -0,0 +1,50 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" +# include "opentelemetry/sdk/metrics/state/metric_collector.h" + +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +struct LastReportedMetrics +{ + std::unique_ptr attributes_map; + opentelemetry::common::SystemTimestamp collection_ts; +}; + +class TemporalMetricStorage +{ +public: + TemporalMetricStorage(InstrumentDescriptor instrument_descriptor); + + bool buildMetrics(CollectorHandle *collector, + nostd::span> collectors, + opentelemetry::common::SystemTimestamp sdk_start_ts, + opentelemetry::common::SystemTimestamp collection_ts, + std::shared_ptr delta_metrics, + nostd::function_ref callback) noexcept; + +private: + InstrumentDescriptor instrument_descriptor_; + + // unreported metrics stash for all the collectors + std::unordered_map>> + unreported_metrics_; + // last reported metrics stash for all the collectors. + std::unordered_map last_reported_metrics_; + + // Lock while building metrics + mutable opentelemetry::common::SpinLockMutex lock_; +}; +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/src/metrics/CMakeLists.txt b/sdk/src/metrics/CMakeLists.txt index b6656b5bf8..77a371a80c 100644 --- a/sdk/src/metrics/CMakeLists.txt +++ b/sdk/src/metrics/CMakeLists.txt @@ -7,6 +7,7 @@ add_library( export/periodic_exporting_metric_reader.cc state/metric_collector.cc state/sync_metric_storage.cc + state/temporal_metric_storage.cc aggregation/histogram_aggregation.cc aggregation/lastvalue_aggregation.cc aggregation/sum_aggregation.cc diff --git a/sdk/src/metrics/aggregation/histogram_aggregation.cc b/sdk/src/metrics/aggregation/histogram_aggregation.cc index 27405999c9..aa2be74713 100644 --- a/sdk/src/metrics/aggregation/histogram_aggregation.cc +++ b/sdk/src/metrics/aggregation/histogram_aggregation.cc @@ -25,6 +25,10 @@ LongHistogramAggregation::LongHistogramAggregation(HistogramPointData &&data) : point_data_{std::move(data)} {} +LongHistogramAggregation::LongHistogramAggregation(const HistogramPointData &data) + : point_data_{data} +{} + void LongHistogramAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); @@ -83,6 +87,10 @@ DoubleHistogramAggregation::DoubleHistogramAggregation(HistogramPointData &&data : point_data_{std::move(data)} {} +DoubleHistogramAggregation::DoubleHistogramAggregation(const HistogramPointData &data) + : point_data_{data} +{} + void DoubleHistogramAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); diff --git a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc index 9c0252be31..a125005335 100644 --- a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc +++ b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc @@ -19,10 +19,15 @@ LongLastValueAggregation::LongLastValueAggregation() point_data_.is_lastvalue_valid_ = false; point_data_.value_ = 0l; } + LongLastValueAggregation::LongLastValueAggregation(LastValuePointData &&data) : point_data_{std::move(data)} {} +LongLastValueAggregation::LongLastValueAggregation(const LastValuePointData &data) + : point_data_{data} +{} + void LongLastValueAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); @@ -71,10 +76,15 @@ DoubleLastValueAggregation::DoubleLastValueAggregation() point_data_.is_lastvalue_valid_ = false; point_data_.value_ = 0.0; } + DoubleLastValueAggregation::DoubleLastValueAggregation(LastValuePointData &&data) : point_data_{std::move(data)} {} +DoubleLastValueAggregation::DoubleLastValueAggregation(const LastValuePointData &data) + : point_data_{data} +{} + void DoubleLastValueAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); diff --git a/sdk/src/metrics/aggregation/sum_aggregation.cc b/sdk/src/metrics/aggregation/sum_aggregation.cc index 94b871cd34..5ca786496e 100644 --- a/sdk/src/metrics/aggregation/sum_aggregation.cc +++ b/sdk/src/metrics/aggregation/sum_aggregation.cc @@ -22,6 +22,8 @@ LongSumAggregation::LongSumAggregation() LongSumAggregation::LongSumAggregation(SumPointData &&data) : point_data_{std::move(data)} {} +LongSumAggregation::LongSumAggregation(const SumPointData &data) : point_data_{data} {} + void LongSumAggregation::Aggregate(long value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); @@ -64,6 +66,8 @@ DoubleSumAggregation::DoubleSumAggregation() DoubleSumAggregation::DoubleSumAggregation(SumPointData &&data) : point_data_(std::move(data)) {} +DoubleSumAggregation::DoubleSumAggregation(const SumPointData &data) : point_data_(data) {} + void DoubleSumAggregation::Aggregate(double value, const PointAttributes &attributes) noexcept { const std::lock_guard locked(lock_); diff --git a/sdk/src/metrics/state/temporal_metric_storage.cc b/sdk/src/metrics/state/temporal_metric_storage.cc new file mode 100644 index 0000000000..55e93e3d46 --- /dev/null +++ b/sdk/src/metrics/state/temporal_metric_storage.cc @@ -0,0 +1,131 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW + +# include "opentelemetry/sdk/metrics/state/temporal_metric_storage.h" +# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +TemporalMetricStorage::TemporalMetricStorage(InstrumentDescriptor instrument_descriptor) + : instrument_descriptor_(instrument_descriptor) +{} + +bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector, + nostd::span> collectors, + opentelemetry::common::SystemTimestamp sdk_start_ts, + opentelemetry::common::SystemTimestamp collection_ts, + std::shared_ptr delta_metrics, + nostd::function_ref callback) noexcept +{ + std::lock_guard guard(lock_); + opentelemetry::common::SystemTimestamp last_collection_ts = sdk_start_ts; + auto aggregation_temporarily = collector->GetAggregationTemporality(); + for (auto &col : collectors) + { + unreported_metrics_[col.get()].push_back(delta_metrics); + } + + // Get the unreported metrics for the `collector` from `unreported metrics stash` + // since last collection, this will also cleanup the unreported metrics for `collector` + // from the stash. + auto present = unreported_metrics_.find(collector); + if (present == unreported_metrics_.end()) + { + // no unreported metrics for the collector, return. + return true; + } + auto unreported_list = std::move(present->second); + // Iterate over the unreporter metrics for `collector` and store result in `merged_metrics` + std::unique_ptr merged_metrics(new AttributesHashMap); + for (auto &agg_hashmap : unreported_list) + { + agg_hashmap->GetAllEnteries( + [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { + auto agg = merged_metrics->Get(attributes); + if (agg) + { + merged_metrics->Set(attributes, agg->Merge(aggregation)); + } + else + { + merged_metrics->Set( + attributes, + DefaultAggregation::CreateAggregation(instrument_descriptor_)->Merge(aggregation)); + merged_metrics->GetAllEnteries( + [](const MetricAttributes &attr, Aggregation &aggr) { return true; }); + } + return true; + }); + } + // Get the last reported metrics for the `collector` from `last reported metrics` stash + // - If the aggregation_temporarily for the collector is cumulative + // - Merge the last reported metrics with unreported metrics (which is in merged_metrics), + // Final result of merge would be in merged_metrics. + // - Move the final merge to the `last reported metrics` stash. + // - If the aggregation_temporarily is delta + // - Store the unreported metrics for `collector` (which is in merged_mtrics) to + // `last reported metrics` stash. + + auto reported = last_reported_metrics_.find(collector); + if (reported != last_reported_metrics_.end()) + { + last_collection_ts = last_reported_metrics_[collector].collection_ts; + auto last_aggr_hashmap = std::move(last_reported_metrics_[collector].attributes_map); + if (aggregation_temporarily == AggregationTemporality::kCumulative) + { + // merge current delta to previous cumulative + last_aggr_hashmap->GetAllEnteries( + [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { + auto agg = merged_metrics->Get(attributes); + if (agg) + { + merged_metrics->Set(attributes, agg->Merge(aggregation)); + } + else + { + merged_metrics->Set(attributes, + DefaultAggregation::CreateAggregation(instrument_descriptor_)); + } + return true; + }); + } + last_reported_metrics_[collector] = + LastReportedMetrics{std::move(merged_metrics), collection_ts}; + } + else + { + merged_metrics->GetAllEnteries( + [](const MetricAttributes &attr, Aggregation &aggr) { return true; }); + last_reported_metrics_.insert( + std::make_pair(collector, LastReportedMetrics{std::move(merged_metrics), collection_ts})); + } + + // Generate the MetricData from the final merged_metrics, and invoke callback over it. + + AttributesHashMap *result_to_export = (last_reported_metrics_[collector]).attributes_map.get(); + MetricData metric_data; + metric_data.instrument_descriptor = instrument_descriptor_; + metric_data.start_ts = last_collection_ts; + metric_data.end_ts = collection_ts; + result_to_export->GetAllEnteries( + [&metric_data](const MetricAttributes &attributes, Aggregation &aggregation) { + PointDataAttributes point_data_attr; + point_data_attr.point_data = aggregation.ToPoint(); + point_data_attr.attributes = attributes; + metric_data.point_data_attr_.push_back(point_data_attr); + return true; + }); + return callback(metric_data); +} + +} // namespace metrics + +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif \ No newline at end of file diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index f939035fb2..a4decaaa79 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -18,45 +18,114 @@ using namespace opentelemetry::sdk::metrics; using namespace opentelemetry::sdk::instrumentationlibrary; using namespace opentelemetry::sdk::resource; -class MockMetricReader : public MetricReader +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::common; +using M = std::map; + +class MockCollectorHandle : public CollectorHandle { public: - MockMetricReader(AggregationTemporality aggr_temporality) : MetricReader(aggr_temporality) {} + MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} - virtual bool OnForceFlush(std::chrono::microseconds timeout) noexcept override { return true; } + AggregationTemporality GetAggregationTemporality() noexcept override { return temporality; } - virtual bool OnShutDown(std::chrono::microseconds timeout) noexcept override { return true; } - - virtual void OnInitialized() noexcept override {} +private: + AggregationTemporality temporality; }; -void measurement_fetch(opentelemetry::metrics::ObserverResult &observer_result) +class WritableMetricStorageTestFixture : public ::testing::TestWithParam +{}; + +class MeasurementFetcher { - observer_result.Observe(20l); - observer_result.Observe(10l); -} +public: + static void Fetcher(opentelemetry::metrics::ObserverResult &observer_result) + { + fetch_count++; + if (fetch_count == 1) + { + observer_result.Observe(20l, {{"RequestType", "GET"}}); + observer_result.Observe(10l, {{"RequestType", "PUT"}}); + number_of_get += 20l; + number_of_put += 10l; + } + else if (fetch_count == 2) + { + observer_result.Observe(40l, {{"RequestType", "GET"}}); + observer_result.Observe(20l, {{"RequestType", "PUT"}}); + number_of_get += 40l; + number_of_put += 20l; + } + } + + static void init_values() + { + fetch_count = 0; + number_of_get = 0; + number_of_put = 0; + } -TEST(AsyncMetricStorageTest, BasicTests) + static size_t fetch_count; + static long number_of_get; + static long number_of_put; + static const size_t number_of_attributes = 2; // GET , PUT +}; + +size_t MeasurementFetcher::fetch_count; +long MeasurementFetcher::number_of_get; +long MeasurementFetcher::number_of_put; +const size_t MeasurementFetcher::number_of_attributes; + +TEST_P(WritableMetricStorageTestFixture, TestAggregation) { - auto metric_callback = [](MetricData &&metric_data) { return true; }; - InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, + MeasurementFetcher::init_values(); + AggregationTemporality temporality = GetParam(); + + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kObservableCounter, InstrumentValueType::kLong}; auto sdk_start_ts = std::chrono::system_clock::now(); // Some computation here auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5); - std::shared_ptr meter_context(new MeterContext()); - std::unique_ptr metric_reader(new MockMetricReader(AggregationTemporality::kDelta)); + std::shared_ptr collector(new MockCollectorHandle(temporality)); + std::vector> collectors; + collectors.push_back(collector); + size_t count_attributes = 0; + long value = 0; - std::shared_ptr collector = std::shared_ptr( - new MetricCollector(std::move(meter_context), std::move(metric_reader))); + MeasurementFetcher measurement_fetcher; + opentelemetry::sdk::metrics::AsyncMetricStorage storage(instr_desc, AggregationType::kSum, + MeasurementFetcher::Fetcher, + new DefaultAttributesProcessor()); - std::vector> collectors{collector}; - - opentelemetry::sdk::metrics::AsyncMetricStorage storage( - instr_desc, AggregationType::kSum, &measurement_fetch, new DefaultAttributesProcessor()); - EXPECT_NO_THROW( - storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, metric_callback)); + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), + MeasurementFetcher::number_of_get); + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), + MeasurementFetcher::number_of_put); + } + count_attributes++; + } + return true; + }); + EXPECT_EQ(MeasurementFetcher::number_of_attributes, count_attributes); } + +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + #endif \ No newline at end of file From 59a48c1c99bbc8822d66eaf9edbe3f384092b125 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Tue, 3 May 2022 17:26:43 -0700 Subject: [PATCH 50/69] fix baggage propagation for empty/invalid baggage context (#1367) --- .../baggage/propagation/baggage_propagator.h | 16 ++++++++-- .../propagation/baggage_propagator_test.cc | 29 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/api/include/opentelemetry/baggage/propagation/baggage_propagator.h b/api/include/opentelemetry/baggage/propagation/baggage_propagator.h index 11abd3107e..3de60860b2 100644 --- a/api/include/opentelemetry/baggage/propagation/baggage_propagator.h +++ b/api/include/opentelemetry/baggage/propagation/baggage_propagator.h @@ -21,7 +21,11 @@ class BaggagePropagator : public opentelemetry::context::propagation::TextMapPro const opentelemetry::context::Context &context) noexcept override { auto baggage = opentelemetry::baggage::GetBaggage(context); - carrier.Set(kBaggageHeader, baggage->ToHeader()); + auto header = baggage->ToHeader(); + if (header.size()) + { + carrier.Set(kBaggageHeader, header); + } } context::Context Extract(const opentelemetry::context::propagation::TextMapCarrier &carrier, @@ -29,7 +33,15 @@ class BaggagePropagator : public opentelemetry::context::propagation::TextMapPro { nostd::string_view baggage_str = carrier.Get(opentelemetry::baggage::kBaggageHeader); auto baggage = opentelemetry::baggage::Baggage::FromHeader(baggage_str); - return opentelemetry::baggage::SetBaggage(context, baggage); + + if (baggage->ToHeader().size()) + { + return opentelemetry::baggage::SetBaggage(context, baggage); + } + else + { + return context; + } } bool Fields(nostd::function_ref callback) const noexcept override diff --git a/api/test/baggage/propagation/baggage_propagator_test.cc b/api/test/baggage/propagation/baggage_propagator_test.cc index 0f1f8f338c..94fe8b005b 100644 --- a/api/test/baggage/propagation/baggage_propagator_test.cc +++ b/api/test/baggage/propagation/baggage_propagator_test.cc @@ -82,3 +82,32 @@ TEST(BaggagePropagatorTest, ExtractAndInjectBaggage) EXPECT_EQ(fields[0], baggage::kBaggageHeader.data()); } } + +TEST(BaggagePropagatorTest, InjectEmptyHeader) +{ + // Test Missing baggage from context + BaggageCarrierTest carrier; + context::Context ctx = context::Context{}; + format.Inject(carrier, ctx); + EXPECT_EQ(carrier.headers_.find(baggage::kBaggageHeader), carrier.headers_.end()); + + { + // Test empty baggage in context + BaggageCarrierTest carrier1; + carrier1.headers_[baggage::kBaggageHeader.data()] = ""; + context::Context ctx1 = context::Context{}; + context::Context ctx2 = format.Extract(carrier1, ctx1); + format.Inject(carrier, ctx2); + EXPECT_EQ(carrier.headers_.find(baggage::kBaggageHeader), carrier.headers_.end()); + } + { + // Invalid baggage in context + BaggageCarrierTest carrier1; + carrier1.headers_[baggage::kBaggageHeader.data()] = "InvalidBaggageData"; + context::Context ctx1 = context::Context{}; + context::Context ctx2 = format.Extract(carrier1, ctx1); + + format.Inject(carrier, ctx2); + EXPECT_EQ(carrier.headers_.find(baggage::kBaggageHeader), carrier.headers_.end()); + } +} From d3c4200654b359aa9ffc0c0e29a72ac97025fde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zsolt=20B=C3=B6l=C3=B6ny?= Date: Thu, 5 May 2022 20:49:23 +0200 Subject: [PATCH 51/69] Fix empty tracestate header propagation (#1373) --- .../opentelemetry/trace/propagation/http_trace_context.h | 6 +++++- api/test/trace/propagation/http_text_format_test.cc | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/api/include/opentelemetry/trace/propagation/http_trace_context.h b/api/include/opentelemetry/trace/propagation/http_trace_context.h index 91905b794e..9440960be3 100644 --- a/api/include/opentelemetry/trace/propagation/http_trace_context.h +++ b/api/include/opentelemetry/trace/propagation/http_trace_context.h @@ -100,7 +100,11 @@ class HttpTraceContext : public opentelemetry::context::propagation::TextMapProp nostd::span{&trace_parent[kTraceIdSize + kSpanIdSize + 5], 2}); carrier.Set(kTraceParent, nostd::string_view(trace_parent, sizeof(trace_parent))); - carrier.Set(kTraceState, span_context.trace_state()->ToHeader()); + const auto trace_state = span_context.trace_state()->ToHeader(); + if (!trace_state.empty()) + { + carrier.Set(kTraceState, trace_state); + } } static SpanContext ExtractContextFromTraceHeaders(nostd::string_view trace_parent, diff --git a/api/test/trace/propagation/http_text_format_test.cc b/api/test/trace/propagation/http_text_format_test.cc index d42d508860..8fa0e44ed2 100644 --- a/api/test/trace/propagation/http_text_format_test.cc +++ b/api/test/trace/propagation/http_text_format_test.cc @@ -55,8 +55,8 @@ TEST(TextMapPropagatorTest, NoSendEmptyTraceState) context::Context ctx2 = format.Extract(carrier, ctx1); TextMapCarrierTest carrier2; format.Inject(carrier2, ctx2); - EXPECT_TRUE(carrier.headers_.count("traceparent") > 0); - EXPECT_FALSE(carrier.headers_.count("tracestate") > 0); + EXPECT_TRUE(carrier2.headers_.count("traceparent") > 0); + EXPECT_FALSE(carrier2.headers_.count("tracestate") > 0); } TEST(TextMapPropagatorTest, PropogateTraceState) @@ -72,8 +72,8 @@ TEST(TextMapPropagatorTest, PropogateTraceState) TextMapCarrierTest carrier2; format.Inject(carrier2, ctx2); - EXPECT_TRUE(carrier.headers_.count("traceparent") > 0); - EXPECT_TRUE(carrier.headers_.count("tracestate") > 0); + EXPECT_TRUE(carrier2.headers_.count("traceparent") > 0); + EXPECT_TRUE(carrier2.headers_.count("tracestate") > 0); EXPECT_EQ(carrier2.headers_["tracestate"], "congo=t61rcWkgMzE"); } From 5458dde947ce28c4c259606d63ae83a1bad03492 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 May 2022 20:50:24 -0700 Subject: [PATCH 52/69] Bump docker/setup-qemu-action from 1 to 2 (#1375) --- .github/workflows/dependencies_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependencies_image.yml b/.github/workflows/dependencies_image.yml index aa7d923071..d04ec4b856 100644 --- a/.github/workflows/dependencies_image.yml +++ b/.github/workflows/dependencies_image.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v2 - name: Set up QEMU - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx id: buildx From 99a72e1ae06ea97a189e5fa00ef7d1d76af39913 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Fri, 6 May 2022 07:21:22 -0700 Subject: [PATCH 53/69] Add noexcept/const qualifier at missing places for Trace API. (#1374) * fix noxcept * fix etw --- api/include/opentelemetry/baggage/baggage.h | 18 ++++++++------- .../opentelemetry/baggage/baggage_context.h | 7 +++--- .../opentelemetry/common/kv_properties.h | 22 +++++++++---------- .../opentelemetry/common/string_util.h | 4 ++-- api/include/opentelemetry/context/context.h | 4 ++-- .../opentelemetry/context/runtime_context.h | 2 +- api/include/opentelemetry/trace/context.h | 4 ++-- .../opentelemetry/trace/default_span.h | 8 +++---- api/include/opentelemetry/trace/noop.h | 9 ++++---- .../opentelemetry/trace/span_context.h | 2 +- api/include/opentelemetry/trace/trace_state.h | 9 ++++---- .../opentelemetry/trace/tracer_provider.h | 2 +- api/test/trace/provider_test.cc | 2 +- .../opentelemetry/exporters/etw/etw_tracer.h | 2 +- 14 files changed, 50 insertions(+), 45 deletions(-) diff --git a/api/include/opentelemetry/baggage/baggage.h b/api/include/opentelemetry/baggage/baggage.h index 259fd7f3b6..eb5e4dcc7c 100644 --- a/api/include/opentelemetry/baggage/baggage.h +++ b/api/include/opentelemetry/baggage/baggage.h @@ -25,11 +25,12 @@ class Baggage static constexpr char kMembersSeparator = ','; static constexpr char kMetadataSeparator = ';'; - Baggage() : kv_properties_(new opentelemetry::common::KeyValueProperties()) {} - Baggage(size_t size) : kv_properties_(new opentelemetry::common::KeyValueProperties(size)){}; + Baggage() noexcept : kv_properties_(new opentelemetry::common::KeyValueProperties()) {} + Baggage(size_t size) noexcept + : kv_properties_(new opentelemetry::common::KeyValueProperties(size)){}; template - Baggage(const T &keys_and_values) + Baggage(const T &keys_and_values) noexcept : kv_properties_(new opentelemetry::common::KeyValueProperties(keys_and_values)) {} @@ -42,7 +43,7 @@ class Baggage /* Get value for key in the baggage @returns true if key is found, false otherwise */ - bool GetValue(nostd::string_view key, std::string &value) const + bool GetValue(nostd::string_view key, std::string &value) const noexcept { return kv_properties_->GetValue(key, value); } @@ -50,7 +51,8 @@ class Baggage /* Returns shared_ptr of new baggage object which contains new key-value pair. If key or value is invalid, copy of current baggage is returned */ - nostd::shared_ptr Set(const nostd::string_view &key, const nostd::string_view &value) + nostd::shared_ptr Set(const nostd::string_view &key, + const nostd::string_view &value) noexcept { nostd::shared_ptr baggage(new Baggage(kv_properties_->Size() + 1)); @@ -89,7 +91,7 @@ class Baggage // if key does not exist, copy of current baggage is returned. // Validity of key is not checked as invalid keys should never be populated in baggage in the // first place. - nostd::shared_ptr Delete(nostd::string_view key) + nostd::shared_ptr Delete(nostd::string_view key) noexcept { // keeping size of baggage same as key might not be found in it nostd::shared_ptr baggage(new Baggage(kv_properties_->Size())); @@ -103,7 +105,7 @@ class Baggage } // Returns shared_ptr of baggage after extracting key-value pairs from header - static nostd::shared_ptr FromHeader(nostd::string_view header) + static nostd::shared_ptr FromHeader(nostd::string_view header) noexcept { if (header.size() > kMaxSize) { @@ -158,7 +160,7 @@ class Baggage } // Creates string from baggage object. - std::string ToHeader() const + std::string ToHeader() const noexcept { std::string header_s; bool first = true; diff --git a/api/include/opentelemetry/baggage/baggage_context.h b/api/include/opentelemetry/baggage/baggage_context.h index b2b61703f8..9a92bac77f 100644 --- a/api/include/opentelemetry/baggage/baggage_context.h +++ b/api/include/opentelemetry/baggage/baggage_context.h @@ -16,7 +16,7 @@ namespace baggage static const std::string kBaggageHeader = "baggage"; inline nostd::shared_ptr GetBaggage( - const opentelemetry::context::Context &context) + const opentelemetry::context::Context &context) noexcept { context::ContextValue context_value = context.GetValue(kBaggageHeader); if (nostd::holds_alternative>(context_value)) @@ -28,8 +28,9 @@ inline nostd::shared_ptr GetBaggage( return empty_baggage; } -inline context::Context SetBaggage(opentelemetry::context::Context &context, - nostd::shared_ptr baggage) +inline context::Context SetBaggage( + opentelemetry::context::Context &context, + nostd::shared_ptr baggage) noexcept { return context.SetValue(kBaggageHeader, baggage); } diff --git a/api/include/opentelemetry/common/kv_properties.h b/api/include/opentelemetry/common/kv_properties.h index 799fd293c7..7ac747a733 100644 --- a/api/include/opentelemetry/common/kv_properties.h +++ b/api/include/opentelemetry/common/kv_properties.h @@ -33,7 +33,7 @@ class KeyValueStringTokenizer public: KeyValueStringTokenizer( nostd::string_view str, - const KeyValueStringTokenizerOptions &opts = KeyValueStringTokenizerOptions()) + const KeyValueStringTokenizerOptions &opts = KeyValueStringTokenizerOptions()) noexcept : str_(str), opts_(opts), index_(0) {} @@ -48,7 +48,7 @@ class KeyValueStringTokenizer // @param key : key in kv pair // @param key : value in kv pair // @returns true if next kv pair was found, false otherwise. - bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) + bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) noexcept { valid_kv = true; while (index_ < str_.size()) @@ -170,13 +170,13 @@ class KeyValueProperties } // Gets the key associated with this entry. - nostd::string_view GetKey() const { return key_.get(); } + nostd::string_view GetKey() const noexcept { return key_.get(); } // Gets the value associated with this entry. - nostd::string_view GetValue() const { return value_.get(); } + nostd::string_view GetValue() const noexcept { return value_.get(); } // Sets the value for this entry. This overrides the previous value. - void SetValue(nostd::string_view value) { value_ = CopyStringToPointer(value); } + void SetValue(nostd::string_view value) noexcept { value_ = CopyStringToPointer(value); } private: // Store key and value as raw char pointers to avoid using std::string. @@ -206,15 +206,15 @@ class KeyValueProperties public: // Create Key-value list of given size // @param size : Size of list. - KeyValueProperties(size_t size) + KeyValueProperties(size_t size) noexcept : num_entries_(0), max_num_entries_(size), entries_(new Entry[size]) {} // Create Empty Key-Value list - KeyValueProperties() : num_entries_(0), max_num_entries_(0), entries_(nullptr) {} + KeyValueProperties() noexcept : num_entries_(0), max_num_entries_(0), entries_(nullptr) {} template ::value>::type> - KeyValueProperties(const T &keys_and_values) + KeyValueProperties(const T &keys_and_values) noexcept : num_entries_(0), max_num_entries_(keys_and_values.size()), entries_(new Entry[max_num_entries_]) @@ -227,7 +227,7 @@ class KeyValueProperties } // Adds new kv pair into kv properties - void AddEntry(nostd::string_view key, nostd::string_view value) + void AddEntry(nostd::string_view key, nostd::string_view value) noexcept { if (num_entries_ < max_num_entries_) { @@ -238,7 +238,7 @@ class KeyValueProperties // Returns all kv pair entries bool GetAllEntries( - nostd::function_ref callback) const + nostd::function_ref callback) const noexcept { for (size_t i = 0; i < num_entries_; i++) { @@ -252,7 +252,7 @@ class KeyValueProperties } // Return value for key if exists, return false otherwise - bool GetValue(nostd::string_view key, std::string &value) const + bool GetValue(nostd::string_view key, std::string &value) const noexcept { for (size_t i = 0; i < num_entries_; i++) { diff --git a/api/include/opentelemetry/common/string_util.h b/api/include/opentelemetry/common/string_util.h index 00f80db992..ffee86c96b 100644 --- a/api/include/opentelemetry/common/string_util.h +++ b/api/include/opentelemetry/common/string_util.h @@ -26,7 +26,7 @@ namespace common class StringUtil { public: - static nostd::string_view Trim(nostd::string_view str, size_t left, size_t right) + static nostd::string_view Trim(nostd::string_view str, size_t left, size_t right) noexcept { while (str[static_cast(left)] == ' ' && left <= right) { @@ -39,7 +39,7 @@ class StringUtil return str.substr(left, 1 + right - left); } - static nostd::string_view Trim(nostd::string_view str) + static nostd::string_view Trim(nostd::string_view str) noexcept { if (str.empty()) { diff --git a/api/include/opentelemetry/context/context.h b/api/include/opentelemetry/context/context.h index 50cfde3c4f..923b396c7f 100644 --- a/api/include/opentelemetry/context/context.h +++ b/api/include/opentelemetry/context/context.h @@ -24,14 +24,14 @@ class Context // Creates a context object from a map of keys and identifiers, this will // hold a shared_ptr to the head of the DataList linked list template - Context(const T &keys_and_values) + Context(const T &keys_and_values) noexcept { head_ = nostd::shared_ptr{new DataList(keys_and_values)}; } // Creates a context object from a key and value, this will // hold a shared_ptr to the head of the DataList linked list - Context(nostd::string_view key, ContextValue value) + Context(nostd::string_view key, ContextValue value) noexcept { head_ = nostd::shared_ptr{new DataList(key, value)}; } diff --git a/api/include/opentelemetry/context/runtime_context.h b/api/include/opentelemetry/context/runtime_context.h index 74fa2151ea..167a928f10 100644 --- a/api/include/opentelemetry/context/runtime_context.h +++ b/api/include/opentelemetry/context/runtime_context.h @@ -173,7 +173,7 @@ class RuntimeContext } }; -inline Token::~Token() +inline Token::~Token() noexcept { context::RuntimeContext::Detach(*this); } diff --git a/api/include/opentelemetry/trace/context.h b/api/include/opentelemetry/trace/context.h index 165f1540b9..963c187177 100644 --- a/api/include/opentelemetry/trace/context.h +++ b/api/include/opentelemetry/trace/context.h @@ -12,7 +12,7 @@ namespace trace { // Get Span from explicit context -inline nostd::shared_ptr GetSpan(const opentelemetry::context::Context &context) +inline nostd::shared_ptr GetSpan(const opentelemetry::context::Context &context) noexcept { context::ContextValue span = context.GetValue(kSpanKey); if (nostd::holds_alternative>(span)) @@ -24,7 +24,7 @@ inline nostd::shared_ptr GetSpan(const opentelemetry::context::Context &co // Set Span into explicit context inline context::Context SetSpan(opentelemetry::context::Context &context, - nostd::shared_ptr span) + nostd::shared_ptr span) noexcept { return context.SetValue(kSpanKey, span); } diff --git a/api/include/opentelemetry/trace/default_span.h b/api/include/opentelemetry/trace/default_span.h index 6755704291..fadd92386f 100644 --- a/api/include/opentelemetry/trace/default_span.h +++ b/api/include/opentelemetry/trace/default_span.h @@ -50,13 +50,13 @@ class DefaultSpan : public Span void End(const EndSpanOptions & /* options */ = {}) noexcept {} - nostd::string_view ToString() { return "DefaultSpan"; } + nostd::string_view ToString() const noexcept { return "DefaultSpan"; } - DefaultSpan(SpanContext span_context) : span_context_(span_context) {} + DefaultSpan(SpanContext span_context) noexcept : span_context_(span_context) {} // movable and copiable - DefaultSpan(DefaultSpan &&spn) : span_context_(spn.GetContext()) {} - DefaultSpan(const DefaultSpan &spn) : span_context_(spn.GetContext()) {} + DefaultSpan(DefaultSpan &&spn) noexcept : span_context_(spn.GetContext()) {} + DefaultSpan(const DefaultSpan &spn) noexcept : span_context_(spn.GetContext()) {} private: SpanContext span_context_; diff --git a/api/include/opentelemetry/trace/noop.h b/api/include/opentelemetry/trace/noop.h index 1257ebd279..e7784c4be6 100644 --- a/api/include/opentelemetry/trace/noop.h +++ b/api/include/opentelemetry/trace/noop.h @@ -100,14 +100,15 @@ class NoopTracer final : public Tracer, public std::enable_shared_from_this( new opentelemetry::trace::NoopTracer)} {} - nostd::shared_ptr GetTracer(nostd::string_view library_name, - nostd::string_view library_version, - nostd::string_view schema_url) override + nostd::shared_ptr GetTracer( + nostd::string_view library_name, + nostd::string_view library_version, + nostd::string_view schema_url) noexcept override { return tracer_; } diff --git a/api/include/opentelemetry/trace/span_context.h b/api/include/opentelemetry/trace/span_context.h index 569a3c1e71..ca13a8df60 100644 --- a/api/include/opentelemetry/trace/span_context.h +++ b/api/include/opentelemetry/trace/span_context.h @@ -26,7 +26,7 @@ class SpanContext final * sampled * @param is_remote true if this context was propagated from a remote parent. */ - SpanContext(bool sampled_flag, bool is_remote) + SpanContext(bool sampled_flag, bool is_remote) noexcept : trace_id_(), span_id_(), trace_flags_(opentelemetry::trace::TraceFlags((uint8_t)sampled_flag)), diff --git a/api/include/opentelemetry/trace/trace_state.h b/api/include/opentelemetry/trace/trace_state.h index 1dc0457356..0343637cfa 100644 --- a/api/include/opentelemetry/trace/trace_state.h +++ b/api/include/opentelemetry/trace/trace_state.h @@ -53,7 +53,7 @@ class TraceState * the W3C Trace Context specification https://www.w3.org/TR/trace-context/ * @return TraceState A new TraceState instance or DEFAULT */ - static nostd::shared_ptr FromHeader(nostd::string_view header) + static nostd::shared_ptr FromHeader(nostd::string_view header) noexcept { common::KeyValueStringTokenizer kv_str_tokenizer(header); @@ -89,7 +89,7 @@ class TraceState /** * Creates a w3c tracestate header from TraceState object */ - std::string ToHeader() + std::string ToHeader() const noexcept { std::string header_s; bool first = true; @@ -135,7 +135,8 @@ class TraceState * * If the existing object has maximum list members, it's copy is returned. */ - nostd::shared_ptr Set(const nostd::string_view &key, const nostd::string_view &value) + nostd::shared_ptr Set(const nostd::string_view &key, + const nostd::string_view &value) noexcept { auto curr_size = kv_properties_->Size(); if (!IsValidKey(key) || !IsValidValue(value)) @@ -168,7 +169,7 @@ class TraceState * @returns empty TraceState object if key is invalid * @returns copy of original TraceState object if key is not present (??) */ - nostd::shared_ptr Delete(const nostd::string_view &key) + nostd::shared_ptr Delete(const nostd::string_view &key) noexcept { if (!IsValidKey(key)) { diff --git a/api/include/opentelemetry/trace/tracer_provider.h b/api/include/opentelemetry/trace/tracer_provider.h index 540a2f6b24..2dae74ce14 100644 --- a/api/include/opentelemetry/trace/tracer_provider.h +++ b/api/include/opentelemetry/trace/tracer_provider.h @@ -25,7 +25,7 @@ class TracerProvider */ virtual nostd::shared_ptr GetTracer(nostd::string_view library_name, nostd::string_view library_version = "", - nostd::string_view schema_url = "") = 0; + nostd::string_view schema_url = "") noexcept = 0; }; } // namespace trace OPENTELEMETRY_END_NAMESPACE diff --git a/api/test/trace/provider_test.cc b/api/test/trace/provider_test.cc index 3c4bd1e74e..9e5a7aad1d 100644 --- a/api/test/trace/provider_test.cc +++ b/api/test/trace/provider_test.cc @@ -16,7 +16,7 @@ class TestProvider : public TracerProvider { nostd::shared_ptr GetTracer(nostd::string_view library_name, nostd::string_view library_version, - nostd::string_view schema_url) override + nostd::string_view schema_url) noexcept override { return nostd::shared_ptr(nullptr); } diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 82bd6d726c..5db31a7a75 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -980,7 +980,7 @@ class TracerProvider : public opentelemetry::trace::TracerProvider nostd::shared_ptr GetTracer( nostd::string_view name, nostd::string_view args = "", - nostd::string_view schema_url = "") override + nostd::string_view schema_url = "") noexcept override { UNREFERENCED_PARAMETER(args); UNREFERENCED_PARAMETER(schema_url); From a0d4a7215a20869bdf2a72966ac223a67f29a428 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 May 2022 19:25:08 +0000 Subject: [PATCH 54/69] Bump docker/build-push-action from 2 to 3 (#1377) --- .github/workflows/dependencies_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependencies_image.yml b/.github/workflows/dependencies_image.yml index d04ec4b856..c4a94efab0 100644 --- a/.github/workflows/dependencies_image.yml +++ b/.github/workflows/dependencies_image.yml @@ -21,7 +21,7 @@ jobs: uses: docker/setup-buildx-action@v1 - name: Build Image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 with: builder: ${{ steps.buildx.outputs.name }} context: ci/ From 0d27a43a2f0ff42499162dd760ad79620061cf6b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 May 2022 20:14:25 +0000 Subject: [PATCH 55/69] Bump docker/setup-buildx-action from 1 to 2 (#1376) --- .github/workflows/dependencies_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependencies_image.yml b/.github/workflows/dependencies_image.yml index c4a94efab0..3a55a0b4e8 100644 --- a/.github/workflows/dependencies_image.yml +++ b/.github/workflows/dependencies_image.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Build Image uses: docker/build-push-action@v3 From 02630e0b6d5875625ba85985494a4182b01ed89a Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Sat, 7 May 2022 00:45:44 -0700 Subject: [PATCH 56/69] [Metrics SDK] Remove un-necessary files. (#1379) --- .../exporters/ostream/metric_exporter.h | 4 +-- .../sdk/metrics/aggregator/aggregator.h | 24 ----------------- .../sdk/metrics/metric_exporter.h | 2 +- .../opentelemetry/sdk/metrics/recordable.h | 26 ------------------- 4 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h delete mode 100644 sdk/include/opentelemetry/sdk/metrics/recordable.h diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h index 465ae02bb6..56b6c577b0 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h @@ -7,11 +7,9 @@ # include # include # include "opentelemetry/common/spin_lock_mutex.h" -# include "opentelemetry/nostd/span.h" # include "opentelemetry/sdk/metrics/data/metric_data.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/metric_exporter.h" -# include "opentelemetry/sdk/metrics/recordable.h" # include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -28,7 +26,7 @@ class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricEx public: /** * Create an OStreamMetricExporter. This constructor takes in a reference to an ostream that the - * export() function will send span data into. + * export() function will send metrics data into. * The default ostream is set to stdout */ explicit OStreamMetricExporter(std::ostream &sout = std::cout) noexcept; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h b/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h deleted file mode 100644 index 416cea5adf..0000000000 --- a/sdk/include/opentelemetry/sdk/metrics/aggregator/aggregator.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once -#ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/sdk/metrics/aggregation/aggregation.h" -# include "opentelemetry/version.h" -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace metrics -{ -class Aggregator -{}; - -class NoOpAggregator : public Aggregator -{ - // TBD -}; - -} // namespace metrics -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h index 127ef468ac..3217b83df5 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h @@ -29,7 +29,7 @@ class MetricExporter virtual ~MetricExporter() = default; /** - * Exports a batch of metrics recordables. This method must not be called + * Exports a batch of metrics data. This method must not be called * concurrently for the same exporter instance. * @param data metrics data */ diff --git a/sdk/include/opentelemetry/sdk/metrics/recordable.h b/sdk/include/opentelemetry/sdk/metrics/recordable.h deleted file mode 100644 index d7e7f5756e..0000000000 --- a/sdk/include/opentelemetry/sdk/metrics/recordable.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once -#ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/nostd/string_view.h" -# include "opentelemetry/version.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace metrics -{ -class Recordable -{ -public: - virtual ~Recordable() = default; - nostd::string_view GetName() { return name_; } - // TBD -private: - nostd::string_view name_; -}; -} // namespace metrics -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE; -#endif From 54abc2741b10efef07f786bb5200fd9112b191bb Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 9 May 2022 15:47:08 -0700 Subject: [PATCH 57/69] reuse temporal metric storage for sync storage (#1369) --- .../sdk/metrics/state/sync_metric_storage.h | 21 +--- sdk/src/metrics/state/sync_metric_storage.cc | 99 +------------------ 2 files changed, 7 insertions(+), 113 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h index c16f33ede2..278f7dbe3f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -5,16 +5,14 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/common/key_value_iterable_view.h" # include "opentelemetry/sdk/common/attributemap_hash.h" -# include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/exemplar/reservoir.h" # include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" # include "opentelemetry/sdk/metrics/state/metric_collector.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" +# include "opentelemetry/sdk/metrics/state/temporal_metric_storage.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" -# include "opentelemetry/sdk/metrics/view/view.h" -# include "opentelemetry/sdk/resource/resource.h" # include # include @@ -24,13 +22,6 @@ namespace sdk { namespace metrics { - -struct LastReportedMetrics -{ - std::unique_ptr attributes_map; - opentelemetry::common::SystemTimestamp collection_ts; -}; - class SyncMetricStorage : public MetricStorage, public WritableMetricStorage { @@ -43,7 +34,9 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage aggregation_type_{aggregation_type}, attributes_hashmap_(new AttributesHashMap()), attributes_processor_{attributes_processor}, - exemplar_reservoir_(exemplar_reservoir) + exemplar_reservoir_(exemplar_reservoir), + temporal_metric_storage_(instrument_descriptor) + { create_default_aggregation_ = [&]() -> std::unique_ptr { return std::move( @@ -114,14 +107,10 @@ class SyncMetricStorage : public MetricStorage, public WritableMetricStorage // hashmap to maintain the metrics for delta collection (i.e, collection since last Collect call) std::unique_ptr attributes_hashmap_; - // unreported metrics stash for all the collectors - std::unordered_map>> - unreported_metrics_; - // last reported metrics stash for all the collectors. - std::unordered_map last_reported_metrics_; const AttributesProcessor *attributes_processor_; std::function()> create_default_aggregation_; nostd::shared_ptr exemplar_reservoir_; + TemporalMetricStorage temporal_metric_storage_; }; } // namespace metrics diff --git a/sdk/src/metrics/state/sync_metric_storage.cc b/sdk/src/metrics/state/sync_metric_storage.cc index f42de82b4b..8c79f9d7ca 100644 --- a/sdk/src/metrics/state/sync_metric_storage.cc +++ b/sdk/src/metrics/state/sync_metric_storage.cc @@ -25,104 +25,9 @@ bool SyncMetricStorage::Collect(CollectorHandle *collector, // recordings std::shared_ptr delta_metrics = std::move(attributes_hashmap_); attributes_hashmap_.reset(new AttributesHashMap); - for (auto &col : collectors) - { - unreported_metrics_[col.get()].push_back(delta_metrics); - } - // Get the unreported metrics for the `collector` from `unreported metrics stash` - // since last collection, this will also cleanup the unreported metrics for `collector` - // from the stash. - auto present = unreported_metrics_.find(collector); - if (present == unreported_metrics_.end()) - { - // no unreported metrics for the collector, return. - return true; - } - auto unreported_list = std::move(present->second); - - // Iterate over the unreporter metrics for `collector` and store result in `merged_metrics` - std::unique_ptr merged_metrics(new AttributesHashMap); - for (auto &agg_hashmap : unreported_list) - { - agg_hashmap->GetAllEnteries([&merged_metrics, this](const MetricAttributes &attributes, - Aggregation &aggregation) { - auto agg = merged_metrics->Get(attributes); - if (agg) - { - merged_metrics->Set(attributes, std::move(agg->Merge(aggregation))); - } - else - { - merged_metrics->Set( - attributes, - std::move( - DefaultAggregation::CreateAggregation(instrument_descriptor_)->Merge(aggregation))); - merged_metrics->GetAllEnteries( - [](const MetricAttributes &attr, Aggregation &aggr) { return true; }); - } - return true; - }); - } - // Get the last reported metrics for the `collector` from `last reported metrics` stash - // - If the aggregation_temporarily for the collector is cumulative - // - Merge the last reported metrics with unreported metrics (which is in merged_metrics), - // Final result of merge would be in merged_metrics. - // - Move the final merge to the `last reported metrics` stash. - // - If the aggregation_temporarily is delta - // - Store the unreported metrics for `collector` (which is in merged_mtrics) to - // `last reported metrics` stash. - - auto reported = last_reported_metrics_.find(collector); - if (reported != last_reported_metrics_.end()) - { - last_collection_ts = last_reported_metrics_[collector].collection_ts; - auto last_aggr_hashmap = std::move(last_reported_metrics_[collector].attributes_map); - if (aggregation_temporarily == AggregationTemporality::kCumulative) - { - // merge current delta to previous cumulative - last_aggr_hashmap->GetAllEnteries( - [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { - auto agg = merged_metrics->Get(attributes); - if (agg) - { - merged_metrics->Set(attributes, agg->Merge(aggregation)); - } - else - { - merged_metrics->Set(attributes, - DefaultAggregation::CreateAggregation(instrument_descriptor_)); - } - return true; - }); - } - last_reported_metrics_[collector] = - LastReportedMetrics{std::move(merged_metrics), collection_ts}; - } - else - { - merged_metrics->GetAllEnteries( - [](const MetricAttributes &attr, Aggregation &aggr) { return true; }); - last_reported_metrics_.insert( - std::make_pair(collector, LastReportedMetrics{std::move(merged_metrics), collection_ts})); - } - - // Generate the MetricData from the final merged_metrics, and invoke callback over it. - - AttributesHashMap *result_to_export = (last_reported_metrics_[collector]).attributes_map.get(); - MetricData metric_data; - metric_data.instrument_descriptor = instrument_descriptor_; - metric_data.start_ts = last_collection_ts; - metric_data.end_ts = collection_ts; - result_to_export->GetAllEnteries( - [&metric_data](const MetricAttributes &attributes, Aggregation &aggregation) { - PointDataAttributes point_data_attr; - point_data_attr.point_data = aggregation.ToPoint(); - point_data_attr.attributes = attributes; - metric_data.point_data_attr_.push_back(point_data_attr); - return true; - }); - return callback(metric_data); + return temporal_metric_storage_.buildMetrics(collector, collectors, sdk_start_ts, collection_ts, + std::move(delta_metrics), callback); } } // namespace metrics From 95effbde67c5a567bc384f38b766fa1926f51aca Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Tue, 10 May 2022 19:55:05 +0200 Subject: [PATCH 58/69] Prometheus exporter meters and instrument name (#1378) --- .../exporters/prometheus/exporter_utils.h | 13 --- exporters/prometheus/src/exporter_utils.cc | 93 ++++++++----------- sdk/src/metrics/meter.cc | 14 ++- 3 files changed, 47 insertions(+), 73 deletions(-) diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h index 1cb7202ce5..cfbbb9c48b 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h @@ -34,12 +34,6 @@ class PrometheusExporterUtils const std::vector> &data); private: - /** - * Set value to metric family according to record - */ - static void SetMetricFamily(sdk::metrics::ResourceMetrics &data, - ::prometheus::MetricFamily *metric_family); - /** * Sanitize the given metric name or label according to Prometheus rule. * @@ -49,13 +43,6 @@ class PrometheusExporterUtils */ static std::string SanitizeNames(std::string name); - /** - * Set value to metric family for different aggregator - */ - static void SetMetricFamilyByAggregator(const sdk::metrics::ResourceMetrics &data, - std::string labels_str, - ::prometheus::MetricFamily *metric_family); - static opentelemetry::sdk::metrics::AggregationType getAggregationType( const opentelemetry::sdk::metrics::PointType &point_type); diff --git a/exporters/prometheus/src/exporter_utils.cc b/exporters/prometheus/src/exporter_utils.cc index 39131e210f..9979c9bebd 100644 --- a/exporters/prometheus/src/exporter_utils.cc +++ b/exporters/prometheus/src/exporter_utils.cc @@ -34,28 +34,51 @@ std::vector PrometheusExporterUtils::TranslateT } // initialize output vector - std::vector output(data.size()); + std::vector output; // iterate through the vector and set result data into it - int i = 0; for (const auto &r : data) { - SetMetricFamily(*r, &output[i]); - i++; + for (const auto &instrumentation_info : r->instrumentation_info_metric_data_) + { + for (const auto &metric_data : instrumentation_info.metric_data_) + { + auto origin_name = metric_data.instrument_descriptor.name_; + auto sanitized = SanitizeNames(origin_name); + prometheus_client::MetricFamily metric_family; + metric_family.name = sanitized; + metric_family.help = metric_data.instrument_descriptor.description_; + auto time = metric_data.start_ts.time_since_epoch(); + for (const auto &point_data_attr : metric_data.point_data_attr_) + { + auto kind = getAggregationType(point_data_attr.point_data); + const prometheus_client::MetricType type = TranslateType(kind); + metric_family.type = type; + if (type == prometheus_client::MetricType::Histogram) // Histogram + { + auto histogram_point_data = + nostd::get(point_data_attr.point_data); + auto boundaries = histogram_point_data.boundaries_; + auto counts = histogram_point_data.counts_; + SetData(std::vector{nostd::get(histogram_point_data.sum_), + (double)histogram_point_data.count_}, + boundaries, counts, "", time, &metric_family); + } + else // Counter, Untyped + { + auto sum_point_data = + nostd::get(point_data_attr.point_data); + std::vector values{sum_point_data.value_}; + SetData(values, "", type, time, &metric_family); + } + } + output.emplace_back(metric_family); + } + } } - return output; } -/** - * Set value to metric family according to record - */ -void PrometheusExporterUtils::SetMetricFamily(sdk::metrics::ResourceMetrics &data, - prometheus_client::MetricFamily *metric_family) -{ - SetMetricFamilyByAggregator(data, "", metric_family); -} - /** * Sanitize the given metric name or label according to Prometheus rule. * @@ -72,48 +95,6 @@ std::string PrometheusExporterUtils::SanitizeNames(std::string name) return name; } -/** - * Set value to metric family for different aggregator - */ -void PrometheusExporterUtils::SetMetricFamilyByAggregator( - const sdk::metrics::ResourceMetrics &data, - std::string labels_str, - prometheus_client::MetricFamily *metric_family) -{ - for (const auto &instrumentation_info : data.instrumentation_info_metric_data_) - { - auto origin_name = instrumentation_info.instrumentation_library_->GetName(); - auto sanitized = SanitizeNames(origin_name); - metric_family->name = sanitized; - for (const auto &metric_data : instrumentation_info.metric_data_) - { - auto time = metric_data.start_ts.time_since_epoch(); - for (const auto &point_data_attr : metric_data.point_data_attr_) - { - auto kind = getAggregationType(point_data_attr.point_data); - const prometheus_client::MetricType type = TranslateType(kind); - metric_family->type = type; - if (type == prometheus_client::MetricType::Histogram) // Histogram - { - auto histogram_point_data = - nostd::get(point_data_attr.point_data); - auto boundaries = histogram_point_data.boundaries_; - auto counts = histogram_point_data.counts_; - SetData(std::vector{nostd::get(histogram_point_data.sum_), - (double)histogram_point_data.count_}, - boundaries, counts, labels_str, time, metric_family); - } - else // Counter, Untyped - { - auto sum_point_data = nostd::get(point_data_attr.point_data); - std::vector values{sum_point_data.value_}; - SetData(values, labels_str, type, time, metric_family); - } - } - } - } -} - metric_sdk::AggregationType PrometheusExporterUtils::getAggregationType( const metric_sdk::PointType &point_type) { diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index c0b0ce7a57..ce638c22e6 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -188,10 +188,16 @@ std::unique_ptr Meter::RegisterMetricStorage( auto success = view_registry->FindViews( instrument_descriptor, *instrumentation_library_, [this, &instrument_descriptor, &storages](const View &view) { - auto view_instr_desc = instrument_descriptor; - view_instr_desc.name_ = view.GetName(); - view_instr_desc.description_ = view.GetDescription(); - auto storage = std::shared_ptr(new SyncMetricStorage( + auto view_instr_desc = instrument_descriptor; + if (!view.GetName().empty()) + { + view_instr_desc.name_ = view.GetName(); + } + if (!view.GetDescription().empty()) + { + view_instr_desc.description_ = view.GetDescription(); + } + auto storage = std::shared_ptr(new SyncMetricStorage( view_instr_desc, view.GetAggregationType(), &view.GetAttributesProcessor(), NoExemplarReservoir::GetNoExemplarReservoir())); storage_registry_[instrument_descriptor.name_] = storage; From 88e23ad469c6439226d929c6f949f4af48e1135c Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Wed, 11 May 2022 13:03:11 -0700 Subject: [PATCH 59/69] Fix sharing resource in batched exported spans (#1386) Co-authored-by: Lalit Kumar Bhasin --- exporters/otlp/src/otlp_recordable_utils.cc | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/exporters/otlp/src/otlp_recordable_utils.cc b/exporters/otlp/src/otlp_recordable_utils.cc index 483f01f905..b981448de1 100644 --- a/exporters/otlp/src/otlp_recordable_utils.cc +++ b/exporters/otlp/src/otlp_recordable_utils.cc @@ -259,25 +259,19 @@ void OtlpRecordableUtils::PopulateRequest( return; } - auto resource_span = request->add_resource_spans(); - auto instrumentation_lib = resource_span->add_instrumentation_library_spans(); - bool first_pass = true; - for (auto &recordable : spans) { auto rec = std::unique_ptr(static_cast(recordable.release())); + auto resource_span = request->add_resource_spans(); + auto instrumentation_lib = resource_span->add_instrumentation_library_spans(); + *instrumentation_lib->add_spans() = std::move(rec->span()); *instrumentation_lib->mutable_instrumentation_library() = rec->GetProtoInstrumentationLibrary(); - if (first_pass) - { - instrumentation_lib->set_schema_url(rec->GetInstrumentationLibrarySchemaURL()); + instrumentation_lib->set_schema_url(rec->GetInstrumentationLibrarySchemaURL()); - *resource_span->mutable_resource() = rec->ProtoResource(); - resource_span->set_schema_url(rec->GetResourceSchemaURL()); - - first_pass = false; - } + *resource_span->mutable_resource() = rec->ProtoResource(); + resource_span->set_schema_url(rec->GetResourceSchemaURL()); } } From 4b69a107ae4328fbb7f7dc4a1ad0055cc33a0011 Mon Sep 17 00:00:00 2001 From: Leo Di Donato Date: Fri, 13 May 2022 22:40:00 +0200 Subject: [PATCH 60/69] fix: missing link to nlohmann_json (#1390) --- exporters/elasticsearch/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exporters/elasticsearch/CMakeLists.txt b/exporters/elasticsearch/CMakeLists.txt index b21dae400a..ed6488316c 100644 --- a/exporters/elasticsearch/CMakeLists.txt +++ b/exporters/elasticsearch/CMakeLists.txt @@ -10,7 +10,8 @@ target_include_directories( target_link_libraries( opentelemetry_exporter_elasticsearch_logs - PUBLIC opentelemetry_trace opentelemetry_logs opentelemetry_http_client_curl) + PUBLIC opentelemetry_trace opentelemetry_logs opentelemetry_http_client_curl + nlohmann_json::nlohmann_json) install( TARGETS opentelemetry_exporter_elasticsearch_logs From 3fd5ca38a0371b0ce64a6b90f54a6af00cc0d96b Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 16 May 2022 16:53:40 +0200 Subject: [PATCH 61/69] Getting started document using ostream exporter (#1394) Co-authored-by: Reiley Yang --- examples/metrics_simple/README.md | 111 ++++++++---------- exporters/ostream/src/metric_exporter.cc | 1 + exporters/ostream/test/ostream_metric_test.cc | 4 + 3 files changed, 55 insertions(+), 61 deletions(-) diff --git a/examples/metrics_simple/README.md b/examples/metrics_simple/README.md index 41d683c782..b2c5dc0a74 100644 --- a/examples/metrics_simple/README.md +++ b/examples/metrics_simple/README.md @@ -1,83 +1,72 @@ # Simple Metrics Example -In this example, the application in `main.cc` initializes the metrics pipeline -and shows 3 different ways of updating instrument values. Here are more detailed -explanations of each part. +This example initializes the metrics pipeline with 2 different instrument types. +Here are more detailed explanations of each part. -1: Initialize a MeterProvider. We will use this to obtain Meter objects in the -future. - -`auto provider = shared_ptr(new MeterProvider);` - -2: Set the MeterProvider as the default instance for the library. This ensures -that we will have access to the same MeterProvider across our application. - -`Provider::SetMeterProvider(provider);` - -3: Obtain a meter from this meter provider. Every Meter pointer returned by the -MeterProvider points to the same Meter. This means that the Meter will be able -to combine metrics captured from different functions without having to -constantly pass the Meter around the library. - -`shared_ptr meter = provider→GetMeter("Test");` - -4: Initialize an exporter and processor. In this case, we initialize an OStream -Exporter which will print to stdout by default. The Processor is an -UngroupedProcessor which doesn’t filter or group captured metrics in any way. -The false parameter indicates that this processor will send metric deltas rather -than metric cumulatives. +1: Initialize an exporter and a reader. In this case, we initialize an OStream +Exporter which will print to stdout by default. +The reader periodically collects metrics from the collector and exports them. ```cpp -unique_ptr exporter = unique_ptr(new OStreamMetricsExporter); -shared_ptr processor = shared_ptr(new UngroupedMetricsProcessor(false)); +std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; +std::unique_ptr reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; ``` -5: Pass the meter, exporter, and processor into the controller. Since this is a -push controller, a collection interval parameter (in seconds) is also taken. At -each collection interval, the controller will request data from all of the -instruments in the code and export them. Start the controller to begin the -metrics pipeline. +2: Initialize a MeterProvider and add the reader. +We will use this to obtain Meter objects in the future. -`metrics_sdk::PushController controller(meter, std::move(exporter), processor, -5);` `controller.start();` +```cpp +auto provider = std::shared_ptr(new opentelemetry::metrics::MeterProvider()); +auto p = std::static_pointer_cast(provider); +p->AddMetricReader(std::move(reader)); +``` -6: Instrument code with synchronous and asynchronous instrument. These -instruments can be placed in areas of interest to collect metrics and are -created by the meter. Synchronous instruments are updated whenever the user -desires with a value and label set. Calling add on a counter instrument for -example will increase its value. Asynchronous instruments can be updated the -same way, but are intended to receive updates from a callback function. The -callback below observes a value of 1. The user never has to call this function -as it is automatically called by the controller. +3: Create and add a view to the provider. ```cpp -// Observer callback function -void SumObserverCallback(metrics_api::ObserverResult result){ - std::map labels = {{"key", "value"}}; - auto labelkv = common::KeyValueIterableView{labels}; - result.observe(1,labelkv); -} +std::unique_ptr instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, "name_counter")}; +std::unique_ptr meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; +std::unique_ptr sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; +p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); +``` -// Create new instruments -auto ctr= meter->NewIntCounter("Counter","none", "none", true); -auto obs= meter->NewIntSumObserver("Counter","none", "none", true, &SumObserverCallback); +4: Then create a +[Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter) +instrument from it. Every Meter pointer returned by the +MeterProvider points to the same Meter. This means that the Meter will be able +to combine metrics captured from different functions without having to +constantly pass the Meter around the library. +```cpp +nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); +auto double_counter = meter->CreateDoubleCounter(counter_name); // Create a label set which annotates metric values std::map labels = {{"key", "value"}}; auto labelkv = common::KeyValueIterableView{labels}; - -// Capture data from instruments. Note that the asynchronous instrument is updates -// automatically though its callback at the collection interval. Additional measurments -// can be made through calls to its observe function. -ctr->add(5, labelkv); - +double_counter->Add(val, labelkv); ``` -7: Stop the controller once the program finished. This ensures that any metrics -inside the pipeline are properly exported. Otherwise, some metrics may be -destroyed in cleanup. +5: To use histogram instrument, a view with proper `InstrumentType` and `AggregationType` +has to be added to the provider. -`controller.stop();` +```cpp +std::unique_ptr histogram_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, "histogram_name")}; +std::unique_ptr histogram_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; +std::unique_ptr histogram_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}}; +p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); + +auto histogram_counter = meter->CreateDoubleHistogram("histogram_name"); +auto context = opentelemetry::context::Context{}; +histogram_counter->Record(val, labelkv, context); +``` See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and running the example. diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index bf97db04c2..18e73a310c 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -96,6 +96,7 @@ void OStreamMetricExporter::printInstrumentationInfoMetricData( { sout_ << "\n start time\t: " << timeToString(record.start_ts) << "\n end time\t: " << timeToString(record.end_ts) + << "\n name\t\t: " << record.instrument_descriptor.name_ << "\n description\t: " << record.instrument_descriptor.description_ << "\n unit\t\t: " << record.instrument_descriptor.unit_; diff --git a/exporters/ostream/test/ostream_metric_test.cc b/exporters/ostream/test/ostream_metric_test.cc index 3618d93e7a..82c1be2bc7 100644 --- a/exporters/ostream/test/ostream_metric_test.cc +++ b/exporters/ostream/test/ostream_metric_test.cc @@ -70,6 +70,7 @@ TEST(OStreamMetricsExporter, ExportSumPointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n type\t\t: SumPointData" @@ -128,6 +129,7 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n type : HistogramPointData" @@ -190,6 +192,7 @@ TEST(OStreamMetricsExporter, ExportLastValuePointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n type : LastValuePointData" @@ -244,6 +247,7 @@ TEST(OStreamMetricsExporter, ExportDropPointData) "\n version\t: 1.2.0" "\n start time\t: Thu Jan 1 00:00:00 1970" "\n end time\t: Thu Jan 1 00:00:00 1970" + "\n name\t\t: library_name" "\n description\t: description" "\n unit\t\t: unit" "\n}\n"; From 45f0235dda385e306ffe423ba3834c124005d9ce Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 16 May 2022 11:10:13 -0700 Subject: [PATCH 62/69] Connect async storage with async instruments (#1388) --- api/include/opentelemetry/metrics/meter.h | 56 +++++------ api/include/opentelemetry/metrics/noop.h | 84 ++++++---------- .../common/metrics_foo_library/foo_library.cc | 27 ++++++ .../common/metrics_foo_library/foo_library.h | 1 + examples/metrics_simple/metrics_ostream.cc | 19 ++++ sdk/include/opentelemetry/sdk/metrics/meter.h | 53 ++++++---- sdk/src/metrics/meter.cc | 96 +++++++++++-------- 7 files changed, 191 insertions(+), 145 deletions(-) diff --git a/api/include/opentelemetry/metrics/meter.h b/api/include/opentelemetry/metrics/meter.h index 9f7f2d2b0a..6a19911390 100644 --- a/api/include/opentelemetry/metrics/meter.h +++ b/api/include/opentelemetry/metrics/meter.h @@ -56,17 +56,15 @@ class Meter * @param callback the function to be observed by the instrument. * @return a shared pointer to the created Observable Counter. */ - virtual nostd::shared_ptr> CreateLongObservableCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + virtual void CreateLongObservableCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; - virtual nostd::shared_ptr> CreateDoubleObservableCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + virtual void CreateDoubleObservableCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; /** * Creates a Histogram with the passed characteristics and returns a shared_ptr to that Histogram. @@ -96,17 +94,15 @@ class Meter * @param callback the function to be observed by the instrument. * @return a shared pointer to the created Observable Gauge. */ - virtual nostd::shared_ptr> CreateLongObservableGauge( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + virtual void CreateLongObservableGauge(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; - virtual nostd::shared_ptr> CreateDoubleObservableGauge( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + virtual void CreateDoubleObservableGauge(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; /** * Creates an UpDownCounter with the passed characteristics and returns a shared_ptr to that @@ -137,17 +133,15 @@ class Meter * @param callback the function to be observed by the instrument. * @return a shared pointer to the created Observable UpDownCounter. */ - virtual nostd::shared_ptr> CreateLongObservableUpDownCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; - - virtual nostd::shared_ptr> CreateDoubleObservableUpDownCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + virtual void CreateLongObservableUpDownCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual void CreateDoubleObservableUpDownCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; }; } // namespace metrics OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index 3332384ee2..0fbda060b9 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -137,25 +137,17 @@ class NoopMeter final : public Meter return nostd::shared_ptr>{new NoopCounter(name, description, unit)}; } - nostd::shared_ptr> CreateLongObservableCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr>{ - new NoopObservableCounter(name, callback, description, unit)}; - } + void CreateLongObservableCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + {} - nostd::shared_ptr> CreateDoubleObservableCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr>{ - new NoopObservableCounter(name, callback, description, unit)}; - } + void CreateDoubleObservableCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + {} nostd::shared_ptr> CreateLongHistogram( nostd::string_view name, @@ -173,25 +165,17 @@ class NoopMeter final : public Meter return nostd::shared_ptr>{new NoopHistogram(name, description, unit)}; } - nostd::shared_ptr> CreateLongObservableGauge( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr>{ - new NoopObservableGauge(name, callback, description, unit)}; - } + void CreateLongObservableGauge(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + {} - nostd::shared_ptr> CreateDoubleObservableGauge( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr>{ - new NoopObservableGauge(name, callback, description, unit)}; - } + void CreateDoubleObservableGauge(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + {} nostd::shared_ptr> CreateLongUpDownCounter( nostd::string_view name, @@ -211,25 +195,17 @@ class NoopMeter final : public Meter new NoopUpDownCounter(name, description, unit)}; } - nostd::shared_ptr> CreateLongObservableUpDownCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr>{ - new NoopObservableUpDownCounter(name, callback, description, unit)}; - } + void CreateLongObservableUpDownCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + {} - nostd::shared_ptr> CreateDoubleObservableUpDownCounter( - nostd::string_view name, - void (*callback)(ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override - { - return nostd::shared_ptr>{ - new NoopObservableUpDownCounter(name, callback, description, unit)}; - } + void CreateDoubleObservableUpDownCounter(nostd::string_view name, + void (*callback)(ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + {} }; /** diff --git a/examples/common/metrics_foo_library/foo_library.cc b/examples/common/metrics_foo_library/foo_library.cc index cd15adad5b..79e0cbc5ab 100644 --- a/examples/common/metrics_foo_library/foo_library.cc +++ b/examples/common/metrics_foo_library/foo_library.cc @@ -6,6 +6,8 @@ # include # include # include +# include +# include "opentelemetry/context/context.h" # include "opentelemetry/metrics/provider.h" namespace nostd = opentelemetry::nostd; @@ -13,6 +15,7 @@ namespace metrics_api = opentelemetry::metrics; namespace { + std::map get_random_attr() { static const std::vector> labels = {{"key1", "value1"}, @@ -23,6 +26,18 @@ std::map get_random_attr() return std::map{labels[rand() % (labels.size() - 1)], labels[rand() % (labels.size() - 1)]}; } + +class MeasurementFetcher +{ +public: + static void Fetcher(opentelemetry::metrics::ObserverResult &observer_result) + { + double val = (rand() % 700) + 1.1; + std::map labels = get_random_attr(); + auto labelkv = opentelemetry::common::KeyValueIterableView{labels}; + observer_result.Observe(val /*, labelkv*/); + } +}; } // namespace void foo_library::counter_example(const std::string &name) @@ -40,6 +55,18 @@ void foo_library::counter_example(const std::string &name) } } +void foo_library::observable_counter_example(const std::string &name) +{ + std::string counter_name = name + "_observable_counter"; + auto provider = metrics_api::Provider::GetMeterProvider(); + nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); + meter->CreateDoubleObservableCounter(counter_name, MeasurementFetcher::Fetcher); + while (true) + { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } +} + void foo_library::histogram_example(const std::string &name) { std::string histogram_name = name + "_histogram"; diff --git a/examples/common/metrics_foo_library/foo_library.h b/examples/common/metrics_foo_library/foo_library.h index 73cd30d2d5..2f84bcc34f 100644 --- a/examples/common/metrics_foo_library/foo_library.h +++ b/examples/common/metrics_foo_library/foo_library.h @@ -10,5 +10,6 @@ class foo_library public: static void counter_example(const std::string &name); static void histogram_example(const std::string &name); + static void observable_counter_example(const std::string &name); }; #endif diff --git a/examples/metrics_simple/metrics_ostream.cc b/examples/metrics_simple/metrics_ostream.cc index ebb8b34b8a..585856f91f 100644 --- a/examples/metrics_simple/metrics_ostream.cc +++ b/examples/metrics_simple/metrics_ostream.cc @@ -54,6 +54,18 @@ void initMetrics(const std::string &name) new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + // observable counter view + std::string observable_counter_name = name + "_observable_counter"; + std::unique_ptr observable_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kObservableCounter, + observable_counter_name)}; + std::unique_ptr observable_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr observable_sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + p->AddView(std::move(observable_instrument_selector), std::move(observable_meter_selector), + std::move(observable_sum_view)); + // histogram view std::string histogram_name = name + "_histogram"; std::unique_ptr histogram_instrument_selector{ @@ -83,6 +95,10 @@ int main(int argc, char **argv) { foo_library::counter_example(name); } + else if (example_type == "observable_counter") + { + foo_library::observable_counter_example(name); + } else if (example_type == "histogram") { foo_library::histogram_example(name); @@ -90,8 +106,11 @@ int main(int argc, char **argv) else { std::thread counter_example{&foo_library::counter_example, name}; + std::thread observable_counter_example{&foo_library::observable_counter_example, name}; std::thread histogram_example{&foo_library::histogram_example, name}; + counter_example.join(); + observable_counter_example.join(); histogram_example.join(); } } diff --git a/sdk/include/opentelemetry/sdk/metrics/meter.h b/sdk/include/opentelemetry/sdk/metrics/meter.h index 4a6ea26aeb..9d9595f660 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter.h @@ -8,6 +8,8 @@ # include "opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/meter_context.h" +# include "opentelemetry/sdk/metrics/state/async_metric_storage.h" + # include "opentelemetry/sdk/resource/resource.h" # include "opentelemetry/version.h" @@ -40,18 +42,17 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateLongObservableCounter( + void CreateLongObservableCounter(nostd::string_view name, + void (*callback)(opentelemetry::metrics::ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override; + + void CreateDoubleObservableCounter( nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> - CreateDoubleObservableCounter(nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "1") noexcept override; - nostd::shared_ptr> CreateLongHistogram( nostd::string_view name, nostd::string_view description = "", @@ -62,13 +63,12 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateLongObservableGauge( - nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + void CreateLongObservableGauge(nostd::string_view name, + void (*callback)(opentelemetry::metrics::ObserverResult &), + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateDoubleObservableGauge( + void CreateDoubleObservableGauge( nostd::string_view name, void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", @@ -84,15 +84,13 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> - CreateLongObservableUpDownCounter( + void CreateLongObservableUpDownCounter( nostd::string_view name, void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> - CreateDoubleObservableUpDownCounter( + void CreateDoubleObservableUpDownCounter( nostd::string_view name, void (*callback)(opentelemetry::metrics::ObserverResult &), nostd::string_view description = "", @@ -116,6 +114,25 @@ class Meter final : public opentelemetry::metrics::Meter std::unique_ptr RegisterMetricStorage( InstrumentDescriptor &instrument_descriptor); + + template + void RegisterAsyncMetricStorage(InstrumentDescriptor &instrument_descriptor, + void (*callback)(opentelemetry::metrics::ObserverResult &)) + { + auto view_registry = meter_context_->GetViewRegistry(); + auto success = view_registry->FindViews( + instrument_descriptor, *instrumentation_library_, + [this, &instrument_descriptor, callback](const View &view) { + auto view_instr_desc = instrument_descriptor; + view_instr_desc.name_ = view.GetName(); + view_instr_desc.description_ = view.GetDescription(); + auto storage = std::shared_ptr>( + new AsyncMetricStorage(view_instr_desc, view.GetAggregationType(), callback, + &view.GetAttributesProcessor())); + storage_registry_[instrument_descriptor.name_] = storage; + return true; + }); + } }; } // namespace metrics } // namespace sdk diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index ce638c22e6..30725bdccf 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -57,24 +57,28 @@ nostd::shared_ptr> Meter::CreateDoubleCounter( new DoubleCounter(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr> Meter::CreateLongObservableCounter( - nostd::string_view name, - void (*callback)(metrics::ObserverResult &), - nostd::string_view description, - nostd::string_view unit) noexcept +void Meter::CreateLongObservableCounter(nostd::string_view name, + void (*callback)(metrics::ObserverResult &), + nostd::string_view description, + nostd::string_view unit) noexcept { - return nostd::shared_ptr>{ - new LongObservableCounter(name, callback, description, unit)}; + InstrumentDescriptor instrument_descriptor = { + std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, + std::string{unit.data(), unit.size()}, InstrumentType::kObservableCounter, + InstrumentValueType::kLong}; + RegisterAsyncMetricStorage(instrument_descriptor, callback); } -nostd::shared_ptr> Meter::CreateDoubleObservableCounter( - nostd::string_view name, - void (*callback)(metrics::ObserverResult &), - nostd::string_view description, - nostd::string_view unit) noexcept +void Meter::CreateDoubleObservableCounter(nostd::string_view name, + void (*callback)(metrics::ObserverResult &), + nostd::string_view description, + nostd::string_view unit) noexcept { - return nostd::shared_ptr>{ - new DoubleObservableCounter(name, callback, description, unit)}; + InstrumentDescriptor instrument_descriptor = { + std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, + std::string{unit.data(), unit.size()}, InstrumentType::kObservableCounter, + InstrumentValueType::kDouble}; + RegisterAsyncMetricStorage(instrument_descriptor, callback); } nostd::shared_ptr> Meter::CreateLongHistogram( @@ -105,24 +109,28 @@ nostd::shared_ptr> Meter::CreateDoubleHistogram( new DoubleHistogram(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr> Meter::CreateLongObservableGauge( - nostd::string_view name, - void (*callback)(metrics::ObserverResult &), - nostd::string_view description, - nostd::string_view unit) noexcept +void Meter::CreateLongObservableGauge(nostd::string_view name, + void (*callback)(metrics::ObserverResult &), + nostd::string_view description, + nostd::string_view unit) noexcept { - return nostd::shared_ptr>{ - new LongObservableGauge(name, callback, description, unit)}; + InstrumentDescriptor instrument_descriptor = { + std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, + std::string{unit.data(), unit.size()}, InstrumentType::kObservableGauge, + InstrumentValueType::kLong}; + RegisterAsyncMetricStorage(instrument_descriptor, callback); } -nostd::shared_ptr> Meter::CreateDoubleObservableGauge( - nostd::string_view name, - void (*callback)(metrics::ObserverResult &), - nostd::string_view description, - nostd::string_view unit) noexcept +void Meter::CreateDoubleObservableGauge(nostd::string_view name, + void (*callback)(metrics::ObserverResult &), + nostd::string_view description, + nostd::string_view unit) noexcept { - return nostd::shared_ptr>{ - new DoubleObservableGauge(name, callback, description, unit)}; + InstrumentDescriptor instrument_descriptor = { + std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, + std::string{unit.data(), unit.size()}, InstrumentType::kObservableGauge, + InstrumentValueType::kDouble}; + RegisterAsyncMetricStorage(instrument_descriptor, callback); } nostd::shared_ptr> Meter::CreateLongUpDownCounter( @@ -153,24 +161,28 @@ nostd::shared_ptr> Meter::CreateDoubleUpDownCount new DoubleUpDownCounter(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr> Meter::CreateLongObservableUpDownCounter( - nostd::string_view name, - void (*callback)(metrics::ObserverResult &), - nostd::string_view description, - nostd::string_view unit) noexcept +void Meter::CreateLongObservableUpDownCounter(nostd::string_view name, + void (*callback)(metrics::ObserverResult &), + nostd::string_view description, + nostd::string_view unit) noexcept { - return nostd::shared_ptr>{ - new LongObservableUpDownCounter(name, callback, description, unit)}; + InstrumentDescriptor instrument_descriptor = { + std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, + std::string{unit.data(), unit.size()}, InstrumentType::kObservableUpDownCounter, + InstrumentValueType::kLong}; + RegisterAsyncMetricStorage(instrument_descriptor, callback); } -nostd::shared_ptr> -Meter::CreateDoubleObservableUpDownCounter(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), - nostd::string_view description, - nostd::string_view unit) noexcept +void Meter::CreateDoubleObservableUpDownCounter(nostd::string_view name, + void (*callback)(metrics::ObserverResult &), + nostd::string_view description, + nostd::string_view unit) noexcept { - return nostd::shared_ptr>{ - new DoubleObservableUpDownCounter(name, callback, description, unit)}; + InstrumentDescriptor instrument_descriptor = { + std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, + std::string{unit.data(), unit.size()}, InstrumentType::kObservableUpDownCounter, + InstrumentValueType::kDouble}; + RegisterAsyncMetricStorage(instrument_descriptor, callback); } const sdk::instrumentationlibrary::InstrumentationLibrary *Meter::GetInstrumentationLibrary() From e11cc62c47cd7d68c8ad23db96df99e99bb1a3b3 Mon Sep 17 00:00:00 2001 From: Hamed Mansouri Date: Mon, 16 May 2022 23:43:28 +0430 Subject: [PATCH 63/69] get span_id from context when Logger::Log received invalid span_id (#1398) --- sdk/src/logs/logger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/src/logs/logger.cc b/sdk/src/logs/logger.cc index 0222b786bc..fc690c6773 100644 --- a/sdk/src/logs/logger.cc +++ b/sdk/src/logs/logger.cc @@ -99,7 +99,7 @@ void Logger::Log(opentelemetry::logs::Severity severity, } else if (span_context.span_id().IsValid()) { - recordable->SetSpanId(span_id); + recordable->SetSpanId(span_context.span_id()); } // TraceFlags From 1e25d58a11f235c3e7a1dc63b0b6ad4a711a26e4 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Mon, 16 May 2022 22:59:15 +0200 Subject: [PATCH 64/69] Alpine image (#1382) --- docker/Dockerfile | 36 +++++++++++++++ docker/Dockerfile.alpine.base | 15 ++++++ docker/README.md | 24 ++++++++++ docker/build.sh | 86 ++++++++++++++++++++++++++++++++++ docker/grpc/CMakeLists.txt | 84 +++++++++++++++++++++++++++++++++ docker/grpc/Dockerfile | 21 +++++++++ docker/thrift/CMakeLists.txt | 87 +++++++++++++++++++++++++++++++++++ docker/thrift/Dockerfile | 21 +++++++++ 8 files changed, 374 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/Dockerfile.alpine.base create mode 100644 docker/README.md create mode 100644 docker/build.sh create mode 100644 docker/grpc/CMakeLists.txt create mode 100644 docker/grpc/Dockerfile create mode 100644 docker/thrift/CMakeLists.txt create mode 100644 docker/thrift/Dockerfile diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000000..118cac62f9 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,36 @@ +ARG BASE_IMAGE=ubuntu:latest +ARG GRPC_IMAGE=grpc-${BASE_IMAGE} +ARG THRIFT_IMAGE=thrift-${BASE_IMAGE} + +FROM ${GRPC_IMAGE} as grpc +FROM ${THRIFT_IMAGE} as thrift + +FROM base-${BASE_IMAGE}-dev AS otel-cpp + +ARG CORES=${nproc} +ARG OTEL_GIT_TAG=v1.3.0 + +COPY --from=grpc / /usr/local +COPY --from=thrift / /usr/local + +#install opentelemetry-cpp +RUN git clone --recurse-submodules -j ${CORES} --depth=1 \ + -b ${OTEL_GIT_TAG} https://github.com/open-telemetry/opentelemetry-cpp.git \ + && cd opentelemetry-cpp \ + && mkdir -p build && cd build \ + && cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + -DWITH_ZIPKIN=ON \ + -DWITH_JAEGER=ON \ + -DCMAKE_INSTALL_PREFIX=/opt/third_party/install \ + -DBUILD_TESTING=OFF \ + -DWITH_OTLP=ON \ + -DWITH_OTLP_GRPC=ON \ + -DBUILD_SHARED_LIBS=ON \ + .. \ + && cmake --build . -j ${CORES} --target install + +FROM scratch as final + +COPY --from=otel-cpp /opt/third_party/install / diff --git a/docker/Dockerfile.alpine.base b/docker/Dockerfile.alpine.base new file mode 100644 index 0000000000..2595efa70f --- /dev/null +++ b/docker/Dockerfile.alpine.base @@ -0,0 +1,15 @@ +ARG BASE_IMAGE=alpine:latest +ARG CORES=${nproc} + +FROM ${BASE_IMAGE} as final + +RUN apk update + +RUN apk add --update alpine-sdk \ + && apk add cmake openssl openssl-dev g++ \ + curl-dev git autoconf libtool linux-headers \ + boost-dev libevent-dev openssl-dev + +RUN mkdir -p /opt/third_party/install + +WORKDIR /opt diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000000..165667117c --- /dev/null +++ b/docker/README.md @@ -0,0 +1,24 @@ +# OpenTelemetry library builder + +**How to use this build script:** + +The build script `build.sh` can be used to build OpenTelemetry and +it's dependencies within the desired base image. +The final image only contains the necessary files in `/`. + +```sh +bash build.sh -b alpine -j ${nproc} -g v1.43.2 -o v1.3.0 -t 0.14.1 + +# copy to current dir +docker create -ti --name otel otel-cpp- bash +docker cp otel:/ ./ +docker rm -f otel + +docker create -ti --name grpc grpc- bash +docker cp grpc:/ ./ +docker rm -f grpc + +docker create -ti --name thrift thrift- bash +docker cp thrift:/ ./ +docker rm -f thrift +``` diff --git a/docker/build.sh b/docker/build.sh new file mode 100644 index 0000000000..53773b739f --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +set -o errexit +set -o nounset +set -o pipefail + +Help() +{ + # Display Help + echo "Add description of the script functions here." + echo + echo "Syntax: scriptTemplate [-b|o|g|j]" + echo "options:" + echo "b Base image" + echo "o OpenTelemetry-cpp git tag" + echo "h Print Help." + echo "g gRPC git tag" + echo "t thrift version" + echo "j Parallel jobs" + echo + echo "how to use:" + echo + echo "docker create -ti --name otel otel-cpp- bash" + echo "docker cp otel:/ ./" + echo "docker rm -f otel" + echo + echo "or:" + echo + echo "COPY --from=otel-cpp- /usr" +} + +base_image=${base_image:="alpine"} +grpc_git_tag=${grpc_git_tag:="v1.43.2"} +thrift_version=${thrift_version:="0.14.1"} +otel_git_tag=${otel_git_tag:="v1.3.0"} +cores=${cores:=1} + +while getopts ":h:b:o:g:j:t:" option; do + case $option in + h) # display Help + Help + exit;; + b) # base image + base_image=$OPTARG + ;; + o) # OpenTelemetry-cpp git tag + otel_git_tag=$OPTARG + ;; + g) # gRPC git tag + grpc_git_tag=$OPTARG + ;; + t) # thrfit version + thrift_version=$OPTARG + ;; + j) # number of cores + cores=$OPTARG + ;; + \?) + Help + exit;; + esac +done + +docker build -t base-${base_image}-dev -f Dockerfile.${base_image}.base . + +pushd grpc/ +docker build --build-arg BASE_IMAGE=base-${base_image}-dev \ + --build-arg GRPC_GIT_TAG=${grpc_git_tag} \ + --build-arg CORES=${cores} \ + -t grpc-${base_image} -f Dockerfile . +popd + +pushd thrift/ +docker build --build-arg BASE_IMAGE=base-${base_image}-dev \ + --build-arg THRIFT_VERSION=${thrift_version} \ + --build-arg CORES=${cores} \ + -t thrift-${base_image} -f Dockerfile . +popd + +docker build --build-arg BASE_IMAGE=${base_image} \ + --build-arg CORES=${cores} \ + --build-arg OTEL_GIT_TAG=${otel_git_tag} \ + -t otel-cpp-${base_image} -f Dockerfile . diff --git a/docker/grpc/CMakeLists.txt b/docker/grpc/CMakeLists.txt new file mode 100644 index 0000000000..8cb69cc6c3 --- /dev/null +++ b/docker/grpc/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.11 FATAL_ERROR) + +project( + dependencies + LANGUAGES CXX + VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_FLAGS "-O2") + +set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Build type" FORCE) + +include(GNUInstallDirs) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + +set(INSTALL_LIBDIR + ${CMAKE_INSTALL_LIBDIR} + CACHE PATH "directory for libraries") +set(INSTALL_BINDIR + ${CMAKE_INSTALL_BINDIR} + CACHE PATH "directory for executables") +set(INSTALL_INCLUDEDIR + ${CMAKE_INSTALL_INCLUDEDIR} + CACHE PATH "directory for header files") + +set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME}) +set(INSTALL_CMAKEDIR + ${DEF_INSTALL_CMAKEDIR} + CACHE PATH "directory for CMake files") + +set_property(DIRECTORY PROPERTY EP_BASE ${CMAKE_BINARY_DIR}/subs) + +set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) +message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") + +find_package(OpenSSL REQUIRED) +message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") +message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") + +set(GRPC_GIT_TAG + "v1.45.2" + CACHE STRING "gRPC version") + +include(ExternalProject) +ExternalProject_Add( + grpc + GIT_REPOSITORY https://github.com/grpc/grpc.git + GIT_TAG ${GRPC_GIT_TAG} + GIT_SHALLOW 1 + UPDATE_COMMAND "" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DgRPC_SSL_PROVIDER=package + -DOPENSSL_ROOT_DIR=OpenSSL + -DgRPC_BUILD_TESTS=OFF + -DBUILD_SHARED_LIBS=ON + -DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF + -DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF + -DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF + -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF + CMAKE_CACHE_ARGS -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} + TEST_AFTER_INSTALL 0 + DOWNLOAD_NO_PROGRESS 1 + LOG_CONFIGURE 1 + LOG_BUILD 0 + LOG_INSTALL 1) + +install( + DIRECTORY ${STAGED_INSTALL_PREFIX}/ + DESTINATION . + USE_SOURCE_PERMISSIONS) diff --git a/docker/grpc/Dockerfile b/docker/grpc/Dockerfile new file mode 100644 index 0000000000..fee3082b2d --- /dev/null +++ b/docker/grpc/Dockerfile @@ -0,0 +1,21 @@ +ARG BASE_IMAGE=ubuntu:latest +FROM ${BASE_IMAGE} AS grpc + +ARG CORES=${nproc} +ARG GRPC_GIT_TAG=v1.45.2 + +RUN mkdir mkdir -p /opt/third_party/grpc + +WORKDIR /opt/third_party/grpc + +ADD CMakeLists.txt /opt/third_party/grpc + +RUN mkdir build \ + && cd build \ + && cmake -DCMAKE_INSTALL_PREFIX=/opt/third_party/install \ + -DGRPC_GIT_TAG=${GRPC_GIT_TAG} /opt/third_party/grpc \ + && cmake --build . -j ${CORES} --target install + +FROM scratch as final + +COPY --from=grpc /opt/third_party/install / diff --git a/docker/thrift/CMakeLists.txt b/docker/thrift/CMakeLists.txt new file mode 100644 index 0000000000..0028dc48c7 --- /dev/null +++ b/docker/thrift/CMakeLists.txt @@ -0,0 +1,87 @@ +cmake_minimum_required(VERSION 3.11 FATAL_ERROR) + +project( + dependencies + LANGUAGES CXX + VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_FLAGS "-O2") + +set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Build type" FORCE) + +include(GNUInstallDirs) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) + +set(INSTALL_LIBDIR + ${CMAKE_INSTALL_LIBDIR} + CACHE PATH "directory for libraries") +set(INSTALL_BINDIR + ${CMAKE_INSTALL_BINDIR} + CACHE PATH "directory for executables") +set(INSTALL_INCLUDEDIR + ${CMAKE_INSTALL_INCLUDEDIR} + CACHE PATH "directory for header files") + +set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME}) +set(INSTALL_CMAKEDIR + ${DEF_INSTALL_CMAKEDIR} + CACHE PATH "directory for CMake files") + +set_property(DIRECTORY PROPERTY EP_BASE ${CMAKE_BINARY_DIR}/subs) + +set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) +message(STATUS "${PROJECT_NAME} staged install: ${STAGED_INSTALL_PREFIX}") + +find_package(OpenSSL REQUIRED) +message("OpenSSL include dir: ${OPENSSL_INCLUDE_DIR}") +message("OpenSSL libraries: ${OPENSSL_LIBRARIES}") + +set(THRIFT_VERSION + "0.14.1" + CACHE STRING "thrift version") + +include(ExternalProject) +ExternalProject_Add( + thrift + URL https://github.com/apache/thrift/archive/refs/tags/v${THRIFT_VERSION}.tar.gz + UPDATE_COMMAND "" + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} + -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE + -DBUILD_COMPILER=OFF + -DBUILD_CPP=ON + -DBUILD_LIBRARIES=ON + -DBUILD_NODEJS=OFF + -DBUILD_PYTHON=OFF + -DBUILD_JAVASCRIPT=OFF + -DBUILD_C_GLIB=OFF + -DBUILD_JAVA=OFF + -DBUILD_TESTING=OFF + -DBUILD_TUTORIALS=OFF + -DWITH_STDTHREADS=ON + -DWITH_BOOSTTHREADS=OFF + -DWITH_BOOST_FUNCTIONAL=OFF + -DWITH_BOOST_SMART_PTR=OFF + CMAKE_CACHE_ARGS -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} + TEST_AFTER_INSTALL 0 + DOWNLOAD_NO_PROGRESS 1 + LOG_CONFIGURE 1 + LOG_BUILD 0 + LOG_INSTALL 1) + +install( + DIRECTORY ${STAGED_INSTALL_PREFIX}/ + DESTINATION . + USE_SOURCE_PERMISSIONS) diff --git a/docker/thrift/Dockerfile b/docker/thrift/Dockerfile new file mode 100644 index 0000000000..2c57199f3f --- /dev/null +++ b/docker/thrift/Dockerfile @@ -0,0 +1,21 @@ +ARG BASE_IMAGE=ubuntu:latest +FROM ${BASE_IMAGE} AS thrift + +ARG CORES=${nproc} +ARG THRIFT_VERSION=0.14.1 + +RUN mkdir mkdir -p /opt/third_party/thrift + +WORKDIR /opt/third_party/th + +ADD CMakeLists.txt /opt/third_party/thrift + +RUN mkdir build \ + && cd build \ + && cmake -DCMAKE_INSTALL_PREFIX=/opt/third_party/install \ + -DTHRIFT_VERSION=${THRIFT_VERSION} /opt/third_party/thrift \ + && cmake --build . -j ${CORES} --target install + +FROM scratch as final + +COPY --from=thrift /opt/third_party/install / From 280f546e175070b324efc966064a634d300bdf23 Mon Sep 17 00:00:00 2001 From: WenTao Ou Date: Tue, 17 May 2022 11:46:39 +0800 Subject: [PATCH 65/69] Upgrade proto to v0.17.0, update log data model (#1383) --- .gitmodules | 42 ++-- CHANGELOG.md | 2 + CMakeLists.txt | 5 + api/include/opentelemetry/common/macros.h | 49 +++++ api/include/opentelemetry/logs/logger.h | 184 ++++++++++++------ api/include/opentelemetry/logs/noop.h | 1 - api/test/logs/logger_test.cc | 54 ++++- bazel/repository.bzl | 10 +- ci/do_ci.ps1 | 34 ++-- ci/do_ci.sh | 2 +- ci/install_windows_protobuf.ps1 | 4 +- ci/setup_thrift.ps1 | 11 +- ci/setup_windows_ci_environment.ps1 | 13 +- cmake/opentelemetry-proto.cmake | 17 +- .../common/logs_foo_library/foo_library.cc | 4 +- .../elasticsearch/es_log_recordable.h | 7 +- .../test/es_log_exporter_test.cc | 1 - .../opentelemetry/exporters/etw/etw_logger.h | 26 ++- exporters/etw/test/etw_logger_test.cc | 5 +- exporters/ostream/src/log_exporter.cc | 3 +- exporters/ostream/test/ostream_log_test.cc | 10 +- .../exporters/otlp/otlp_log_recordable.h | 9 +- exporters/otlp/src/otlp_log_recordable.cc | 23 ++- exporters/otlp/src/otlp_recordable_utils.cc | 74 +++++-- .../otlp/test/otlp_grpc_log_exporter_test.cc | 8 +- .../otlp/test/otlp_http_log_exporter_test.cc | 18 +- .../otlp/test/otlp_log_recordable_test.cc | 8 - exporters/otlp/test/otlp_recordable_test.cc | 11 +- .../instrumentation_library.h | 16 +- .../opentelemetry/sdk/logs/log_record.h | 13 -- sdk/include/opentelemetry/sdk/logs/logger.h | 2 - .../opentelemetry/sdk/logs/multi_recordable.h | 6 - .../opentelemetry/sdk/logs/recordable.h | 6 - sdk/src/logs/logger.cc | 2 - sdk/src/logs/logger_provider.cc | 16 +- sdk/src/logs/multi_recordable.cc | 8 - sdk/test/logs/batch_log_processor_test.cc | 22 +-- sdk/test/logs/log_record_test.cc | 3 - sdk/test/logs/logger_provider_sdk_test.cc | 8 +- sdk/test/logs/logger_sdk_test.cc | 8 +- sdk/test/logs/simple_log_processor_test.cc | 4 +- third_party/opentelemetry-proto | 2 +- third_party_release | 8 +- tools/build-vcpkg.sh | 19 +- tools/setup-buildtools.cmd | 20 +- 45 files changed, 493 insertions(+), 305 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5da651fd16..c422e39e27 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,34 +1,34 @@ [submodule "third_party/prometheus-cpp"] - path = third_party/prometheus-cpp - url = https://github.com/jupp0r/prometheus-cpp - branch = master +path = third_party/prometheus-cpp +url = https://github.com/jupp0r/prometheus-cpp +branch = master [submodule "tools/vcpkg"] - path = tools/vcpkg - url = https://github.com/Microsoft/vcpkg - branch = master +path = tools/vcpkg +url = https://github.com/Microsoft/vcpkg +branch = master [submodule "third_party/ms-gsl"] - path = third_party/ms-gsl - url = https://github.com/microsoft/GSL - branch = master +path = third_party/ms-gsl +url = https://github.com/microsoft/GSL +branch = main [submodule "third_party/googletest"] - path = third_party/googletest - url = https://github.com/google/googletest - branch = master +path = third_party/googletest +url = https://github.com/google/googletest +branch = main [submodule "third_party/benchmark"] - path = third_party/benchmark - url = https://github.com/google/benchmark - branch = master +path = third_party/benchmark +url = https://github.com/google/benchmark +branch = main [submodule "third_party/opentelemetry-proto"] - path = third_party/opentelemetry-proto - url = https://github.com/open-telemetry/opentelemetry-proto - branch = master +path = third_party/opentelemetry-proto +url = https://github.com/open-telemetry/opentelemetry-proto +branch = main [submodule "third_party/nlohmann-json"] - path = third_party/nlohmann-json - url = https://github.com/nlohmann/json - branch = master +path = third_party/nlohmann-json +url = https://github.com/nlohmann/json +branch = master diff --git a/CHANGELOG.md b/CHANGELOG.md index 425029d72f..9393523ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Increment the: ## [Unreleased] +* [PROTOCOL \& LOGS] Upgrade proto to v0.17.0, update log data model ([#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383)) + ## [1.3.0] 2022-04-11 * [ETW EXPORTER] ETW provider handle cleanup ([#1322](https://github.com/open-telemetry/opentelemetry-cpp/pull/1322)) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9840aa19a6..6d2b274358 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,11 @@ if(WIN32) option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON) endif(WIN32) +# Do not convert deprecated message to error +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") + add_compile_options(-Wno-error=deprecated-declarations) +endif() + option( WITH_API_ONLY "Only build the API (use as a header-only library). Overrides WITH_EXAMPLES and all options to enable exporters" diff --git a/api/include/opentelemetry/common/macros.h b/api/include/opentelemetry/common/macros.h index 982e368ce3..204c1ed04e 100644 --- a/api/include/opentelemetry/common/macros.h +++ b/api/include/opentelemetry/common/macros.h @@ -7,6 +7,23 @@ #include "opentelemetry/version.h" +#if !defined(OPENTELEMETRY_LIKELY_IF) && defined(__cplusplus) +// GCC 9 has likely attribute but do not support declare it at the beginning of statement +# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) +# if __has_cpp_attribute(likely) +# define OPENTELEMETRY_LIKELY_IF(...) \ + if (__VA_ARGS__) \ + [[likely]] +# endif +# endif +#endif +#if !defined(OPENTELEMETRY_LIKELY_IF) && (defined(__clang__) || defined(__GNUC__)) +# define OPENTELEMETRY_LIKELY_IF(...) if (__builtin_expect(!!(__VA_ARGS__), true)) +#endif +#ifndef OPENTELEMETRY_LIKELY_IF +# define OPENTELEMETRY_LIKELY_IF(...) if (__VA_ARGS__) +#endif + /// \brief Declare variable as maybe unused /// usage: /// OPENTELEMETRY_MAYBE_UNUSED int a; @@ -40,3 +57,35 @@ # endif # endif #endif + +#if defined(__cplusplus) && __cplusplus >= 201402L +# define OPENTELEMETRY_DEPRECATED [[deprecated]] +#elif defined(__clang__) +# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) +#elif defined(__GNUC__) +# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define OPENTELEMETRY_DEPRECATED [[deprecated]] +# else +# define OPENTELEMETRY_DEPRECATED __declspec(deprecated) +# endif +#else +# define OPENTELEMETRY_DEPRECATED +#endif + +#if defined(__cplusplus) && __cplusplus >= 201402L +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] +#elif defined(__clang__) +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) +#elif defined(__GNUC__) +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) +#elif defined(_MSC_VER) +# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] +# else +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __declspec(deprecated(msg)) +# endif +#else +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) +#endif diff --git a/api/include/opentelemetry/logs/logger.h b/api/include/opentelemetry/logs/logger.h index 91e882717f..32c3974a1f 100644 --- a/api/include/opentelemetry/logs/logger.h +++ b/api/include/opentelemetry/logs/logger.h @@ -11,6 +11,7 @@ # include "opentelemetry/common/attribute_value.h" # include "opentelemetry/common/key_value_iterable.h" # include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/common/macros.h" # include "opentelemetry/common/timestamp.h" # include "opentelemetry/logs/severity.h" # include "opentelemetry/nostd/shared_ptr.h" @@ -41,7 +42,6 @@ class Logger * creates a log message with the specific parameters passed. * * @param severity the severity level of the log event. - * @param name the name of the log event. * @param message the string message of the log (perhaps support std::fmt or fmt-lib format). * @param attributes the attributes, stored as a 2D list of key/value pairs, that are associated * with the log event. @@ -57,7 +57,6 @@ class Logger * in order to create a log record. */ virtual void Log(Severity severity, - nostd::string_view name, nostd::string_view body, const common::KeyValueIterable &attributes, trace::TraceId trace_id, @@ -65,6 +64,34 @@ class Logger trace::TraceFlags trace_flags, common::SystemTimestamp timestamp) noexcept = 0; + /** + * Each of the following overloaded Log(...) methods + * creates a log message with the specific parameters passed. + * + * @param severity the severity level of the log event. + * @param name the name of the log event. + * @param message the string message of the log (perhaps support std::fmt or fmt-lib format). + * @param attributes the attributes, stored as a 2D list of key/value pairs, that are associated + * with the log event. + * @param trace_id the trace id associated with the log event. + * @param span_id the span id associate with the log event. + * @param trace_flags the trace flags associated with the log event. + * @param timestamp the timestamp the log record was created. + * @throws No exceptions under any circumstances. + */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") + virtual void Log(Severity severity, + OPENTELEMETRY_MAYBE_UNUSED nostd::string_view name, + nostd::string_view body, + const common::KeyValueIterable &attributes, + trace::TraceId trace_id, + trace::SpanId span_id, + trace::TraceFlags trace_flags, + common::SystemTimestamp timestamp) noexcept + { + Log(severity, body, attributes, trace_id, span_id, trace_flags, timestamp); + } + /*** Overloaded methods for KeyValueIterables ***/ /** * The secondary base Log(...) method that all other Log(...) overloaded methods except the one @@ -72,6 +99,21 @@ class Logger */ template ::value> * = nullptr> + void Log(Severity severity, + nostd::string_view body, + const T &attributes, + trace::TraceId trace_id, + trace::SpanId span_id, + trace::TraceFlags trace_flags, + common::SystemTimestamp timestamp) noexcept + { + Log(severity, body, common::KeyValueIterableView(attributes), trace_id, span_id, trace_flags, + timestamp); + } + + template ::value> * = nullptr> + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Log(Severity severity, nostd::string_view name, nostd::string_view body, @@ -85,6 +127,21 @@ class Logger trace_flags, timestamp); } + void Log(Severity severity, + nostd::string_view body, + std::initializer_list> attributes, + trace::TraceId trace_id, + trace::SpanId span_id, + trace::TraceFlags trace_flags, + common::SystemTimestamp timestamp) noexcept + { + return this->Log(severity, body, + nostd::span>{ + attributes.begin(), attributes.end()}, + trace_id, span_id, trace_flags, timestamp); + } + + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Log(Severity severity, nostd::string_view name, nostd::string_view body, @@ -109,15 +166,10 @@ class Logger */ void Log(Severity severity, nostd::string_view message) noexcept { - this->Log(severity, "", message, {}, {}, {}, {}, std::chrono::system_clock::now()); + this->Log(severity, message, {}, {}, {}, {}, std::chrono::system_clock::now()); } - /** - * Writes a log. - * @param severity The severity of the log - * @param name The name of the log - * @param message The message to log - */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Log(Severity severity, nostd::string_view name, nostd::string_view message) noexcept { this->Log(severity, name, message, {}, {}, {}, {}, std::chrono::system_clock::now()); @@ -132,20 +184,20 @@ class Logger nostd::enable_if_t::value> * = nullptr> void Log(Severity severity, const T &attributes) noexcept { - this->Log(severity, "", "", attributes, {}, {}, {}, std::chrono::system_clock::now()); + this->Log(severity, "", attributes, {}, {}, {}, std::chrono::system_clock::now()); } /** * Writes a log. * @param severity The severity of the log - * @param name The name of the log + * @param message The message to log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Log(Severity severity, nostd::string_view name, const T &attributes) noexcept + void Log(Severity severity, nostd::string_view message, const T &attributes) noexcept { - this->Log(severity, name, "", attributes, {}, {}, {}, std::chrono::system_clock::now()); + this->Log(severity, message, attributes, {}, {}, {}, std::chrono::system_clock::now()); } /** @@ -157,35 +209,46 @@ class Logger std::initializer_list> attributes) noexcept { - this->Log(severity, "", "", attributes, {}, {}, {}, std::chrono::system_clock::now()); + this->Log(severity, "", attributes, {}, {}, {}, std::chrono::system_clock::now()); } /** * Writes a log. * @param severity The severity of the log - * @param name The name of the log + * @param message The message to log * @param attributes The attributes of the log as an initializer list */ void Log(Severity severity, - nostd::string_view name, + nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(severity, name, "", attributes, {}, {}, {}, std::chrono::system_clock::now()); + this->Log(severity, message, attributes, {}, {}, {}, std::chrono::system_clock::now()); } /** * Writes a log. * @param severity The severity of the log - * @param name The name of the log + * @param attributes The attributes, stored as a 2D list of key/value pairs, that are associated + * with the log event + */ + void Log(Severity severity, const common::KeyValueIterable &attributes) noexcept + { + this->Log(severity, "", attributes, {}, {}, {}, std::chrono::system_clock::now()); + } + + /** + * Writes a log. + * @param severity The severity of the log + * @param message The message to log * @param attributes The attributes, stored as a 2D list of key/value pairs, that are associated * with the log event */ void Log(Severity severity, - nostd::string_view name, - common::KeyValueIterable &attributes) noexcept + nostd::string_view message, + const common::KeyValueIterable &attributes) noexcept { - this->Log(severity, name, {}, attributes, {}, {}, {}, std::chrono::system_clock::now()); + this->Log(severity, message, attributes, {}, {}, {}, std::chrono::system_clock::now()); } /** Trace severity overloads **/ @@ -201,6 +264,7 @@ class Logger * @param name The name of the log * @param message The message to log */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Trace(nostd::string_view name, nostd::string_view message) noexcept { this->Log(Severity::kTrace, name, message); @@ -219,14 +283,14 @@ class Logger /** * Writes a log with a severity of trace. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Trace(nostd::string_view name, const T &attributes) noexcept + void Trace(nostd::string_view message, const T &attributes) noexcept { - this->Log(Severity::kTrace, name, attributes); + this->Log(Severity::kTrace, message, attributes); } /** @@ -241,14 +305,14 @@ class Logger /** * Writes a log with a severity of trace. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as an initializer list */ - void Trace(nostd::string_view name, + void Trace(nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(Severity::kTrace, name, attributes); + this->Log(Severity::kTrace, message, attributes); } /** Debug severity overloads **/ @@ -264,6 +328,7 @@ class Logger * @param name The name of the log * @param message The message to log */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Debug(nostd::string_view name, nostd::string_view message) noexcept { this->Log(Severity::kDebug, name, message); @@ -282,14 +347,14 @@ class Logger /** * Writes a log with a severity of debug. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Debug(nostd::string_view name, const T &attributes) noexcept + void Debug(nostd::string_view message, const T &attributes) noexcept { - this->Log(Severity::kDebug, name, attributes); + this->Log(Severity::kDebug, message, attributes); } /** @@ -304,14 +369,14 @@ class Logger /** * Writes a log with a severity of debug. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as an initializer list */ - void Debug(nostd::string_view name, + void Debug(nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(Severity::kDebug, name, attributes); + this->Log(Severity::kDebug, message, attributes); } /** Info severity overloads **/ @@ -327,6 +392,7 @@ class Logger * @param name The name of the log * @param message The message to log */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Info(nostd::string_view name, nostd::string_view message) noexcept { this->Log(Severity::kInfo, name, message); @@ -345,14 +411,14 @@ class Logger /** * Writes a log with a severity of info. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Info(nostd::string_view name, const T &attributes) noexcept + void Info(nostd::string_view message, const T &attributes) noexcept { - this->Log(Severity::kInfo, name, attributes); + this->Log(Severity::kInfo, message, attributes); } /** @@ -367,14 +433,14 @@ class Logger /** * Writes a log with a severity of info. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as an initializer list */ - void Info(nostd::string_view name, + void Info(nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(Severity::kInfo, name, attributes); + this->Log(Severity::kInfo, message, attributes); } /** Warn severity overloads **/ @@ -390,6 +456,7 @@ class Logger * @param name The name of the log * @param message The message to log */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Warn(nostd::string_view name, nostd::string_view message) noexcept { this->Log(Severity::kWarn, name, message); @@ -408,14 +475,14 @@ class Logger /** * Writes a log with a severity of warn. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Warn(nostd::string_view name, const T &attributes) noexcept + void Warn(nostd::string_view message, const T &attributes) noexcept { - this->Log(Severity::kWarn, name, attributes); + this->Log(Severity::kWarn, message, attributes); } /** @@ -430,14 +497,14 @@ class Logger /** * Writes a log with a severity of warn. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as an initializer list */ - void Warn(nostd::string_view name, + void Warn(nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(Severity::kWarn, name, attributes); + this->Log(Severity::kWarn, message, attributes); } /** Error severity overloads **/ @@ -453,6 +520,7 @@ class Logger * @param name The name of the log * @param message The message to log */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Error(nostd::string_view name, nostd::string_view message) noexcept { this->Log(Severity::kError, name, message); @@ -471,14 +539,14 @@ class Logger /** * Writes a log with a severity of error. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Error(nostd::string_view name, const T &attributes) noexcept + void Error(nostd::string_view message, const T &attributes) noexcept { - this->Log(Severity::kError, name, attributes); + this->Log(Severity::kError, message, attributes); } /** @@ -493,14 +561,14 @@ class Logger /** * Writes a log with a severity of error. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as an initializer list */ - void Error(nostd::string_view name, + void Error(nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(Severity::kError, name, attributes); + this->Log(Severity::kError, message, attributes); } /** Fatal severity overloads **/ @@ -516,6 +584,7 @@ class Logger * @param name The name of the log * @param message The message to log */ + OPENTELEMETRY_DEPRECATED_MESSAGE("name will be removed in the future") void Fatal(nostd::string_view name, nostd::string_view message) noexcept { this->Log(Severity::kFatal, name, message); @@ -534,14 +603,14 @@ class Logger /** * Writes a log with a severity of fatal. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as a key/value object */ template ::value> * = nullptr> - void Fatal(nostd::string_view name, const T &attributes) noexcept + void Fatal(nostd::string_view message, const T &attributes) noexcept { - this->Log(Severity::kFatal, name, attributes); + this->Log(Severity::kFatal, message, attributes); } /** @@ -556,16 +625,17 @@ class Logger /** * Writes a log with a severity of fatal. - * @param name The name of the log + * @param message The message of the log * @param attributes The attributes of the log as an initializer list */ - void Fatal(nostd::string_view name, + void Fatal(nostd::string_view message, std::initializer_list> attributes) noexcept { - this->Log(Severity::kFatal, name, attributes); + this->Log(Severity::kFatal, message, attributes); } }; } // namespace logs OPENTELEMETRY_END_NAMESPACE + #endif diff --git a/api/include/opentelemetry/logs/noop.h b/api/include/opentelemetry/logs/noop.h index 8186fb8c76..2816123fde 100644 --- a/api/include/opentelemetry/logs/noop.h +++ b/api/include/opentelemetry/logs/noop.h @@ -42,7 +42,6 @@ class NoopLogger final : public Logger const nostd::string_view GetName() noexcept override { return "noop logger"; } void Log(Severity severity, - nostd::string_view name, nostd::string_view body, const common::KeyValueIterable &attributes, trace::TraceId trace_id, diff --git a/api/test/logs/logger_test.cc b/api/test/logs/logger_test.cc index b2d2d1d60a..07480ef44c 100644 --- a/api/test/logs/logger_test.cc +++ b/api/test/logs/logger_test.cc @@ -26,7 +26,7 @@ namespace trace = opentelemetry::trace; TEST(Logger, GetLoggerDefault) { auto lp = Provider::GetLoggerProvider(); - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = lp->GetLogger("TestLogger", "", "opentelelemtry_library", "", schema_url); auto name = logger->GetName(); EXPECT_NE(nullptr, logger); @@ -41,7 +41,7 @@ TEST(Logger, GetNoopLoggerNameWithArgs) // GetLogger(name, list(args)) std::array sv{"string"}; span args{sv}; - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; lp->GetLogger("NoopLoggerWithArgs", args, "opentelelemtry_library", "", schema_url); // GetLogger(name, string options) @@ -52,7 +52,7 @@ TEST(Logger, GetNoopLoggerNameWithArgs) TEST(Logger, LogMethodOverloads) { auto lp = Provider::GetLoggerProvider(); - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = lp->GetLogger("TestLogger", "", "opentelelemtry_library", "", schema_url); // Create a map to test the logs with @@ -60,19 +60,56 @@ TEST(Logger, LogMethodOverloads) // Log overloads logger->Log(Severity::kTrace, "Test log message"); - logger->Log(Severity::kInfo, "Logging a message", "Test log message"); + logger->Log(Severity::kInfo, "Test log message"); logger->Log(Severity::kDebug, m); logger->Log(Severity::kWarn, "Logging a map", m); logger->Log(Severity::kError, {{"key1", "value 1"}, {"key2", 2}}); logger->Log(Severity::kFatal, "Logging an initializer list", {{"key1", "value 1"}, {"key2", 2}}); + // Deprecated Log overloads + logger->Log(Severity::kTrace, "Log name", "Test log message"); + logger->Log(Severity::kWarn, "Log name", "Logging a map", m, {}, {}, {}, + std::chrono::system_clock::now()); + logger->Log(Severity::kError, "Log name", "Logging a map", {{"key1", "value 1"}, {"key2", 2}}, {}, + {}, {}, std::chrono::system_clock::now()); + logger->Trace("Log name", "Test log message"); + logger->Debug("Log name", "Test log message"); + logger->Info("Log name", "Test log message"); + logger->Warn("Log name", "Test log message"); + logger->Error("Log name", "Test log message"); + logger->Fatal("Log name", "Test log message"); + // Severity methods logger->Trace("Test log message"); - logger->Debug("Logging a message", "Test log message"); + logger->Trace("Test log message", m); + logger->Trace("Test log message", {{"key1", "value 1"}, {"key2", 2}}); + logger->Trace(m); + logger->Trace({{"key1", "value 1"}, {"key2", 2}}); + logger->Debug("Test log message"); + logger->Debug("Test log message", m); + logger->Debug("Test log message", {{"key1", "value 1"}, {"key2", 2}}); + logger->Debug(m); + logger->Debug({{"key1", "value 1"}, {"key2", 2}}); + logger->Info("Test log message"); + logger->Info("Test log message", m); + logger->Info("Test log message", {{"key1", "value 1"}, {"key2", 2}}); logger->Info(m); - logger->Warn("Logging a map", m); + logger->Info({{"key1", "value 1"}, {"key2", 2}}); + logger->Warn("Test log message"); + logger->Warn("Test log message", m); + logger->Warn("Test log message", {{"key1", "value 1"}, {"key2", 2}}); + logger->Warn(m); + logger->Warn({{"key1", "value 1"}, {"key2", 2}}); + logger->Error("Test log message"); + logger->Error("Test log message", m); + logger->Error("Test log message", {{"key1", "value 1"}, {"key2", 2}}); + logger->Error(m); logger->Error({{"key1", "value 1"}, {"key2", 2}}); - logger->Fatal("Logging an initializer list", {{"key1", "value 1"}, {"key2", 2}}); + logger->Fatal("Test log message"); + logger->Fatal("Test log message", m); + logger->Fatal("Test log message", {{"key1", "value 1"}, {"key2", 2}}); + logger->Fatal(m); + logger->Fatal({{"key1", "value 1"}, {"key2", 2}}); } // Define a basic Logger class @@ -81,7 +118,6 @@ class TestLogger : public Logger const nostd::string_view GetName() noexcept override { return "test logger"; } void Log(Severity severity, - string_view name, string_view body, const common::KeyValueIterable &attributes, trace::TraceId trace_id, @@ -122,7 +158,7 @@ TEST(Logger, PushLoggerImplementation) auto lp = Provider::GetLoggerProvider(); // Check that the implementation was pushed by calling TestLogger's GetName() - nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = lp->GetLogger("TestLogger", "", "opentelelemtry_library", "", schema_url); ASSERT_EQ("test logger", logger->GetName()); } diff --git a/bazel/repository.bzl b/bazel/repository.bzl index f3f276e2a5..7d50e12d31 100644 --- a/bazel/repository.bzl +++ b/bazel/repository.bzl @@ -2,7 +2,7 @@ load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") -_ALL_CONTENT = """\ +_ALL_CONTENT = """ filegroup( name = "all_srcs", srcs = glob(["**"]), @@ -74,10 +74,10 @@ def opentelemetry_cpp_deps(): http_archive, name = "com_github_opentelemetry_proto", build_file = "@io_opentelemetry_cpp//bazel:opentelemetry_proto.BUILD", - sha256 = "985367f8905e91018e636cbf0d83ab3f834b665c4f5899a27d10cae9657710e2", - strip_prefix = "opentelemetry-proto-0.11.0", + sha256 = "f269fbcb30e17b03caa1decd231ce826e59d7651c0f71c3b28eb5140b4bb5412", + strip_prefix = "opentelemetry-proto-0.17.0", urls = [ - "https://github.com/open-telemetry/opentelemetry-proto/archive/v0.11.0.tar.gz", + "https://github.com/open-telemetry/opentelemetry-proto/archive/v0.17.0.tar.gz", ], ) @@ -164,5 +164,5 @@ cc_library( visibility = ["//visibility:public"], ) """, - path = "vcpkg/installed/x64-windows/", + path = "tools/vcpkg/installed/x64-windows/", ) diff --git a/ci/do_ci.ps1 b/ci/do_ci.ps1 index ca7f8abf83..b32c9ff54b 100644 --- a/ci/do_ci.ps1 +++ b/ci/do_ci.ps1 @@ -3,22 +3,22 @@ trap { $host.SetShouldExit(1) } $action = $args[0] -$SRC_DIR=(Get-Item -Path ".\").FullName +$SRC_DIR = (Get-Item -Path ".\").FullName -$BAZEL_OPTIONS="--copt=-DENABLE_METRICS_PREVIEW --copt=-DENABLE_LOGS_PREVIEW" -$BAZEL_TEST_OPTIONS="$BAZEL_OPTIONS --test_output=errors" +$BAZEL_OPTIONS = "--copt=-DENABLE_METRICS_PREVIEW --copt=-DENABLE_LOGS_PREVIEW" +$BAZEL_TEST_OPTIONS = "$BAZEL_OPTIONS --test_output=errors" if (!(test-path build)) { mkdir build } -$BUILD_DIR="$SRC_DIR\build" +$BUILD_DIR = Join-Path "$SRC_DIR" "build" if (!(test-path plugin)) { mkdir plugin } -$PLUGIN_DIR="$SRC_DIR\plugin" +$PLUGIN_DIR = Join-Path "$SRC_DIR" "plugin" -$VCPKG_DIR="$SRC_DIR\vcpkg" +$VCPKG_DIR = Join-Path "$SRC_DIR" "tools" "vcpkg" switch ($action) { "bazel.build" { @@ -31,8 +31,8 @@ switch ($action) { "cmake.test" { cd "$BUILD_DIR" cmake $SRC_DIR ` - -DVCPKG_TARGET_TRIPLET=x64-windows ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR\scripts\buildsystems\vcpkg.cmake" + -DVCPKG_TARGET_TRIPLET=x64-windows ` + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -51,9 +51,9 @@ switch ($action) { "cmake.exporter.otprotocol.test" { cd "$BUILD_DIR" cmake $SRC_DIR ` - -DVCPKG_TARGET_TRIPLET=x64-windows ` - -DWITH_OTPROTCOL=ON ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR\scripts\buildsystems\vcpkg.cmake" + -DVCPKG_TARGET_TRIPLET=x64-windows ` + -DWITH_OTPROTCOL=ON ` + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -72,8 +72,8 @@ switch ($action) { "cmake.build_example_plugin" { cd "$BUILD_DIR" cmake $SRC_DIR ` - -DVCPKG_TARGET_TRIPLET=x64-windows ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR\scripts\buildsystems\vcpkg.cmake" + -DVCPKG_TARGET_TRIPLET=x64-windows ` + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -83,13 +83,13 @@ switch ($action) { if ($exit -ne 0) { exit $exit } - cp examples\plugin\plugin\Debug\example_plugin.dll ${PLUGIN_DIR} + cp examples/plugin/plugin/Debug/example_plugin.dll ${PLUGIN_DIR} } "cmake.test_example_plugin" { cd "$BUILD_DIR" cmake $SRC_DIR ` - -DVCPKG_TARGET_TRIPLET=x64-windows ` - "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR\scripts\buildsystems\vcpkg.cmake" + -DVCPKG_TARGET_TRIPLET=x64-windows ` + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" $exit = $LASTEXITCODE if ($exit -ne 0) { exit $exit @@ -99,7 +99,7 @@ switch ($action) { if ($exit -ne 0) { exit $exit } - cp examples\plugin\plugin\Debug\example_plugin.dll ${PLUGIN_DIR} + cp examples/plugin/plugin/Debug/example_plugin.dll ${PLUGIN_DIR} $config = New-TemporaryFile examples/plugin/load/Debug/load_plugin_example.exe ${PLUGIN_DIR}/example_plugin.dll $config $exit = $LASTEXITCODE diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 14749500ec..e11ca0d2ec 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -281,7 +281,7 @@ elif [[ "$1" == "third_party.tags" ]]; then echo "gRPC=v1.43.2" > third_party_release echo "thrift=0.14.1" >> third_party_release echo "abseil=20210324.0" >> third_party_release - git submodule status | sed 's:.*/::' | sed 's/ (/=/g' | sed 's/)//g' >> third_party_release + git submodule foreach --quiet 'echo "$name=$(git describe --tags HEAD)"' | sed 's:.*/::' >> third_party_release exit 0 fi diff --git a/ci/install_windows_protobuf.ps1 b/ci/install_windows_protobuf.ps1 index 979a9e5f4f..4e1b1b8f05 100644 --- a/ci/install_windows_protobuf.ps1 +++ b/ci/install_windows_protobuf.ps1 @@ -1,6 +1,6 @@ $ErrorActionPreference = "Stop" trap { $host.SetShouldExit(1) } -cd vcpkg +cd tools/vcpkg # Lock to specific version of Protobuf port file to avoid build break -./vcpkg install --overlay-ports="$PSScriptRoot\ports" protobuf:x64-windows +./vcpkg "--vcpkg-root=$PWD" install --overlay-ports="$PSScriptRoot\ports" protobuf:x64-windows diff --git a/ci/setup_thrift.ps1 b/ci/setup_thrift.ps1 index 62b0d25c97..a9be25262d 100644 --- a/ci/setup_thrift.ps1 +++ b/ci/setup_thrift.ps1 @@ -1,14 +1,13 @@ $ErrorActionPreference = "Stop" trap { $host.SetShouldExit(1) } -# TODO: consider moving this to .gitmodules -git clone --depth=1 -b 2020.04 https://github.com/Microsoft/vcpkg.git -Push-Location -Path vcpkg -$VCPKG_DIR=(Get-Item -Path ".\").FullName -setx VCPKG_DIR (Get-Item -Path ".\").FullName +git submodule update -f "tools/vcpkg" +Push-Location -Path "tools/vcpkg" +$VCPKG_DIR = (Get-Item -Path ".\").FullName +setx VCPKG_DIR "$VCPKG_DIR" ./bootstrap-vcpkg.bat # boost needed for thrift -./vcpkg install boost-predef[core]:x64-windows boost-locale[core]:x64-windows boost-numeric-conversion[core]:x64-windows boost-scope-exit[core]:x64-windows openssl:x64-windows +./vcpkg "--vcpkg-root=$VCPKG_DIR" install boost-predef[core]:x64-windows boost-locale[core]:x64-windows boost-numeric-conversion[core]:x64-windows boost-scope-exit[core]:x64-windows openssl:x64-windows Pop-Location \ No newline at end of file diff --git a/ci/setup_windows_ci_environment.ps1 b/ci/setup_windows_ci_environment.ps1 index e7cdfeda97..4a0e04459d 100755 --- a/ci/setup_windows_ci_environment.ps1 +++ b/ci/setup_windows_ci_environment.ps1 @@ -1,20 +1,19 @@ $ErrorActionPreference = "Stop" trap { $host.SetShouldExit(1) } -# TODO: consider moving this to .gitmodules -git clone https://github.com/Microsoft/vcpkg.git -Push-Location -Path vcpkg -$VCPKG_DIR=(Get-Item -Path ".\").FullName +git submodule update -f "tools/vcpkg" +Push-Location -Path "tools/vcpkg" +$VCPKG_DIR = (Get-Item -Path ".\").FullName ./bootstrap-vcpkg.bat ./vcpkg integrate install # Patched Google Benchmark can be shared between vs2017 and vs2019 compilers -./vcpkg install --overlay-ports="$PSScriptRoot\ports" benchmark:x64-windows +./vcpkg "--vcpkg-root=$VCPKG_DIR" install --overlay-ports="$PSScriptRoot\ports" benchmark:x64-windows # Google Test -./vcpkg install gtest:x64-windows +./vcpkg "--vcpkg-root=$VCPKG_DIR" install gtest:x64-windows # nlohmann-json -./vcpkg install nlohmann-json:x64-windows +./vcpkg "--vcpkg-root=$VCPKG_DIR" install nlohmann-json:x64-windows Pop-Location diff --git a/cmake/opentelemetry-proto.cmake b/cmake/opentelemetry-proto.cmake index 8d8f868baf..37d45da6c4 100644 --- a/cmake/opentelemetry-proto.cmake +++ b/cmake/opentelemetry-proto.cmake @@ -3,7 +3,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/opentelemetry-proto/.git) set(needs_proto_download FALSE) else() if("${opentelemetry-proto}" STREQUAL "") - set(opentelemetry-proto "main") + set(opentelemetry-proto "v0.17.0") endif() include(ExternalProject) ExternalProject_Add( @@ -153,8 +153,9 @@ if(WITH_OTLP_GRPC) ${METRICS_SERVICE_GRPC_PB_H_FILE} ${METRICS_SERVICE_GRPC_PB_CPP_FILE} COMMAND - ${PROTOBUF_PROTOC_EXECUTABLE} ARGS "--proto_path=${PROTO_PATH}" - ${PROTOBUF_INCLUDE_FLAGS} "--cpp_out=${GENERATED_PROTOBUF_PATH}" + ${PROTOBUF_PROTOC_EXECUTABLE} ARGS "--experimental_allow_proto3_optional" + "--proto_path=${PROTO_PATH}" ${PROTOBUF_INCLUDE_FLAGS} + "--cpp_out=${GENERATED_PROTOBUF_PATH}" "--grpc_out=generate_mock_code=true:${GENERATED_PROTOBUF_PATH}" --plugin=protoc-gen-grpc="${gRPC_CPP_PLUGIN_EXECUTABLE}" ${COMMON_PROTO} ${RESOURCE_PROTO} ${TRACE_PROTO} ${LOGS_PROTO} ${METRICS_PROTO} @@ -178,11 +179,11 @@ else() ${METRICS_SERVICE_PB_H_FILE} ${METRICS_SERVICE_PB_CPP_FILE} COMMAND - ${PROTOBUF_PROTOC_EXECUTABLE} ARGS "--proto_path=${PROTO_PATH}" - ${PROTOBUF_INCLUDE_FLAGS} "--cpp_out=${GENERATED_PROTOBUF_PATH}" - ${COMMON_PROTO} ${RESOURCE_PROTO} ${TRACE_PROTO} ${LOGS_PROTO} - ${METRICS_PROTO} ${TRACE_SERVICE_PROTO} ${LOGS_SERVICE_PROTO} - ${METRICS_SERVICE_PROTO}) + ${PROTOBUF_PROTOC_EXECUTABLE} ARGS "--experimental_allow_proto3_optional" + "--proto_path=${PROTO_PATH}" ${PROTOBUF_INCLUDE_FLAGS} + "--cpp_out=${GENERATED_PROTOBUF_PATH}" ${COMMON_PROTO} ${RESOURCE_PROTO} + ${TRACE_PROTO} ${LOGS_PROTO} ${METRICS_PROTO} ${TRACE_SERVICE_PROTO} + ${LOGS_SERVICE_PROTO} ${METRICS_SERVICE_PROTO}) endif() include_directories("${GENERATED_PROTOBUF_PATH}") diff --git a/examples/common/logs_foo_library/foo_library.cc b/examples/common/logs_foo_library/foo_library.cc index 2ae5ccfaf6..daba9191bc 100644 --- a/examples/common/logs_foo_library/foo_library.cc +++ b/examples/common/logs_foo_library/foo_library.cc @@ -32,7 +32,7 @@ void foo_library() auto scoped_span = trace::Scope(get_tracer()->StartSpan("foo_library")); auto ctx = span->GetContext(); auto logger = get_logger(); - logger->Log(opentelemetry::logs::Severity::kDebug, "name", "body", {}, ctx.trace_id(), - ctx.span_id(), ctx.trace_flags(), opentelemetry::common::SystemTimestamp()); + logger->Log(opentelemetry::logs::Severity::kDebug, "body", {}, ctx.trace_id(), ctx.span_id(), + ctx.trace_flags(), opentelemetry::common::SystemTimestamp()); } #endif diff --git a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h index 5c223cd0d4..c38bf8769d 100755 --- a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h +++ b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h @@ -124,12 +124,6 @@ class ElasticSearchRecordable final : public sdk::logs::Recordable } } - /** - * Set name for this log - * @param name the name to set - */ - void SetName(nostd::string_view name) noexcept override { json_["name"] = name.data(); } - /** * Set body field for this log. * @param message the body to set @@ -214,6 +208,7 @@ class ElasticSearchRecordable final : public sdk::logs::Recordable const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary &instrumentation_library) noexcept { + json_["name"] = instrumentation_library.GetName(); instrumentation_library_ = &instrumentation_library; } diff --git a/exporters/elasticsearch/test/es_log_exporter_test.cc b/exporters/elasticsearch/test/es_log_exporter_test.cc index d32048e83d..943f9fa7ba 100644 --- a/exporters/elasticsearch/test/es_log_exporter_test.cc +++ b/exporters/elasticsearch/test/es_log_exporter_test.cc @@ -69,7 +69,6 @@ TEST(ElasticsearchLogsExporterTests, RecordableCreation) // Create a recordable auto record = exporter->MakeRecordable(); - record->SetName("Timeout Log"); record->SetSeverity(logs_api::Severity::kFatal); record->SetTimestamp(std::chrono::system_clock::now()); record->SetBody("Body of the log message"); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h index 84f6b6970f..bd2478224f 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h @@ -100,6 +100,30 @@ class Logger : public opentelemetry::logs::Logger provHandle(initProvHandle()) {} + void Log(opentelemetry::logs::Severity severity, + nostd::string_view body, + const common::KeyValueIterable &attributes, + opentelemetry::trace::TraceId trace_id, + opentelemetry::trace::SpanId span_id, + opentelemetry::trace::TraceFlags trace_flags, + common::SystemTimestamp timestamp) noexcept override + { + +# ifdef OPENTELEMETRY_RTTI_ENABLED + common::KeyValueIterable &attribs = const_cast(attributes); + Properties *evt = dynamic_cast(&attribs); + // Properties *res = dynamic_cast(&resr); + + if (evt != nullptr) + { + // Pass as a reference to original modifyable collection without creating a copy + return Log(severity, provId, body, *evt, trace_id, span_id, trace_flags, timestamp); + } +# endif + Properties evtCopy = attributes; + return Log(severity, provId, body, evtCopy, trace_id, span_id, trace_flags, timestamp); + } + void Log(opentelemetry::logs::Severity severity, nostd::string_view name, nostd::string_view body, @@ -163,7 +187,7 @@ class Logger : public opentelemetry::logs::Logger ActivityIdPtr = &ActivityId; } } - evt[ETW_FIELD_PAYLOAD_NAME] = std::string(name.data(), name.length()); + evt[ETW_FIELD_PAYLOAD_NAME] = std::string(name.data(), name.size()); std::chrono::system_clock::time_point ts = timestamp; int64_t tsMs = std::chrono::duration_cast(ts.time_since_epoch()).count(); diff --git a/exporters/etw/test/etw_logger_test.cc b/exporters/etw/test/etw_logger_test.cc index e4cf53ee34..99d5b3a9b8 100644 --- a/exporters/etw/test/etw_logger_test.cc +++ b/exporters/etw/test/etw_logger_test.cc @@ -51,8 +51,7 @@ TEST(ETWLogger, LoggerCheckWithBody) const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; auto logger = lp.GetLogger(providerName, "", schema_url); Properties attribs = {{"attrib1", 1}, {"attrib2", 2}}; - EXPECT_NO_THROW( - logger->Log(opentelemetry::logs::Severity::kDebug, "My Log", "This is test log body")); + EXPECT_NO_THROW(logger->Log(opentelemetry::logs::Severity::kDebug, "This is test log body")); } /** @@ -95,7 +94,7 @@ TEST(ETWLogger, LoggerCheckWithAttributes) auto logger = lp.GetLogger(providerName, "", schema_url); // Log attributes Properties attribs = {{"attrib1", 1}, {"attrib2", 2}}; - EXPECT_NO_THROW(logger->Log(opentelemetry::logs::Severity::kDebug, "My Log", attribs)); + EXPECT_NO_THROW(logger->Log(opentelemetry::logs::Severity::kDebug, attribs)); } # endif // _WIN32 diff --git a/exporters/ostream/src/log_exporter.cc b/exporters/ostream/src/log_exporter.cc index ef103bb6b2..ba6997aa7e 100644 --- a/exporters/ostream/src/log_exporter.cc +++ b/exporters/ostream/src/log_exporter.cc @@ -159,8 +159,7 @@ sdk::common::ExportResult OStreamLogExporter::Export( sout_ << opentelemetry::logs::SeverityNumToText[severity_index] << "\n"; } - sout_ << " name : " << log_record->GetName() << "\n" - << " body : " << log_record->GetBody() << "\n" + sout_ << " body : " << log_record->GetBody() << "\n" << " resource : "; printMap(log_record->GetResource().GetAttributes(), sout_); diff --git a/exporters/ostream/test/ostream_log_test.cc b/exporters/ostream/test/ostream_log_test.cc index e5eaa7ef67..7fa51c18a9 100644 --- a/exporters/ostream/test/ostream_log_test.cc +++ b/exporters/ostream/test/ostream_log_test.cc @@ -79,7 +79,6 @@ TEST(OstreamLogExporter, DefaultLogRecordToCout) " timestamp : 0\n" " severity_num : 0\n" " severity_text : INVALID\n" - " name : \n" " body : \n", " resource : {", "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", @@ -117,7 +116,6 @@ TEST(OStreamLogExporter, SimpleLogToCout) auto record = std::unique_ptr(new sdklogs::LogRecord()); record->SetTimestamp(now); record->SetSeverity(logs_api::Severity::kTrace); // kTrace has enum value of 1 - record->SetName("Name"); record->SetBody("Message"); // Log a record to cout @@ -133,7 +131,6 @@ TEST(OStreamLogExporter, SimpleLogToCout) "\n" " severity_num : 1\n" " severity_text : TRACE\n" - " name : Name\n" " body : Message\n", " resource : {", "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", @@ -187,7 +184,6 @@ TEST(OStreamLogExporter, LogWithStringAttributesToCerr) " timestamp : 0\n" " severity_num : 0\n" " severity_text : INVALID\n" - " name : \n" " body : \n", " resource : {", "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", @@ -249,7 +245,6 @@ TEST(OStreamLogExporter, LogWithVariantTypesToClog) " timestamp : 0\n" " severity_num : 0\n" " severity_text : INVALID\n" - " name : \n" " body : \n", " resource : {", "{service.name: unknown_service}", @@ -283,7 +278,7 @@ TEST(OStreamLogExporter, IntegrationTest) auto apiProvider = nostd::shared_ptr(sdkProvider); auto provider = nostd::shared_ptr(apiProvider); logs_api::Provider::SetLoggerProvider(provider); - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = logs_api::Provider::GetLoggerProvider()->GetLogger( "Logger", "", "opentelelemtry_library", "", schema_url); @@ -296,7 +291,7 @@ TEST(OStreamLogExporter, IntegrationTest) // Write a log to ostream exporter common::SystemTimestamp now(std::chrono::system_clock::now()); - logger->Log(logs_api::Severity::kDebug, "", "Hello", {}, {}, {}, {}, now); + logger->Log(logs_api::Severity::kDebug, "Hello", {}, {}, {}, {}, now); // Restore cout's original streambuf std::cout.rdbuf(original); @@ -309,7 +304,6 @@ TEST(OStreamLogExporter, IntegrationTest) "\n" " severity_num : 5\n" " severity_text : DEBUG\n" - " name : \n" " body : Hello\n", " resource : {", "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h index b6d02bddcd..57ae94ea03 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h @@ -49,12 +49,6 @@ class OtlpLogRecordable final : public opentelemetry::sdk::logs::Recordable */ void SetSeverity(opentelemetry::logs::Severity severity) noexcept override; - /** - * Set name for this log - * @param name the name to set - */ - void SetName(nostd::string_view name) noexcept override; - /** * Set body field for this log. * @param message the body to set @@ -67,6 +61,9 @@ class OtlpLogRecordable final : public opentelemetry::sdk::logs::Recordable */ void SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept override; + /** Returns the associated resource */ + const opentelemetry::sdk::resource::Resource &GetResource() const noexcept; + /** * Set an attribute of a log. * @param key the name of the attribute diff --git a/exporters/otlp/src/otlp_log_recordable.cc b/exporters/otlp/src/otlp_log_recordable.cc index e859981e9f..d38fe241fa 100644 --- a/exporters/otlp/src/otlp_log_recordable.cc +++ b/exporters/otlp/src/otlp_log_recordable.cc @@ -3,6 +3,8 @@ #ifdef ENABLE_LOGS_PREVIEW +# include "opentelemetry/common/macros.h" + # include "opentelemetry/exporters/otlp/otlp_log_recordable.h" # include "opentelemetry/exporters/otlp/otlp_recordable_utils.h" @@ -167,11 +169,6 @@ void OtlpLogRecordable::SetSeverity(opentelemetry::logs::Severity severity) noex } } -void OtlpLogRecordable::SetName(nostd::string_view name) noexcept -{ - log_record_.set_name(name.data(), name.size()); -} - void OtlpLogRecordable::SetBody(nostd::string_view message) noexcept { log_record_.mutable_body()->set_string_value(message.data(), message.size()); @@ -182,6 +179,13 @@ void OtlpLogRecordable::SetResource(const opentelemetry::sdk::resource::Resource resource_ = &resource; } +const opentelemetry::sdk::resource::Resource &OtlpLogRecordable::GetResource() const noexcept +{ + OPENTELEMETRY_LIKELY_IF(nullptr != resource_) { return *resource_; } + + return opentelemetry::sdk::resource::Resource::GetDefault(); +} + void OtlpLogRecordable::SetAttribute(nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept { @@ -215,7 +219,14 @@ void OtlpLogRecordable::SetInstrumentationLibrary( const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary & OtlpLogRecordable::GetInstrumentationLibrary() const noexcept { - return *instrumentation_library_; + OPENTELEMETRY_LIKELY_IF(nullptr != instrumentation_library_) { return *instrumentation_library_; } + + static opentelemetry::nostd::unique_ptr< + opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary> + default_instrumentation = + opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary::Create( + "default", "1.0.0", "https://opentelemetry.io/schemas/1.11.0"); + return *default_instrumentation; } } // namespace otlp } // namespace exporter diff --git a/exporters/otlp/src/otlp_recordable_utils.cc b/exporters/otlp/src/otlp_recordable_utils.cc index b981448de1..bb3c846042 100644 --- a/exporters/otlp/src/otlp_recordable_utils.cc +++ b/exporters/otlp/src/otlp_recordable_utils.cc @@ -13,6 +13,9 @@ #include "opentelemetry/exporters/otlp/otlp_log_recordable.h" #include "opentelemetry/exporters/otlp/otlp_recordable.h" +#include +#include + namespace nostd = opentelemetry::nostd; OPENTELEMETRY_BEGIN_NAMESPACE @@ -21,6 +24,29 @@ namespace exporter namespace otlp { +namespace +{ +struct InstrumentationLibraryPointerHasher +{ + std::size_t operator()(const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary + *instrumentation) const noexcept + { + return instrumentation->HashCode(); + } +}; + +struct InstrumentationLibraryPointerEqual +{ + std::size_t operator()( + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary *left, + const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary *right) + const noexcept + { + return *left == *right; + } +}; +} // namespace + // // See `attribute_value.h` for details. // @@ -285,26 +311,48 @@ void OtlpRecordableUtils::PopulateRequest( return; } + using logs_index_by_instrumentation_type = + std::unordered_map>, + InstrumentationLibraryPointerHasher, InstrumentationLibraryPointerEqual>; + std::unordered_map + logs_index_by_resource; + for (auto &recordable : logs) { - auto resource_logs = request->add_resource_logs(); - auto instrumentation_lib = resource_logs->add_instrumentation_library_logs(); - auto rec = std::unique_ptr(static_cast(recordable.release())); + auto instrumentation = &rec->GetInstrumentationLibrary(); + auto resource = &rec->GetResource(); + + logs_index_by_resource[resource][instrumentation].emplace_back(std::move(rec)); + } - // TODO schema url - *resource_logs->mutable_resource() = rec->ProtoResource(); + for (auto &input_resource_log : logs_index_by_resource) + { + auto output_resource_log = request->add_resource_logs(); + for (auto &input_scope_log : input_resource_log.second) + { + auto output_scope_log = output_resource_log->add_scope_logs(); + for (auto &input_log_record : input_scope_log.second) + { + if (!output_resource_log->has_resource()) + { + *output_resource_log->mutable_resource() = input_log_record->ProtoResource(); + output_resource_log->set_schema_url(input_resource_log.first->GetSchemaURL()); + } - // TODO schema url - // resource_logs->set_schema_url(rec->GetResourceSchemaURL()); + if (!output_scope_log->has_scope()) + { + output_scope_log->mutable_scope()->set_name(input_scope_log.first->GetName()); + output_scope_log->mutable_scope()->set_version(input_scope_log.first->GetVersion()); + output_scope_log->set_schema_url(input_scope_log.first->GetSchemaURL()); + } - *instrumentation_lib->add_logs() = std::move(rec->log_record()); - // TODO instrumentation_library - // *instrumentation_lib->mutable_instrumentation_library() = - // rec->GetProtoInstrumentationLibrary(); - // TODO schema data - // instrumentation_lib->set_schema_url(rec->GetInstrumentationLibrarySchemaURL()); + *output_scope_log->add_log_records() = std::move(input_log_record->log_record()); + } + } } } #endif diff --git a/exporters/otlp/test/otlp_grpc_log_exporter_test.cc b/exporters/otlp/test/otlp_grpc_log_exporter_test.cc index f5f621bf9f..b60aac61a4 100644 --- a/exporters/otlp/test/otlp_grpc_log_exporter_test.cc +++ b/exporters/otlp/test/otlp_grpc_log_exporter_test.cc @@ -58,9 +58,7 @@ TEST_F(OtlpGrpcLogExporterTestPeer, ShutdownTest) auto exporter = GetExporter(stub_interface); auto recordable_1 = exporter->MakeRecordable(); - recordable_1->SetName("Test log 1"); auto recordable_2 = exporter->MakeRecordable(); - recordable_2->SetName("Test log 2"); // exporter shuold not be shutdown by default nostd::span> batch_1(&recordable_1, 1); @@ -87,9 +85,7 @@ TEST_F(OtlpGrpcLogExporterTestPeer, ExportUnitTest) auto exporter = GetExporter(stub_interface); auto recordable_1 = exporter->MakeRecordable(); - recordable_1->SetName("Test logs 1"); auto recordable_2 = exporter->MakeRecordable(); - recordable_2->SetName("Test logs 2"); // Test successful RPC nostd::span> batch_1(&recordable_1, 1); @@ -137,9 +133,9 @@ TEST_F(OtlpGrpcLogExporterTestPeer, ExportIntegrationTest) '3', '2', '1', '0'}; opentelemetry::trace::SpanId span_id{span_id_bin}; - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = provider->GetLogger("test", "", "opentelelemtry_library", "", schema_url); - logger->Log(opentelemetry::logs::Severity::kInfo, "Log name", "Log message", + logger->Log(opentelemetry::logs::Severity::kInfo, "Log message", {{"service.name", "unit_test_service"}, {"tenant.id", "test_user"}, {"bool_value", true}, diff --git a/exporters/otlp/test/otlp_http_log_exporter_test.cc b/exporters/otlp/test/otlp_http_log_exporter_test.cc index ffd1a9a0f3..7e2c0808e2 100644 --- a/exporters/otlp/test/otlp_http_log_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_log_exporter_test.cc @@ -118,7 +118,7 @@ TEST_F(OtlpHttpLogExporterTestPeer, ExportJsonIntegrationTest) const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; auto logger = provider->GetLogger("test", "", "opentelelemtry_library", "", schema_url); - logger->Log(opentelemetry::logs::Severity::kInfo, "Log name", "Log message", + logger->Log(opentelemetry::logs::Severity::kInfo, "Log message", {{"service.name", "unit_test_service"}, {"tenant.id", "test_user"}, {"bool_value", true}, @@ -151,14 +151,13 @@ TEST_F(OtlpHttpLogExporterTestPeer, ExportJsonIntegrationTest) .WillOnce([&mock_session, report_trace_id, report_span_id](opentelemetry::ext::http::client::EventHandler &callback) { auto check_json = nlohmann::json::parse(mock_session->GetRequest()->body_, nullptr, false); - auto resource_logs = *check_json["resource_logs"].begin(); - auto instrumentation_library_span = *resource_logs["instrumentation_library_logs"].begin(); - auto log = *instrumentation_library_span["logs"].begin(); - auto received_trace_id = log["trace_id"].get(); - auto received_span_id = log["span_id"].get(); + auto resource_logs = *check_json["resource_logs"].begin(); + auto scope_logs = *resource_logs["scope_logs"].begin(); + auto log = *scope_logs["log_records"].begin(); + auto received_trace_id = log["trace_id"].get(); + auto received_span_id = log["span_id"].get(); EXPECT_EQ(received_trace_id, report_trace_id); EXPECT_EQ(received_span_id, report_span_id); - EXPECT_EQ("Log name", log["name"].get()); EXPECT_EQ("Log message", log["body"]["string_value"].get()); EXPECT_LE(15, log["attributes"].size()); auto custom_header = mock_session->GetRequest()->headers_.find("Custom-Header-Key"); @@ -205,7 +204,7 @@ TEST_F(OtlpHttpLogExporterTestPeer, ExportBinaryIntegrationTest) const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; auto logger = provider->GetLogger("test", "", "opentelelemtry_library", "", schema_url); - logger->Log(opentelemetry::logs::Severity::kInfo, "Log name", "Log message", + logger->Log(opentelemetry::logs::Severity::kInfo, "Log message", {{"service.name", "unit_test_service"}, {"tenant.id", "test_user"}, {"bool_value", true}, @@ -237,10 +236,9 @@ TEST_F(OtlpHttpLogExporterTestPeer, ExportBinaryIntegrationTest) opentelemetry::proto::collector::logs::v1::ExportLogsServiceRequest request_body; request_body.ParseFromArray(&mock_session->GetRequest()->body_[0], static_cast(mock_session->GetRequest()->body_.size())); - auto received_log = request_body.resource_logs(0).instrumentation_library_logs(0).logs(0); + auto &received_log = request_body.resource_logs(0).scope_logs(0).log_records(0); EXPECT_EQ(received_log.trace_id(), report_trace_id); EXPECT_EQ(received_log.span_id(), report_span_id); - EXPECT_EQ("Log name", received_log.name()); EXPECT_EQ("Log message", received_log.body().string_value()); EXPECT_LE(15, received_log.attributes_size()); bool check_service_name = false; diff --git a/exporters/otlp/test/otlp_log_recordable_test.cc b/exporters/otlp/test/otlp_log_recordable_test.cc index a4945d394b..bb48fd54e9 100644 --- a/exporters/otlp/test/otlp_log_recordable_test.cc +++ b/exporters/otlp/test/otlp_log_recordable_test.cc @@ -17,14 +17,6 @@ namespace otlp namespace resource = opentelemetry::sdk::resource; namespace proto = opentelemetry::proto; -TEST(OtlpLogRecordable, SetName) -{ - OtlpLogRecordable rec; - nostd::string_view name = "Test Log Name"; - rec.SetName(name); - EXPECT_EQ(rec.log_record().name(), name); -} - TEST(OtlpLogRecordable, SetTimestamp) { OtlpLogRecordable rec; diff --git a/exporters/otlp/test/otlp_recordable_test.cc b/exporters/otlp/test/otlp_recordable_test.cc index 1c5b8a6895..b46802d875 100644 --- a/exporters/otlp/test/otlp_recordable_test.cc +++ b/exporters/otlp/test/otlp_recordable_test.cc @@ -49,13 +49,6 @@ TEST(OtlpRecordable, SetIdentity) EXPECT_EQ(rec_invalid_parent.span().parent_span_id(), std::string{}); } -TEST(OtlpRecordable, SetName) -{ - OtlpRecordable rec; - nostd::string_view name = "Test Span"; - rec.SetName(name); - EXPECT_EQ(rec.span().name(), name); -} TEST(OtlpRecordable, SetSpanKind) { OtlpRecordable rec; @@ -77,7 +70,7 @@ TEST(OtlpRecordable, SetInstrumentationLibrary) TEST(OtlpRecordable, SetInstrumentationLibraryWithSchemaURL) { OtlpRecordable rec; - const std::string expected_schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string expected_schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto inst_lib = trace_sdk::InstrumentationLibrary::Create("test", "v1", expected_schema_url); rec.SetInstrumentationLibrary(*inst_lib); EXPECT_EQ(expected_schema_url, rec.GetInstrumentationLibrarySchemaURL()); @@ -220,7 +213,7 @@ TEST(OtlpRecordable, SetResourceWithSchemaURL) OtlpRecordable rec; const std::string service_name_key = "service.name"; const std::string service_name = "test-otlp"; - const std::string expected_schema_url = "https://opentelemetry.io/schemas/1.2.0"; + const std::string expected_schema_url = "https://opentelemetry.io/schemas/1.11.0"; auto resource = resource::Resource::Create({{service_name_key, service_name}}, expected_schema_url); rec.SetResource(resource); diff --git a/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h b/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h index b288aa5b71..20f82a5d18 100644 --- a/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h +++ b/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h @@ -3,11 +3,13 @@ #pragma once -#include #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/version.h" +#include +#include + OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -35,6 +37,8 @@ class InstrumentationLibrary new InstrumentationLibrary{name, version, schema_url}); } + std::size_t HashCode() const noexcept { return hash_code_; } + /** * Compare 2 instrumentation libraries. * @param other the instrumentation library to compare to. @@ -70,12 +74,20 @@ class InstrumentationLibrary nostd::string_view version, nostd::string_view schema_url = "") : name_(name), version_(version), schema_url_(schema_url) - {} + { + std::string hash_data; + hash_data.reserve(name_.size() + version_.size() + schema_url_.size()); + hash_data += name_; + hash_data += version_; + hash_data += schema_url_; + hash_code_ = std::hash{}(hash_data); + } private: std::string name_; std::string version_; std::string schema_url_; + std::size_t hash_code_; }; } // namespace instrumentationlibrary diff --git a/sdk/include/opentelemetry/sdk/logs/log_record.h b/sdk/include/opentelemetry/sdk/logs/log_record.h index 502a87a6f0..2a3a782893 100644 --- a/sdk/include/opentelemetry/sdk/logs/log_record.h +++ b/sdk/include/opentelemetry/sdk/logs/log_record.h @@ -31,7 +31,6 @@ class LogRecord final : public Recordable opentelemetry::logs::Severity severity_ = opentelemetry::logs::Severity::kInvalid; const opentelemetry::sdk::resource::Resource *resource_ = nullptr; common::AttributeMap attributes_map_; - std::string name_; std::string body_; // Currently a simple string, but should be changed to "Any" type opentelemetry::trace::TraceId trace_id_; opentelemetry::trace::SpanId span_id_; @@ -50,12 +49,6 @@ class LogRecord final : public Recordable severity_ = severity; } - /** - * Set name for this log - * @param name the name to set - */ - void SetName(nostd::string_view name) noexcept override { name_ = std::string(name); } - /** * Set body field for this log. * @param message the body to set @@ -127,12 +120,6 @@ class LogRecord final : public Recordable */ opentelemetry::logs::Severity GetSeverity() const noexcept { return severity_; } - /** - * Get the name of this log - * @return the name of this log - */ - std::string GetName() const noexcept { return name_; } - /** * Get the body of this log * @return the body of this log diff --git a/sdk/include/opentelemetry/sdk/logs/logger.h b/sdk/include/opentelemetry/sdk/logs/logger.h index 604eb0d8f9..4eeca2da11 100644 --- a/sdk/include/opentelemetry/sdk/logs/logger.h +++ b/sdk/include/opentelemetry/sdk/logs/logger.h @@ -40,7 +40,6 @@ class Logger final : public opentelemetry::logs::Logger /** * Writes a log record into the processor. * @param severity the severity level of the log event. - * @param name the name of the log event. * @param message the string message of the log (perhaps support std::fmt or fmt-lib format). * with the log event. * @param attributes the attributes, stored as a 2D list of key/value pairs, that are associated @@ -51,7 +50,6 @@ class Logger final : public opentelemetry::logs::Logger * @param timestamp the timestamp the log record was created. * @throws No exceptions under any circumstances. */ void Log(opentelemetry::logs::Severity severity, - nostd::string_view name, nostd::string_view body, const opentelemetry::common::KeyValueIterable &attributes, opentelemetry::trace::TraceId trace_id, diff --git a/sdk/include/opentelemetry/sdk/logs/multi_recordable.h b/sdk/include/opentelemetry/sdk/logs/multi_recordable.h index 59c018d2d6..db3df96227 100644 --- a/sdk/include/opentelemetry/sdk/logs/multi_recordable.h +++ b/sdk/include/opentelemetry/sdk/logs/multi_recordable.h @@ -41,12 +41,6 @@ class MultiRecordable final : public Recordable */ void SetSeverity(opentelemetry::logs::Severity severity) noexcept override; - /** - * Set name for this log - * @param name the name to set - */ - void SetName(nostd::string_view name) noexcept override; - /** * Set body field for this log. * @param message the body to set diff --git a/sdk/include/opentelemetry/sdk/logs/recordable.h b/sdk/include/opentelemetry/sdk/logs/recordable.h index a858e67d62..4a32273732 100644 --- a/sdk/include/opentelemetry/sdk/logs/recordable.h +++ b/sdk/include/opentelemetry/sdk/logs/recordable.h @@ -45,12 +45,6 @@ class Recordable */ virtual void SetSeverity(opentelemetry::logs::Severity severity) noexcept = 0; - /** - * Set name for this log - * @param name the name to set - */ - virtual void SetName(nostd::string_view name) noexcept = 0; - /** * Set body field for this log. * @param message the body to set diff --git a/sdk/src/logs/logger.cc b/sdk/src/logs/logger.cc index fc690c6773..b8fdb15c38 100644 --- a/sdk/src/logs/logger.cc +++ b/sdk/src/logs/logger.cc @@ -36,7 +36,6 @@ const nostd::string_view Logger::GetName() noexcept * if the user does not specify them. */ void Logger::Log(opentelemetry::logs::Severity severity, - nostd::string_view name, nostd::string_view body, const common::KeyValueIterable &attributes, trace_api::TraceId trace_id, @@ -63,7 +62,6 @@ void Logger::Log(opentelemetry::logs::Severity severity, // Populate recordable fields recordable->SetTimestamp(timestamp); recordable->SetSeverity(severity); - recordable->SetName(name); recordable->SetBody(body); recordable->SetInstrumentationLibrary(GetInstrumentationLibrary()); diff --git a/sdk/src/logs/logger_provider.cc b/sdk/src/logs/logger_provider.cc index 3115b7fac8..089b8d0de0 100644 --- a/sdk/src/logs/logger_provider.cc +++ b/sdk/src/logs/logger_provider.cc @@ -88,9 +88,19 @@ nostd::shared_ptr LoggerProvider::GetLogger( } */ - // If no logger with that name exists yet, create it and add it to the map of loggers - auto lib = instrumentationlibrary::InstrumentationLibrary::Create(library_name, library_version, - schema_url); + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-instrumentationscope + opentelemetry::nostd::unique_ptr lib; + if (library_name.empty()) + { + lib = instrumentationlibrary::InstrumentationLibrary::Create(logger_name, library_version, + schema_url); + } + else + { + lib = instrumentationlibrary::InstrumentationLibrary::Create(library_name, library_version, + schema_url); + } + loggers_.push_back(std::shared_ptr( new Logger(logger_name, context_, std::move(lib)))); return nostd::shared_ptr{loggers_.back()}; diff --git a/sdk/src/logs/multi_recordable.cc b/sdk/src/logs/multi_recordable.cc index b7bb92c627..4d615ec738 100644 --- a/sdk/src/logs/multi_recordable.cc +++ b/sdk/src/logs/multi_recordable.cc @@ -72,14 +72,6 @@ void MultiRecordable::SetSeverity(opentelemetry::logs::Severity severity) noexce } } -void MultiRecordable::SetName(nostd::string_view name) noexcept -{ - for (auto &recordable : recordables_) - { - recordable.second->SetName(name); - } -} - void MultiRecordable::SetBody(nostd::string_view message) noexcept { for (auto &recordable : recordables_) diff --git a/sdk/test/logs/batch_log_processor_test.cc b/sdk/test/logs/batch_log_processor_test.cc index df503cb2aa..63e44676c8 100644 --- a/sdk/test/logs/batch_log_processor_test.cc +++ b/sdk/test/logs/batch_log_processor_test.cc @@ -110,7 +110,7 @@ TEST_F(BatchLogProcessorTest, TestShutdown) for (int i = 0; i < num_logs; ++i) { auto log = batch_processor->MakeRecordable(); - log->SetName("Log" + std::to_string(i)); + log->SetBody("Log" + std::to_string(i)); batch_processor->OnReceive(std::move(log)); } @@ -126,7 +126,7 @@ TEST_F(BatchLogProcessorTest, TestShutdown) // Assume logs are received by exporter in same order as sent by processor for (int i = 0; i < num_logs; ++i) { - EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetName()); + EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetBody()); } // Also check that the processor is shut down at the end @@ -145,7 +145,7 @@ TEST_F(BatchLogProcessorTest, TestForceFlush) for (int i = 0; i < num_logs; ++i) { auto log = batch_processor->MakeRecordable(); - log->SetName("Log" + std::to_string(i)); + log->SetBody("Log" + std::to_string(i)); batch_processor->OnReceive(std::move(log)); } @@ -154,14 +154,14 @@ TEST_F(BatchLogProcessorTest, TestForceFlush) EXPECT_EQ(num_logs, logs_received->size()); for (int i = 0; i < num_logs; ++i) { - EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetName()); + EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetBody()); } // Create some more logs to make sure that the processor still works for (int i = 0; i < num_logs; ++i) { auto log = batch_processor->MakeRecordable(); - log->SetName("Log" + std::to_string(i)); + log->SetBody("Log" + std::to_string(i)); batch_processor->OnReceive(std::move(log)); } @@ -170,7 +170,7 @@ TEST_F(BatchLogProcessorTest, TestForceFlush) EXPECT_EQ(num_logs * 2, logs_received->size()); for (int i = 0; i < num_logs * 2; ++i) { - EXPECT_EQ("Log" + std::to_string(i % num_logs), logs_received->at(i)->GetName()); + EXPECT_EQ("Log" + std::to_string(i % num_logs), logs_received->at(i)->GetBody()); } } @@ -190,7 +190,7 @@ TEST_F(BatchLogProcessorTest, TestManyLogsLoss) for (int i = 0; i < max_queue_size; ++i) { auto log = batch_processor->MakeRecordable(); - log->SetName("Log" + std::to_string(i)); + log->SetBody("Log" + std::to_string(i)); batch_processor->OnReceive(std::move(log)); } @@ -214,7 +214,7 @@ TEST_F(BatchLogProcessorTest, TestManyLogsLossLess) for (int i = 0; i < num_logs; ++i) { auto log = batch_processor->MakeRecordable(); - log->SetName("Log" + std::to_string(i)); + log->SetBody("Log" + std::to_string(i)); batch_processor->OnReceive(std::move(log)); } @@ -223,7 +223,7 @@ TEST_F(BatchLogProcessorTest, TestManyLogsLossLess) EXPECT_EQ(num_logs, logs_received->size()); for (int i = 0; i < num_logs; ++i) { - EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetName()); + EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetBody()); } } @@ -247,7 +247,7 @@ TEST_F(BatchLogProcessorTest, TestScheduledDelayMillis) for (std::size_t i = 0; i < max_export_batch_size; ++i) { auto log = batch_processor->MakeRecordable(); - log->SetName("Log" + std::to_string(i)); + log->SetBody("Log" + std::to_string(i)); batch_processor->OnReceive(std::move(log)); } // Sleep for scheduled_delay_millis milliseconds @@ -263,7 +263,7 @@ TEST_F(BatchLogProcessorTest, TestScheduledDelayMillis) EXPECT_EQ(max_export_batch_size, logs_received->size()); for (size_t i = 0; i < max_export_batch_size; ++i) { - EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetName()); + EXPECT_EQ("Log" + std::to_string(i), logs_received->at(i)->GetBody()); } } #endif diff --git a/sdk/test/logs/log_record_test.cc b/sdk/test/logs/log_record_test.cc index dda80cc1ee..89b07473a3 100644 --- a/sdk/test/logs/log_record_test.cc +++ b/sdk/test/logs/log_record_test.cc @@ -24,7 +24,6 @@ TEST(LogRecord, GetDefaultValues) LogRecord record; ASSERT_EQ(record.GetSeverity(), logs_api::Severity::kInvalid); - ASSERT_EQ(record.GetName(), ""); ASSERT_EQ(record.GetBody(), ""); ASSERT_NE(record.GetResource().GetAttributes().size(), 0); ASSERT_EQ(record.GetAttributes().size(), 0); @@ -46,7 +45,6 @@ TEST(LogRecord, SetAndGet) LogRecord record; auto resource = opentelemetry::sdk::resource::Resource::Create({{"res1", true}}); record.SetSeverity(logs_api::Severity::kInvalid); - record.SetName("Log name"); record.SetBody("Message"); record.SetResource(resource); record.SetAttribute("attr1", (int64_t)314159); @@ -57,7 +55,6 @@ TEST(LogRecord, SetAndGet) // Test that all fields match what was set ASSERT_EQ(record.GetSeverity(), logs_api::Severity::kInvalid); - ASSERT_EQ(record.GetName(), "Log name"); ASSERT_EQ(record.GetBody(), "Message"); ASSERT_TRUE(nostd::get(record.GetResource().GetAttributes().at("res1"))); ASSERT_EQ(nostd::get(record.GetAttributes().at("attr1")), 314159); diff --git a/sdk/test/logs/logger_provider_sdk_test.cc b/sdk/test/logs/logger_provider_sdk_test.cc index 5948a9dfd2..3e5e8dfb26 100644 --- a/sdk/test/logs/logger_provider_sdk_test.cc +++ b/sdk/test/logs/logger_provider_sdk_test.cc @@ -32,9 +32,9 @@ TEST(LoggerProviderSDK, LoggerProviderGetLoggerSimple) { auto lp = std::shared_ptr(new LoggerProvider()); - nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger1 = lp->GetLogger("logger1", "", "opentelelemtry_library", "", schema_url); - auto logger2 = lp->GetLogger("logger2", "", "opentelelemtry_library", "", schema_url); + auto logger2 = lp->GetLogger("logger2", "", "", "", schema_url); // Check that the logger is not nullptr ASSERT_NE(logger1, nullptr); @@ -46,7 +46,7 @@ TEST(LoggerProviderSDK, LoggerProviderGetLoggerSimple) ASSERT_EQ(sdk_logger1->GetInstrumentationLibrary().GetVersion(), ""); ASSERT_EQ(sdk_logger1->GetInstrumentationLibrary().GetSchemaURL(), schema_url); - ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetName(), "opentelelemtry_library"); + ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetName(), "logger2"); ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetVersion(), ""); ASSERT_EQ(sdk_logger2->GetInstrumentationLibrary().GetSchemaURL(), schema_url); @@ -67,7 +67,7 @@ TEST(LoggerProviderSDK, LoggerProviderLoggerArguments) // detail to this test auto lp = std::shared_ptr(new LoggerProvider()); - nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + nostd::string_view schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger1 = lp->GetLogger("logger1", "", "opentelelemtry_library", "", schema_url); // Check GetLogger(logger_name, args) diff --git a/sdk/test/logs/logger_sdk_test.cc b/sdk/test/logs/logger_sdk_test.cc index aad13f41e2..3747731f1f 100644 --- a/sdk/test/logs/logger_sdk_test.cc +++ b/sdk/test/logs/logger_sdk_test.cc @@ -18,7 +18,7 @@ TEST(LoggerSDK, LogToNullProcessor) // since it calls Processor::OnReceive() auto lp = std::shared_ptr(new LoggerProvider()); - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = lp->GetLogger("logger", "", "opentelelemtry_library", "", schema_url); auto sdk_logger = static_cast(logger.get()); @@ -54,7 +54,6 @@ class MockProcessor final : public LogProcessor // Copy over the received log record's severity, name, and body fields over to the recordable // passed in the constructor record_received_->SetSeverity(copy->GetSeverity()); - record_received_->SetName(copy->GetName()); record_received_->SetBody(copy->GetBody()); } bool ForceFlush(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept @@ -71,7 +70,7 @@ TEST(LoggerSDK, LogToAProcessor) { // Create an API LoggerProvider and logger auto api_lp = std::shared_ptr(new LoggerProvider()); - const std::string schema_url{"https://opentelemetry.io/schemas/1.2.0"}; + const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; auto logger = api_lp->GetLogger("logger", "", "opentelelemtry_library", "", schema_url); // Cast the API LoggerProvider to an SDK Logger Provider and assert that it is still the same @@ -90,10 +89,9 @@ TEST(LoggerSDK, LogToAProcessor) lp->AddProcessor(std::unique_ptr(new MockProcessor(shared_recordable))); // Check that the recordable created by the Log() statement is set properly - logger->Log(logs_api::Severity::kWarn, "Log Name", "Log Message"); + logger->Log(logs_api::Severity::kWarn, "Log Message"); ASSERT_EQ(shared_recordable->GetSeverity(), logs_api::Severity::kWarn); - ASSERT_EQ(shared_recordable->GetName(), "Log Name"); ASSERT_EQ(shared_recordable->GetBody(), "Log Message"); } #endif diff --git a/sdk/test/logs/simple_log_processor_test.cc b/sdk/test/logs/simple_log_processor_test.cc index 0bb6ba2667..32c62a5083 100644 --- a/sdk/test/logs/simple_log_processor_test.cc +++ b/sdk/test/logs/simple_log_processor_test.cc @@ -85,7 +85,7 @@ TEST(SimpleLogProcessorTest, SendReceivedLogsToExporter) for (int i = 0; i < num_logs; i++) { auto recordable = processor.MakeRecordable(); - recordable->SetName("Log"); + recordable->SetBody("Log Body"); processor.OnReceive(std::move(recordable)); // Verify that the batch of 1 log record sent by processor matches what exporter received @@ -96,7 +96,7 @@ TEST(SimpleLogProcessorTest, SendReceivedLogsToExporter) EXPECT_EQ(logs_received->size(), num_logs); for (int i = 0; i < num_logs; i++) { - EXPECT_EQ("Log", logs_received->at(i)->GetName()); + EXPECT_EQ("Log Body", logs_received->at(i)->GetBody()); } } diff --git a/third_party/opentelemetry-proto b/third_party/opentelemetry-proto index b43e9b18b7..5c2fe5ddbd 160000 --- a/third_party/opentelemetry-proto +++ b/third_party/opentelemetry-proto @@ -1 +1 @@ -Subproject commit b43e9b18b76abf3ee040164b55b9c355217151f3 +Subproject commit 5c2fe5ddbd9fb9f3e08f31d20f7566a3ee3d8885 diff --git a/third_party_release b/third_party_release index c752efe629..964cbfb871 100644 --- a/third_party_release +++ b/third_party_release @@ -2,9 +2,9 @@ gRPC=v1.43.2 thrift=0.14.1 abseil=20210324.0 benchmark=v1.5.3 -googletest=release-1.8.0-2523-ga6dfd3ac -ms-gsl=v1.0.0-393-g6f45293 +googletest=release-1.10.0-459-ga6dfd3ac +ms-gsl=v3.1.0-67-g6f45293 nlohmann-json=v3.9.1 -opentelemetry-proto=v0.11.0 +opentelemetry-proto=v0.17.0 prometheus-cpp=v1.0.0 -vcpkg=2020.04-2702-g5568f110b +vcpkg=2022.04.12 diff --git a/tools/build-vcpkg.sh b/tools/build-vcpkg.sh index f7fb829ce2..f4acb009fe 100755 --- a/tools/build-vcpkg.sh +++ b/tools/build-vcpkg.sh @@ -1,23 +1,26 @@ #!/bin/bash export PATH=/usr/local/bin:$PATH -DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" +DIR="$( + cd "$(dirname "$0")" >/dev/null 2>&1 + pwd -P +)" WORKSPACE_ROOT=$DIR/.. export VCPKG_ROOT=$WORKSPACE_ROOT/tools/vcpkg export PATH=$VCPKG_ROOT:$PATH -if [[ ! -f $DIR/vcpkg/vcpkg ]] ; then +if [[ ! -f $DIR/vcpkg/vcpkg ]]; then pushd $DIR/vcpkg ./bootstrap-vcpkg.sh popd fi -vcpkg install gtest -vcpkg install benchmark -vcpkg install ms-gsl -vcpkg install nlohmann-json -vcpkg install abseil -vcpkg install protobuf +vcpkg "--vcpkg-root=$VCPKG_ROOT" install gtest +vcpkg "--vcpkg-root=$VCPKG_ROOT" install benchmark +vcpkg "--vcpkg-root=$VCPKG_ROOT" install ms-gsl +vcpkg "--vcpkg-root=$VCPKG_ROOT" install nlohmann-json +vcpkg "--vcpkg-root=$VCPKG_ROOT" install abseil +vcpkg "--vcpkg-root=$VCPKG_ROOT" install protobuf cd $WORKSPACE_ROOT export USE_VCPKG=1 diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd index 956c8ddfe4..fab61a520e 100644 --- a/tools/setup-buildtools.cmd +++ b/tools/setup-buildtools.cmd @@ -61,15 +61,15 @@ if %ERRORLEVEL% == 1 ( ) REM Install dependencies -vcpkg install gtest:%ARCH%-windows -vcpkg install --overlay-ports=%~dp0ports benchmark:%ARCH%-windows -vcpkg install --overlay-ports=%~dp0ports protobuf:%ARCH%-windows -vcpkg install ms-gsl:%ARCH%-windows -vcpkg install nlohmann-json:%ARCH%-windows -vcpkg install abseil:%ARCH%-windows -vcpkg install gRPC:%ARCH%-windows -vcpkg install prometheus-cpp:%ARCH%-windows -vcpkg install curl:%ARCH%-windows -vcpkg install thrift:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install gtest:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install --overlay-ports=%~dp0ports benchmark:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install --overlay-ports=%~dp0ports protobuf:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install ms-gsl:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install nlohmann-json:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install abseil:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install gRPC:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install prometheus-cpp:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install curl:%ARCH%-windows +vcpkg "--vcpkg-root=%VCPKG_ROOT%" install thrift:%ARCH%-windows popd exit /b 0 From 09b92afd9d901dc5d9b6d2a95877806b25c61d44 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Wed, 18 May 2022 09:22:06 -0700 Subject: [PATCH 66/69] Prepare v1.4.0 release (#1404) --- CHANGELOG.md | 54 +++++++++++++++++++ README.md | 14 ++--- api/include/opentelemetry/version.h | 2 +- docs/public/conf.py | 2 +- .../opentelemetry/sdk/version/version.h | 2 +- sdk/src/version/version.cc | 2 +- 6 files changed, 65 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9393523ddf..5a260fe8be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,61 @@ Increment the: ## [Unreleased] +## [1.4.0] 2022-05-17 + +* [API SDK] Upgrade proto to v0.17.0, update log data model ([#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383)) +* [BUILD] Alpine image ([#1382](https://github.com/open-telemetry/opentelemetry-cpp/pull/1382)) +* [LOGS SDK] Get span_id from context when Logger::Log received invalid span_id + ([#1398](https://github.com/open-telemetry/opentelemetry-cpp/pull/1398)) +* [METRICS SDK] Connect async storage with async instruments ([#1388](https://github.com/open-telemetry/opentelemetry-cpp/pull/1388)) +* [DOCS] Getting started document using ostream exporter ([#1394](https://github.com/open-telemetry/opentelemetry-cpp/pull/1394)) +* [BUILD] Fix missing link to nlohmann_json ([#1390](https://github.com/open-telemetry/opentelemetry-cpp/pull/1390)) +* [SDK] Fix sharing resource in batched exported spans ([#1386](https://github.com/open-telemetry/opentelemetry-cpp/pull/1386)) * [PROTOCOL \& LOGS] Upgrade proto to v0.17.0, update log data model ([#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383)) +* [METRICS SDK] Remove un-necessary files. ([#1379](https://github.com/open-telemetry/opentelemetry-cpp/pull/1379)) +* [EXPORTER] Prometheus exporter meters and instrument name ([#1378](https://github.com/open-telemetry/opentelemetry-cpp/pull/1378)) +* [API] Add noexcept/const qualifier at missing places for Trace API. ([#1374](https://github.com/open-telemetry/opentelemetry-cpp/pull/1374)) +* [SDK] Fix empty tracestate header propagation ([#1373](https://github.com/open-telemetry/opentelemetry-cpp/pull/1373)) +* [METRICS SDK] Reuse temporal metric storage for sync storage ([#1369](https://github.com/open-telemetry/opentelemetry-cpp/pull/1369)) +* [SDK] Fix baggage propagation for empty/invalid baggage context ([#1367](https://github.com/open-telemetry/opentelemetry-cpp/pull/1367)) +* [BUILD] Export opentelemetry_otlp_recordable ([#1365](https://github.com/open-telemetry/opentelemetry-cpp/pull/1365)) +* [TESTS] Disable test on prometheus-cpp which not need ([#1363](https://github.com/open-telemetry/opentelemetry-cpp/pull/1363)) +* [METRICS] Fix class member initialization order ([#1360](https://github.com/open-telemetry/opentelemetry-cpp/pull/1360)) +* [METRICS SDK] Simplify SDK Configuration: Use View with default aggregation if + no matching View is configured + ([#1358](https://github.com/open-telemetry/opentelemetry-cpp/pull/1358)) +* [BUILD] Add missing include guard ([#1357](https://github.com/open-telemetry/opentelemetry-cpp/pull/1357)) +* [ETW EXPORTER] Fix scalar delete against array ([#1356](https://github.com/open-telemetry/opentelemetry-cpp/pull/1356)) +* [ETW EXPORTER] Conditional include for codecvt header ([#1355](https://github.com/open-telemetry/opentelemetry-cpp/pull/1355)) +* [BUILD] Use latest TraceLoggingDynamic.h ([#1354](https://github.com/open-telemetry/opentelemetry-cpp/pull/1354)) +* [SDK] Add explicit type cast in baggage UrlDecode ([#1353](https://github.com/open-telemetry/opentelemetry-cpp/pull/1353)) +* [METRICS SDK] Remove exporter registration to meter provider ([#1350](https://github.com/open-telemetry/opentelemetry-cpp/pull/1350)) +* [METRICS SDK] Fix output time in metrics OStream exporter ([#1346](https://github.com/open-telemetry/opentelemetry-cpp/pull/1346)) +* [BUILD] ostream metrics cmake ([#1344](https://github.com/open-telemetry/opentelemetry-cpp/pull/1344)) +* [BUILD] Link `opentelemetry_ext` with `opentelemetry_api` ([#1336](https://github.com/open-telemetry/opentelemetry-cpp/pull/1336)) +* [METRICS SDK] Enable metric collection for Async Instruments - Delta and + Cumulative + ([#1334](https://github.com/open-telemetry/opentelemetry-cpp/pull/1334)) +* [BUILD] Dependencies image as artifact ([#1333](https://github.com/open-telemetry/opentelemetry-cpp/pull/1333)) +* [EXAMPLE] Prometheus example ([#1332](https://github.com/open-telemetry/opentelemetry-cpp/pull/1332)) +* [METRICS EXPORTER] Prometheus exporter ([#1331](https://github.com/open-telemetry/opentelemetry-cpp/pull/1331)) +* [METRICS] Metrics histogram example ([#1330](https://github.com/open-telemetry/opentelemetry-cpp/pull/1330)) +* [TESTS] Replace deprecated googletest API ([#1327](https://github.com/open-telemetry/opentelemetry-cpp/pull/1327)) +* [BUILD] Fix Ninja path ([#1326](https://github.com/open-telemetry/opentelemetry-cpp/pull/1326)) +* [API] Update yield logic for ARM processor ([#1325](https://github.com/open-telemetry/opentelemetry-cpp/pull/1325)) +* [BUILD] Fix metrics compiler warnings ([#1328](https://github.com/open-telemetry/opentelemetry-cpp/pull/1328)) +* [METRICS SDK] Implement Merge and Diff operation for Histogram Aggregation ([#1303](https://github.com/open-telemetry/opentelemetry-cpp/pull/1303)) + +Notes: + +While opentelemetry-cpp Logs are still in experimental stage, +[#1383](https://github.com/open-telemetry/opentelemetry-cpp/pull/1383) updated +opentelemetry-proto to 0.17.0, which includes some breaking change in the +protocol, like +[this](https://github.com/open-telemetry/opentelemetry-proto/pull/373). This +makes `name` parameter for our log API unnecessary. However, this parameter is +marked deprecated instead of being removed in this release, and it will be +removed in future release. ## [1.3.0] 2022-04-11 diff --git a/README.md b/README.md index 7dc77fc940..75231ac7cc 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,15 @@ The C++ [OpenTelemetry](https://opentelemetry.io/) client. | Signal | Status | Project | | ------- | ---------------------- | ------------------------------------------------------------------------ | | Traces | Public Release | N/A | -| Metrics | Development [1] | N/A | +| Metrics | Alpha [1] | N/A | | Logs | Experimental [2] | N/A | -* [1]: The development of the metrics API and SDK based on new stable - specification is ongoing. The timelines would be available in release - milestone. The earlier implementation (based on old specification) can be - included in build by setting `ENABLE_METRICS_PREVIEW` preprocessor macro, - and is included under `*/_metrics/*` directory. This would be eventually - removed once the ongoing implemetation is stable. +* [1]: The metric collection pipeline is available for testing purpose. Not + ready for production. The earlier implementation (based on old + specification) can be included in build by setting + `ENABLE_METRICS_PREVIEW` preprocessor macro, and is included under + `*/_metrics/*` directory. This would be eventually removed once the + ongoing implemetation is stable. * [2]: The current Log Signal Implementation is Experimental, and will change as the current OpenTelemetry Log specification matures. The current implementation can be included in build by setting `ENABLE_LOGS_PREVIEW` diff --git a/api/include/opentelemetry/version.h b/api/include/opentelemetry/version.h index 1e01e242ed..849259d3ed 100644 --- a/api/include/opentelemetry/version.h +++ b/api/include/opentelemetry/version.h @@ -6,7 +6,7 @@ #include "opentelemetry/detail/preprocessor.h" #define OPENTELEMETRY_ABI_VERSION_NO 1 -#define OPENTELEMETRY_VERSION "1.3.0" +#define OPENTELEMETRY_VERSION "1.4.0" #define OPENTELEMETRY_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_ABI_VERSION_NO) // clang-format off diff --git a/docs/public/conf.py b/docs/public/conf.py index 910cfc6346..ff95a16b3f 100644 --- a/docs/public/conf.py +++ b/docs/public/conf.py @@ -21,7 +21,7 @@ author = 'OpenTelemetry authors' # The full version, including alpha/beta/rc tags -release = '1.3.0' +release = '1.4.0' # Run sphinx on subprojects and copy output # ----------------------------------------- diff --git a/sdk/include/opentelemetry/sdk/version/version.h b/sdk/include/opentelemetry/sdk/version/version.h index 155cba3f87..65c3c826ca 100644 --- a/sdk/include/opentelemetry/sdk/version/version.h +++ b/sdk/include/opentelemetry/sdk/version/version.h @@ -5,7 +5,7 @@ #include "opentelemetry/detail/preprocessor.h" -#define OPENTELEMETRY_SDK_VERSION "1.3.0" +#define OPENTELEMETRY_SDK_VERSION "1.4.0" #include "opentelemetry/version.h" diff --git a/sdk/src/version/version.cc b/sdk/src/version/version.cc index a153196514..9303a305aa 100644 --- a/sdk/src/version/version.cc +++ b/sdk/src/version/version.cc @@ -9,7 +9,7 @@ namespace sdk namespace version { const int MAJOR_VERSION = 1; -const int MINOR_VERSION = 3; +const int MINOR_VERSION = 4; const int PATCH_VERSION = 0; const char *PRE_RELEASE = ""; const char *BUILD_METADATA = ""; From ab084ecea5b4888110016c47237e877a82795319 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Wed, 18 May 2022 10:52:59 -0700 Subject: [PATCH 67/69] Fix vcpkg package name in doc (#1392) --- docs/building-with-vcpkg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-with-vcpkg.md b/docs/building-with-vcpkg.md index 7586486e88..aace95460c 100644 --- a/docs/building-with-vcpkg.md +++ b/docs/building-with-vcpkg.md @@ -13,7 +13,7 @@ source release of OpenTelemetry C++ SDK. The following command can be used to install the public open source release: ```console -vcpkg install opentelemetry +vcpkg install opentelemetry-cpp ``` That's it! The package should be compiled for the current OS. From a847d0ce42209e458f8f98a5751626a33adfad95 Mon Sep 17 00:00:00 2001 From: Ehsan Saei <71217171+esigo@users.noreply.github.com> Date: Wed, 18 May 2022 23:29:22 +0200 Subject: [PATCH 68/69] Document Getting Started with Prometheus and Grafana (#1396) Co-authored-by: Lalit Kumar Bhasin --- examples/prometheus/README.md | 208 ++++++++++++++++++ examples/prometheus/prometheus.yml | 4 +- .../exporters/prometheus/exporter.h | 6 +- 3 files changed, 213 insertions(+), 5 deletions(-) create mode 100644 examples/prometheus/README.md diff --git a/examples/prometheus/README.md b/examples/prometheus/README.md new file mode 100644 index 0000000000..d7e284a0ec --- /dev/null +++ b/examples/prometheus/README.md @@ -0,0 +1,208 @@ +# Getting Started with Prometheus and Grafana + +- [Export metrics from the application](#export-metrics-from-the-application) + - [Check results in the browser](#check-results-in-the-browser) +- [Collect metrics using Prometheus](#collect-metrics-using-prometheus) + - [Configuration](#configuration) + - [Start Prometheus](#start-prometheus) + - [View results in Prometheus](#view-results-in-prometheus) +- [Explore metrics using Grafana](#explore-metrics-using-grafana) +- [Learn more](#learn-more) + +## Export metrics from the application + +It is highly recommended to go over the [ostream-metrics](../metrics_simple/README.md) +doc before following along this document. + +Run the application with: + +```sh +bazel run //examples/prometheus:prometheus_example +``` + +The main difference between the [ostream-metrics](../metrics_simple/README.md) +example with this one is that the line below is replaced: + +```cpp +std::unique_ptr exporter{ + new exportermetrics::OStreamMetricExporter}; + +``` + +with + +```cpp +std::unique_ptr exporter{ + new metrics_exporter::PrometheusExporter(opts)}; +``` + +OpenTelemetry `PrometheusExporter` will export +data via the endpoint defined by +`metrics_exporter::PrometheusExporterOptions::url`, +which is `http://localhost:9464/` by default. + +```mermaid +graph LR + +subgraph SDK + MeterProvider + MetricReader[PeriodicExportingMetricReader] + PrometheusExporter["PrometheusExporter
(http://localhost:9464/)"] +end + +subgraph API + Instrument["Meter(#quot;prometheus_metric_example#quot;, #quot;1.0#quot;)
Histogram(#quot;prometheus_metric_example_histogram#quot;)"] +end + +Instrument --> | Measurements | MeterProvider + +MeterProvider --> | Metrics | MetricReader --> | Pull | PrometheusExporter +``` + +Also, for our learning purpose, we use a while-loop to keep recoring random +values until the program stops. + +```cpp +while (true) +{ + double val = (rand() % 700) + 1.1; + std::map labels = get_random_attr(); + auto labelkv = opentelemetry::common::KeyValueIterableView{labels}; + histogram_counter->Record(val, labelkv, context); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); +} +``` + +### Check results in the browser + +Start the application and keep it running. Now we should be able to see the +metrics at [http://localhost:9464/metrics](http://localhost:9464/metrics) from a +web browser: + +![Browser UI](https://user-images.githubusercontent.com/71217171/168492500-12bd1c99-33ab-4515-a294-17bc349b5d13.png) + +Now, we understand how we can configure `PrometheusExporter` to export metrics. +Next, we are going to learn about how to use Prometheus to collect the metrics. + +## Collect metrics using Prometheus + +Follow the [first steps](https://prometheus.io/docs/introduction/first_steps/) +to download the [latest release](https://prometheus.io/download/) of Prometheus. +It is also possible to use `prom/prometheus` docker image. + +### Configuration + +After downloading, extract it to a local location that's easy to +access. We will find the default Prometheus configuration YAML file in the +folder, named `prometheus.yml`. + +```yaml +global: + scrape_interval: 5s + scrape_timeout: 2s + evaluation_interval: 5s +alerting: + alertmanagers: + - follow_redirects: true + scheme: http + timeout: 5s + api_version: v2 + static_configs: + - targets: [localhost:9464] +scrape_configs: + - job_name: otel + static_configs: + - targets: ['localhost:9464'] +``` + +### Start Prometheus + +Follow the instructions from +[starting-prometheus](https://prometheus.io/docs/introduction/first_steps/#starting-prometheus) +to start the Prometheus server and verify it has been started successfully. + +Please note that we will need pass in `prometheus.yml` file as the argument +or mount as volume: + +```console +./prometheus --config.file=prometheus.yml +# OR: +docker run -p 9090:9090 -v $(pwd):/etc/prometheus --network="host" prom/prometheus +``` + +### View results in Prometheus + +To use the graphical interface for viewing our metrics with Prometheus, navigate +to [http://localhost:9090/graph](http://localhost:9090/graph), +and type `prometheus_metric_example_bucket` in the expression bar of the UI; +finally, click the execute button. + +We should be able to see the following chart from the browser: + +![Prometheus UI](https://user-images.githubusercontent.com/71217171/168492437-f9769db1-6f9e-49c6-8ef0-85f5e1188ba0.png) + +From the legend, we can see that the `instance` name and the `job` name are the +values we have set in `prometheus.yml`. + +Congratulations! + +Now we know how to configure Prometheus server and deploy OpenTelemetry +`PrometheusExporter` to export our metrics. Next, we are going to explore a tool +called Grafana, which has powerful visualizations for the metrics. + +## Explore metrics using Grafana + +[Install Grafana](https://grafana.com/docs/grafana/latest/installation/). + +Start the standalone Grafana server (`grafana-server.exe` or +`./bin/grafana-server`, depending on the operating system). Then, use the +browser to navigate to [http://localhost:3000/](http://localhost:3000/). +It is also possible to run `grafana/grafana` container: + +```sh +docker run -d -p 3000:3000 --network="host" grafana/grafana +``` + +Follow the instructions in the Grafana getting started +[doc](https://grafana.com/docs/grafana/latest/getting-started/getting-started/#step-2-log-in) +to log in. + +After successfully logging in, click on the Configuration icon +on the panel at the left hand side, and click on Prometheus. +Type in the default endpoint of Prometheus as suggested by the UI +as the value for the URI. + +```console +http://localhost:9090 +``` + +Then, click on the Explore icon on the left panel of +the website - we should be able to write some queries to explore our metrics +now! + +Feel free to find some handy PromQL +[here](https://promlabs.com/promql-cheat-sheet/). + +![Grafana +UI](https://user-images.githubusercontent.com/71217171/168492482-047a4429-4854-4b3c-a2dd-4d75362090d5.png) + +```mermaid +graph TD + +subgraph Prometheus + PrometheusScraper + PrometheusDatabase +end + +PrometheusExporter["PrometheusExporter
(listening at #quot;http://localhost:9464/#quot;)"] -->|HTTP GET| PrometheusScraper{{"Prometheus scraper
(polling #quot;http://localhost:9464/metrics#quot; every 5 seconds)"}} +PrometheusScraper --> PrometheusDatabase[("Prometheus TSDB (time series database)")] +PrometheusDatabase -->|http://localhost:9090/graph| PrometheusUI["Browser
(Prometheus Dashboard)"] +PrometheusDatabase -->|http://localhost:9090/api/| Grafana[Grafana Server] +Grafana -->|http://localhost:3000/dashboard| GrafanaUI["Browser
(Grafana Dashboard)"] +``` + +## Learn more + +- [What is Prometheus?](https://prometheus.io/docs/introduction/overview/) +- [Grafana support for + Prometheus](https://prometheus.io/docs/visualization/grafana/#creating-a-prometheus-graph) diff --git a/examples/prometheus/prometheus.yml b/examples/prometheus/prometheus.yml index 3f415d39dc..17c42fda3f 100644 --- a/examples/prometheus/prometheus.yml +++ b/examples/prometheus/prometheus.yml @@ -9,8 +9,8 @@ alerting: timeout: 5s api_version: v2 static_configs: - - targets: [localhost:8080] + - targets: [localhost:9464] scrape_configs: - job_name: otel static_configs: - - targets: ['localhost:8080'] \ No newline at end of file + - targets: ['localhost:9464'] \ No newline at end of file diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h index 151244928f..59ef1a11ad 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h @@ -28,10 +28,10 @@ namespace exporter namespace metrics { -inline const std::string GetOtlpDefaultHttpEndpoint() +inline const std::string GetPrometheusDefaultHttpEndpoint() { constexpr char kPrometheusEndpointEnv[] = "PROMETHEUS_EXPORTER_ENDPOINT"; - constexpr char kPrometheusEndpointDefault[] = "localhost:8080"; + constexpr char kPrometheusEndpointDefault[] = "localhost:9464"; auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kPrometheusEndpointEnv); return endpoint.size() ? endpoint : kPrometheusEndpointDefault; @@ -43,7 +43,7 @@ inline const std::string GetOtlpDefaultHttpEndpoint() struct PrometheusExporterOptions { // The endpoint the Prometheus backend can collect metrics from - std::string url = GetOtlpDefaultHttpEndpoint(); + std::string url = GetPrometheusDefaultHttpEndpoint(); }; class PrometheusExporter : public sdk::metrics::MetricExporter From 63803d10c6ec2b8f5315856fe258f63d386aca3b Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 18 May 2022 18:56:21 -0700 Subject: [PATCH 69/69] fix OTEL_INTERNAL_LOG_INFO (#1407) --- .../opentelemetry/sdk/common/global_log_handler.h | 6 +++--- sdk/test/common/global_log_handle_test.cc | 12 +++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index 06bbd30f7d..612d21eca5 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -236,9 +236,9 @@ OPENTELEMETRY_END_NAMESPACE # define OTEL_INTERNAL_LOG_INFO_2_ARGS(message, attributes) \ OTEL_INTERNAL_LOG_DISPATCH(opentelemetry::sdk::common::internal_log::LogLevel::Info, message, \ attributes) -# define OTEL_INTERNAL_LOG_INFO_MACRO(...) \ - OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_ERROR_2_ARGS, \ - OTEL_INTERNAL_LOG_ERROR_1_ARGS) +# define OTEL_INTERNAL_LOG_INFO_MACRO(...) \ + OTEL_INTERNAL_LOG_GET_3RD_ARG(__VA_ARGS__, OTEL_INTERNAL_LOG_INFO_2_ARGS, \ + OTEL_INTERNAL_LOG_INFO_1_ARGS) # define OTEL_INTERNAL_LOG_INFO(...) OTEL_INTERNAL_LOG_INFO_MACRO(__VA_ARGS__)(__VA_ARGS__) #else # define OTEL_INTERNAL_LOG_INFO(...) diff --git a/sdk/test/common/global_log_handle_test.cc b/sdk/test/common/global_log_handle_test.cc index 9c24b0234e..a38bdc8728 100644 --- a/sdk/test/common/global_log_handle_test.cc +++ b/sdk/test/common/global_log_handle_test.cc @@ -24,6 +24,14 @@ class CustomLogHandler : public opentelemetry::sdk::common::internal_log::LogHan { EXPECT_EQ(0, strncmp(msg, "Error message", 13)); } + else if (level == opentelemetry::sdk::common::internal_log::LogLevel::Info) + { + EXPECT_EQ(0, strncmp(msg, "Info message", 12)); + } + else if (level == opentelemetry::sdk::common::internal_log::LogLevel::Warning) + { + EXPECT_EQ(0, strncmp(msg, "Warning message", 15)); + } ++count; } @@ -50,7 +58,9 @@ TEST(GlobalLogHandleTest, CustomLogHandler) opentelemetry::sdk::common::internal_log::LogLevel::Debug); OTEL_INTERNAL_LOG_ERROR("Error message"); OTEL_INTERNAL_LOG_DEBUG("Debug message. Headers:", attributes); - EXPECT_EQ(before_count + 3, static_cast(custom_log_handler.get())->count); + OTEL_INTERNAL_LOG_INFO("Info message"); + OTEL_INTERNAL_LOG_WARN("Warning message"); + EXPECT_EQ(before_count + 5, static_cast(custom_log_handler.get())->count); opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogHandler(backup_log_handle); opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogLevel(backup_log_level);