From 33c6dd48081f583003d61a11b685aa4a7fde5285 Mon Sep 17 00:00:00 2001 From: proost Date: Fri, 14 Aug 2026 23:32:24 +0900 Subject: [PATCH 1/5] fix: fixed size exemplar reservoir --- .../exemplar/fixed_size_exemplar_reservoir.h | 26 ++- .../simple_fixed_size_exemplar_reservoir.h | 3 +- sdk/test/metrics/exemplar/BUILD | 17 ++ sdk/test/metrics/exemplar/CMakeLists.txt | 2 +- .../fixed_size_exemplar_reservoir_test.cc | 178 ++++++++++++++++++ 5 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h index c455c0188b..ac48eb2d7d 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h @@ -6,6 +6,8 @@ #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW # include +# include +# include # include # include "opentelemetry/context/context.h" @@ -44,6 +46,9 @@ class FixedSizeExemplarReservoir : public ExemplarReservoir { return; } + + std::lock_guard lock{mutex_}; + auto idx = reservoir_cell_selector_->ReservoirCellIndexFor(storage_, value, attributes, context); if (idx != -1) @@ -60,6 +65,9 @@ class FixedSizeExemplarReservoir : public ExemplarReservoir { return; } + + std::lock_guard lock{mutex_}; + auto idx = reservoir_cell_selector_->ReservoirCellIndexFor(storage_, value, attributes, context); if (idx != -1) @@ -76,17 +84,26 @@ class FixedSizeExemplarReservoir : public ExemplarReservoir { return results; } + + std::lock_guard lock{mutex_}; + if (!map_and_reset_cell_) { - reservoir_cell_selector_.reset(); + reservoir_cell_selector_->reset(); return results; } - for (auto reservoirCell : storage_) + + results.reserve(storage_.size()); + for (auto &reservoirCell : storage_) { auto result = (reservoirCell.*(map_and_reset_cell_))(pointAttributes); - results.push_back(result); + if (result) + { + results.emplace_back(std::move(result)); + } } - reservoir_cell_selector_.reset(); + + reservoir_cell_selector_->reset(); return results; } @@ -95,6 +112,7 @@ class FixedSizeExemplarReservoir : public ExemplarReservoir std::vector storage_; std::shared_ptr reservoir_cell_selector_; MapAndResetCellType map_and_reset_cell_{nullptr}; + std::mutex mutex_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h index 3465431d65..1743344370 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h @@ -88,11 +88,12 @@ class SimpleFixedSizeExemplarReservoir : public FixedSizeExemplarReservoir return static_cast(index); } - void reset() override {} + void reset() override { measurements_seen_ = 0; } private: size_t measurements_seen_ = 0; size_t size_; + friend class SimpleFixedSizeCellSelectorTestPeer; }; // class SimpleFixedSizeCellSelector }; // class SimpleFixedSizeExemplarReservoir diff --git a/sdk/test/metrics/exemplar/BUILD b/sdk/test/metrics/exemplar/BUILD index 2dbfd39f8d..19f62e8cc1 100644 --- a/sdk/test/metrics/exemplar/BUILD +++ b/sdk/test/metrics/exemplar/BUILD @@ -70,3 +70,20 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "fixed_size_exemplar_reservoir_test", + srcs = [ + "fixed_size_exemplar_reservoir_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/sdk/test/metrics/exemplar/CMakeLists.txt b/sdk/test/metrics/exemplar/CMakeLists.txt index 2dfb891ee2..184e574398 100644 --- a/sdk/test/metrics/exemplar/CMakeLists.txt +++ b/sdk/test/metrics/exemplar/CMakeLists.txt @@ -4,7 +4,7 @@ foreach( testname no_exemplar_reservoir_test aligned_histogram_bucket_exemplar_reservoir_test - reservoir_cell_test filter_predicate_test) + reservoir_cell_test filter_predicate_test fixed_size_exemplar_reservoir_test) add_executable(${testname} "${testname}.cc") target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} diff --git a/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc new file mode 100644 index 0000000000..5c9fd15323 --- /dev/null +++ b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc @@ -0,0 +1,178 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW + +# include +# include +# include +# include +# include +# include +# include +# include + +# include "opentelemetry/context/context.h" +# include "opentelemetry/sdk/metrics/data/exemplar_data.h" +# include "opentelemetry/sdk/metrics/exemplar/aligned_histogram_bucket_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h" +# include "opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h" +# include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class SimpleFixedSizeCellSelectorTestPeer +{ +public: + static size_t GetMeasurementsSeen( + const SimpleFixedSizeExemplarReservoir::SimpleFixedSizeCellSelector &selector) + { + return selector.measurements_seen_; + } +}; + +namespace +{ + +TEST(FixedSizeExemplarReservoirTest, CollectAndResetSupportsMultipleIntervals) +{ + std::vector boundaries{1.0, 5.0, 10.0}; + auto reservoir = ExemplarReservoir::GetAlignedHistogramBucketExemplarReservoir( + boundaries.size(), + AlignedHistogramBucketExemplarReservoir::GetHistogramCellSelector(boundaries), + &ReservoirCell::GetAndResetDouble); + + reservoir->OfferMeasurement(2.0, MetricAttributes{}, opentelemetry::context::Context{}); + auto first_interval = reservoir->CollectAndReset(MetricAttributes{}); + ASSERT_EQ(first_interval.size(), 1U); + EXPECT_NE(first_interval[0], nullptr); + + // Collecting again without another offer verifies that the cells in storage, + // rather than copies of those cells, were reset. + EXPECT_TRUE(reservoir->CollectAndReset(MetricAttributes{}).empty()); + + // A collection resets the selector state without destroying the selector, so + // the same reservoir remains usable in the next interval. + reservoir->OfferMeasurement(8.0, MetricAttributes{}, opentelemetry::context::Context{}); + auto second_interval = reservoir->CollectAndReset(MetricAttributes{}); + ASSERT_EQ(second_interval.size(), 1U); + EXPECT_NE(second_interval[0], nullptr); +} + +TEST(FixedSizeExemplarReservoirTest, SimpleReservoirRestartsSamplingEachInterval) +{ + auto selector = + std::make_shared(1); + auto reservoir = ExemplarReservoir::GetSimpleFixedSizeExemplarReservoir( + 1, selector, &ReservoirCell::GetAndResetLong); + + reservoir->OfferMeasurement(static_cast(1), MetricAttributes{}, + opentelemetry::context::Context{}); + ASSERT_EQ(SimpleFixedSizeCellSelectorTestPeer::GetMeasurementsSeen(*selector), 1U); + + auto exemplars = reservoir->CollectAndReset(MetricAttributes{}); + ASSERT_EQ(exemplars.size(), 1U); + EXPECT_NE(exemplars[0], nullptr); + EXPECT_EQ(SimpleFixedSizeCellSelectorTestPeer::GetMeasurementsSeen(*selector), 0U); +} + +class ConcurrentAccessDetector final : public ReservoirCellSelector +{ +public: + int ReservoirCellIndexFor(const std::vector & /* cells */, + int64_t /* value */, + const MetricAttributes & /* attributes */, + const opentelemetry::context::Context & /* context */) override + { + Visit(); + return 0; + } + + int ReservoirCellIndexFor(const std::vector & /* cells */, + double /* value */, + const MetricAttributes & /* attributes */, + const opentelemetry::context::Context & /* context */) override + { + Visit(); + return 0; + } + + void reset() override { Visit(); } + + bool HasConcurrentAccess() const noexcept + { + return concurrent_access_.load(std::memory_order_relaxed); + } + +private: + void Visit() + { + if (active_calls_.fetch_add(1, std::memory_order_acq_rel) != 0) + { + concurrent_access_.store(true, std::memory_order_relaxed); + } + std::this_thread::yield(); + active_calls_.fetch_sub(1, std::memory_order_release); + } + + std::atomic active_calls_{0}; + std::atomic concurrent_access_{false}; +}; + +TEST(FixedSizeExemplarReservoirTest, SerializesOffersAndCollection) +{ + auto selector = std::make_shared(); + auto reservoir = ExemplarReservoir::GetSimpleFixedSizeExemplarReservoir( + 1, selector, &ReservoirCell::GetAndResetLong); + std::atomic start{false}; + + constexpr size_t kOfferThreadCount = 3; + constexpr size_t kIterations = 500; + std::vector threads; + threads.reserve(kOfferThreadCount + 1); + for (size_t thread_index = 0; thread_index < kOfferThreadCount; ++thread_index) + { + threads.emplace_back([&] { + while (!start.load(std::memory_order_acquire)) + { + std::this_thread::yield(); + } + for (size_t i = 0; i < kIterations; ++i) + { + reservoir->OfferMeasurement(static_cast(i), MetricAttributes{}, + opentelemetry::context::Context{}); + } + }); + } + threads.emplace_back([&] { + while (!start.load(std::memory_order_acquire)) + { + std::this_thread::yield(); + } + for (size_t i = 0; i < kIterations; ++i) + { + reservoir->CollectAndReset(MetricAttributes{}); + } + }); + + start.store(true, std::memory_order_release); + for (auto &thread : threads) + { + thread.join(); + } + + EXPECT_FALSE(selector->HasConcurrentAccess()); +} + +} // namespace +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE + +#endif // ENABLE_METRICS_EXEMPLAR_PREVIEW From deb01d6d5de62def6222620fb79447bb5045cd6b Mon Sep 17 00:00:00 2001 From: proost Date: Fri, 14 Aug 2026 23:38:43 +0900 Subject: [PATCH 2/5] doc: update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7935e0456..a586bf1b70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -196,6 +196,12 @@ Increment the: `AlwaysOff`/`TraceBased`) [#4267](https://github.com/open-telemetry/opentelemetry-cpp/pull/4267) +* [METRICS SDK] Fix preview exemplar reservoirs to serialize concurrent + measurement offers and collection, reset stored cells and sampling state + between collection intervals, remain usable after collection, and omit empty + cells from collected results. + [#4429](https://github.com/open-telemetry/opentelemetry-cpp/pull/4429) + Breaking changes: * [CONFIGURATION] SDK default component builder libraries and example From c7864c3a933baaa3e72f4b23d38991be31013952 Mon Sep 17 00:00:00 2001 From: proost Date: Thu, 20 Aug 2026 23:39:07 +0900 Subject: [PATCH 3/5] fix: uniform distributed random --- CHANGELOG.md | 3 ++- .../simple_fixed_size_exemplar_reservoir.h | 21 +++++++++++----- .../fixed_size_exemplar_reservoir_test.cc | 25 ++++++++++++++++++- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c6efdf55b..e2c47efe7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -226,7 +226,8 @@ Increment the: * [METRICS SDK] Fix preview exemplar reservoirs to serialize concurrent measurement offers and collection, reset stored cells and sampling state between collection intervals, remain usable after collection, and omit empty - cells from collected results. + cells from collected results. Correct the simple fixed-size reservoir's + sampling bounds so the current measurement can be discarded. [#4429](https://github.com/open-telemetry/opentelemetry-cpp/pull/4429) Important changes: diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h index 1743344370..932a225133 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h @@ -5,6 +5,7 @@ #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW +# include # include # include @@ -68,6 +69,11 @@ class SimpleFixedSizeExemplarReservoir : public FixedSizeExemplarReservoir // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#simplefixedsizeexemplarreservoir // + if (size_ == 0) + { + return -1; + } + size_t measurement_num = measurements_seen_++; size_t index = static_cast(-1); @@ -77,12 +83,7 @@ class SimpleFixedSizeExemplarReservoir : public FixedSizeExemplarReservoir } else { - size_t random_index = sdk::common::Random::GenerateRandom64() % measurement_num; - - if (random_index < size_) - { - index = random_index; - } + return GetRandomCellIndex(size_, measurement_num, sdk::common::Random::GenerateRandom64()); } return static_cast(index); @@ -91,6 +92,14 @@ class SimpleFixedSizeExemplarReservoir : public FixedSizeExemplarReservoir void reset() override { measurements_seen_ = 0; } private: + static int GetRandomCellIndex(size_t size, + size_t measurement_num, + uint64_t random_value) noexcept + { + size_t random_index = random_value % (measurement_num + 1); + return random_index < size ? static_cast(random_index) : -1; + } + size_t measurements_seen_ = 0; size_t size_; friend class SimpleFixedSizeCellSelectorTestPeer; diff --git a/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc index 5c9fd15323..7ed68d67c8 100644 --- a/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc +++ b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_test.cc @@ -4,9 +4,9 @@ #ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW # include -# include # include # include +# include # include # include # include @@ -35,6 +35,12 @@ class SimpleFixedSizeCellSelectorTestPeer { return selector.measurements_seen_; } + + static int GetRandomCellIndex(size_t size, size_t measurement_num, uint64_t random_value) + { + return SimpleFixedSizeExemplarReservoir::SimpleFixedSizeCellSelector::GetRandomCellIndex( + size, measurement_num, random_value); + } }; namespace @@ -82,6 +88,23 @@ TEST(FixedSizeExemplarReservoirTest, SimpleReservoirRestartsSamplingEachInterval EXPECT_EQ(SimpleFixedSizeCellSelectorTestPeer::GetMeasurementsSeen(*selector), 0U); } +TEST(FixedSizeExemplarReservoirTest, SimpleReservoirSelectionCoversCurrentMeasurement) +{ + EXPECT_EQ(SimpleFixedSizeCellSelectorTestPeer::GetRandomCellIndex(1, 1, 0), 0); + EXPECT_EQ(SimpleFixedSizeCellSelectorTestPeer::GetRandomCellIndex(1, 1, 1), -1); +} + +TEST(FixedSizeExemplarReservoirTest, SimpleReservoirWithZeroSizeDoesNotSelectCell) +{ + SimpleFixedSizeExemplarReservoir::SimpleFixedSizeCellSelector selector{0}; + std::vector cells; + + EXPECT_EQ(selector.ReservoirCellIndexFor(cells, 1.0, MetricAttributes{}, + opentelemetry::context::Context{}), + -1); + EXPECT_EQ(SimpleFixedSizeCellSelectorTestPeer::GetMeasurementsSeen(selector), 0U); +} + class ConcurrentAccessDetector final : public ReservoirCellSelector { public: From 6c4e5f6f22fe78b93ba0759ba3a35847fe9aa5d6 Mon Sep 17 00:00:00 2001 From: proost Date: Fri, 21 Aug 2026 09:21:14 +0900 Subject: [PATCH 4/5] test: benchmark for lock contention --- sdk/test/metrics/exemplar/BUILD | 18 ++++ sdk/test/metrics/exemplar/CMakeLists.txt | 8 ++ ...fixed_size_exemplar_reservoir_benchmark.cc | 90 +++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc diff --git a/sdk/test/metrics/exemplar/BUILD b/sdk/test/metrics/exemplar/BUILD index 19f62e8cc1..b8af58e15d 100644 --- a/sdk/test/metrics/exemplar/BUILD +++ b/sdk/test/metrics/exemplar/BUILD @@ -2,6 +2,24 @@ # SPDX-License-Identifier: Apache-2.0 load("@rules_cc//cc:cc_test.bzl", "cc_test") +load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark") + +otel_cc_benchmark( + name = "fixed_size_exemplar_reservoir_benchmark", + srcs = [ + "fixed_size_exemplar_reservoir_benchmark.cc", + ], + tags = [ + "benchmark", + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/metrics", + ], +) cc_test( name = "no_exemplar_reservoir_test", diff --git a/sdk/test/metrics/exemplar/CMakeLists.txt b/sdk/test/metrics/exemplar/CMakeLists.txt index 184e574398..849e9ec337 100644 --- a/sdk/test/metrics/exemplar/CMakeLists.txt +++ b/sdk/test/metrics/exemplar/CMakeLists.txt @@ -1,6 +1,14 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 +if(WITH_BENCHMARK) + add_executable(fixed_size_exemplar_reservoir_benchmark + fixed_size_exemplar_reservoir_benchmark.cc) + target_link_libraries( + fixed_size_exemplar_reservoir_benchmark benchmark::benchmark + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) +endif() + foreach( testname no_exemplar_reservoir_test aligned_histogram_bucket_exemplar_reservoir_test diff --git a/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc new file mode 100644 index 0000000000..1b2961d6d0 --- /dev/null +++ b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc @@ -0,0 +1,90 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW + +# include +# include +# include +# include + +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/metrics/data/exemplar_data.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell.h" +# include "opentelemetry/sdk/metrics/exemplar/simple_fixed_size_exemplar_reservoir.h" + +namespace +{ + +using opentelemetry::context::Context; +using opentelemetry::nostd::shared_ptr; +using opentelemetry::sdk::metrics::ExemplarReservoir; +using opentelemetry::sdk::metrics::MetricAttributes; +using opentelemetry::sdk::metrics::ReservoirCell; +using opentelemetry::sdk::metrics::SimpleFixedSizeExemplarReservoir; + +class SharedSimpleFixedSizeExemplarReservoirFixture : public benchmark::Fixture +{ +public: + void SetUp(benchmark::State &state) override + { + if (state.thread_index() != 0) + { + return; + } + + reservoir_ = ExemplarReservoir::GetSimpleFixedSizeExemplarReservoir( + 1, SimpleFixedSizeExemplarReservoir::GetSimpleFixedSizeCellSelector(1), + &ReservoirCell::GetAndResetDouble); + + // Model a reservoir partway through a normal collection interval. This + // keeps the benchmark focused on the steady-state offer path. + for (int64_t i = 0; i < 1024; ++i) + { + reservoir_->OfferMeasurement(static_cast(i), attributes_, context_); + } + } + + void TearDown(benchmark::State &state) override + { + if (state.thread_index() == 0) + { + reservoir_ = nullptr; + } + } + +protected: + shared_ptr reservoir_; + MetricAttributes attributes_{{"http.request.method", "GET"}, + {"http.route", "/checkout"}, + {"http.response.status_code", int64_t{200}}, + {"service.version", "1.42.0"}}; + Context context_; +}; + +BENCHMARK_DEFINE_F(SharedSimpleFixedSizeExemplarReservoirFixture, OfferMeasurement) +(benchmark::State &state) +{ + double value = 10.0 + static_cast(state.thread_index()); + for (auto _ : state) + { + reservoir_->OfferMeasurement(value, attributes_, context_); + value += 0.001; + } + + benchmark::DoNotOptimize(value); + state.SetItemsProcessed(state.iterations()); +} + +BENCHMARK_REGISTER_F(SharedSimpleFixedSizeExemplarReservoirFixture, OfferMeasurement) + ->ThreadRange(1, 8) + ->UseRealTime() + ->Unit(benchmark::kNanosecond); + +} // namespace + +BENCHMARK_MAIN(); + +#endif // ENABLE_METRICS_EXEMPLAR_PREVIEW From ee3c93e740c4845cab2ec35ba9cfc878a05ad6d5 Mon Sep 17 00:00:00 2001 From: proost Date: Sat, 22 Aug 2026 00:46:33 +0900 Subject: [PATCH 5/5] test: add preview benchmark --- bazel/otel_cc_benchmark.bzl | 6 +++--- sdk/test/metrics/exemplar/BUILD | 3 ++- sdk/test/metrics/exemplar/CMakeLists.txt | 2 +- .../exemplar/fixed_size_exemplar_reservoir_benchmark.cc | 9 ++++++--- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/bazel/otel_cc_benchmark.bzl b/bazel/otel_cc_benchmark.bzl index dd95103d0a..bae46fdcec 100644 --- a/bazel/otel_cc_benchmark.bzl +++ b/bazel/otel_cc_benchmark.bzl @@ -4,7 +4,7 @@ load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:cc_test.bzl", "cc_test") -def otel_cc_benchmark(name, srcs, deps, tags = [""]): +def otel_cc_benchmark(name, srcs, deps, tags = [""], defines = []): """ Creates targets for the benchmark and related targets. @@ -30,7 +30,7 @@ def otel_cc_benchmark(name, srcs, deps, tags = [""]): srcs = srcs, deps = deps + ["@com_github_google_benchmark//:benchmark"], tags = tags + ["manual"], - defines = ["BAZEL_BUILD"], + defines = ["BAZEL_BUILD"] + defines, ) # The result of running the benchmark, captured into a text file. @@ -51,5 +51,5 @@ def otel_cc_benchmark(name, srcs, deps, tags = [""]): deps = deps + ["@com_github_google_benchmark//:benchmark"], args = ["--benchmark_min_time=1x"], tags = tags + ["benchmark"], - defines = ["BAZEL_BUILD"], + defines = ["BAZEL_BUILD"] + defines, ) diff --git a/sdk/test/metrics/exemplar/BUILD b/sdk/test/metrics/exemplar/BUILD index b8af58e15d..b6a3306fd7 100644 --- a/sdk/test/metrics/exemplar/BUILD +++ b/sdk/test/metrics/exemplar/BUILD @@ -9,6 +9,7 @@ otel_cc_benchmark( srcs = [ "fixed_size_exemplar_reservoir_benchmark.cc", ], + defines = ["ENABLE_METRICS_EXEMPLAR_PREVIEW"], tags = [ "benchmark", "metrics", @@ -17,7 +18,7 @@ otel_cc_benchmark( deps = [ "//api", "//sdk:headers", - "//sdk/src/metrics", + "//sdk/src/common:random", ], ) diff --git a/sdk/test/metrics/exemplar/CMakeLists.txt b/sdk/test/metrics/exemplar/CMakeLists.txt index 849e9ec337..b28134f2ff 100644 --- a/sdk/test/metrics/exemplar/CMakeLists.txt +++ b/sdk/test/metrics/exemplar/CMakeLists.txt @@ -6,7 +6,7 @@ if(WITH_BENCHMARK) fixed_size_exemplar_reservoir_benchmark.cc) target_link_libraries( fixed_size_exemplar_reservoir_benchmark benchmark::benchmark - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_common) endif() foreach( diff --git a/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc index 1b2961d6d0..ed04a6630b 100644 --- a/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc +++ b/sdk/test/metrics/exemplar/fixed_size_exemplar_reservoir_benchmark.cc @@ -28,6 +28,9 @@ using opentelemetry::sdk::metrics::SimpleFixedSizeExemplarReservoir; class SharedSimpleFixedSizeExemplarReservoirFixture : public benchmark::Fixture { public: + using benchmark::Fixture::SetUp; + using benchmark::Fixture::TearDown; + void SetUp(benchmark::State &state) override { if (state.thread_index() != 0) @@ -35,9 +38,9 @@ class SharedSimpleFixedSizeExemplarReservoirFixture : public benchmark::Fixture return; } - reservoir_ = ExemplarReservoir::GetSimpleFixedSizeExemplarReservoir( - 1, SimpleFixedSizeExemplarReservoir::GetSimpleFixedSizeCellSelector(1), - &ReservoirCell::GetAndResetDouble); + auto selector = SimpleFixedSizeExemplarReservoir::GetSimpleFixedSizeCellSelector(1); + reservoir_ = shared_ptr{ + new SimpleFixedSizeExemplarReservoir{1, selector, &ReservoirCell::GetAndResetDouble}}; // Model a reservoir partway through a normal collection interval. This // keeps the benchmark focused on the steady-state offer path.