Skip to content

Commit 7bc61db

Browse files
authored
Merge branch 'main' into fix_lifetime_in_log_record
2 parents bada7dc + 4e4d8de commit 7bc61db

File tree

9 files changed

+238
-75
lines changed

9 files changed

+238
-75
lines changed

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ jobs:
3939
sudo -E ./ci/setup_googletest.sh
4040
sudo -E ./ci/setup_ci_environment.sh
4141
- name: Initialize CodeQL
42-
uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
42+
uses: github/codeql-action/init@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
4343
with:
4444
languages: cpp
4545
- name: Autobuild
46-
uses: github/codeql-action/autobuild@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
46+
uses: github/codeql-action/autobuild@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
4747
- name: Perform CodeQL Analysis
48-
uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
48+
uses: github/codeql-action/analyze@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17

.github/workflows/ossf-scorecard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ jobs:
4747
# Upload the results to GitHub's code scanning dashboard (optional).
4848
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
4949
- name: "Upload to code-scanning"
50-
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3.28.16
50+
uses: github/codeql-action/upload-sarif@60168efe1c415ce0f5521ea06d5c2062adbeed1b # v3.28.17
5151
with:
5252
sarif_file: results.sarif

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Increment the:
1515

1616
## [Unreleased]
1717

18+
* [Metrics SDK] Use nostd::function_ref in AttributesHashMap
19+
[#3393](https://github.com/open-telemetry/opentelemetry-cpp/pull/3393)
20+
1821
* [SDK] Base2 exponential histogram aggregation
1922
[#3175](https://github.com/open-telemetry/opentelemetry-cpp/pull/3346)
2023

@@ -33,6 +36,10 @@ Increment the:
3336
* [API] Add Enabled method to Tracer
3437
[#3357](https://github.com/open-telemetry/opentelemetry-cpp/pull/3357)
3538

39+
40+
* [SDK] Optimize PeriodicExportingMetricReader thread usage
41+
[#3383](https://github.com/open-telemetry/opentelemetry-cpp/pull/3383)
42+
3643
* [SDK] Fix lifetime for sdk::ReadWriteLogRecord
3744
[#3147](https://github.com/open-telemetry/opentelemetry-cpp/pull/3245)
3845

@@ -49,6 +56,7 @@ Important changes:
4956
`const opentelemetry::sdk::common::OwnedAttributeValue &` instead of a
5057
`const opentelemetry::common::AttributeValue &`.
5158

59+
5260
## [1.20 2025-04-01]
5361

5462
* [BUILD] Update opentelemetry-proto version

sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ class AttributesHashMapWithCustomHash
7474
* If not present, it uses the provided callback to generate
7575
* value and store in the hash
7676
*/
77-
Aggregation *GetOrSetDefault(const opentelemetry::common::KeyValueIterable &attributes,
78-
const AttributesProcessor *attributes_processor,
79-
std::function<std::unique_ptr<Aggregation>()> aggregation_callback)
77+
Aggregation *GetOrSetDefault(
78+
const opentelemetry::common::KeyValueIterable &attributes,
79+
const AttributesProcessor *attributes_processor,
80+
nostd::function_ref<std::unique_ptr<Aggregation>()> aggregation_callback)
8081
{
8182
// TODO: avoid constructing MetricAttributes from KeyValueIterable for
8283
// hash_map_.find which is a heavy operation
@@ -97,8 +98,9 @@ class AttributesHashMapWithCustomHash
9798
return result.first->second.get();
9899
}
99100

100-
Aggregation *GetOrSetDefault(const MetricAttributes &attributes,
101-
std::function<std::unique_ptr<Aggregation>()> aggregation_callback)
101+
Aggregation *GetOrSetDefault(
102+
const MetricAttributes &attributes,
103+
nostd::function_ref<std::unique_ptr<Aggregation>()> aggregation_callback)
102104
{
103105
auto it = hash_map_.find(attributes);
104106
if (it != hash_map_.end())
@@ -115,8 +117,9 @@ class AttributesHashMapWithCustomHash
115117
return hash_map_[attributes].get();
116118
}
117119

118-
Aggregation *GetOrSetDefault(MetricAttributes &&attributes,
119-
std::function<std::unique_ptr<Aggregation>()> aggregation_callback)
120+
Aggregation *GetOrSetDefault(
121+
MetricAttributes &&attributes,
122+
nostd::function_ref<std::unique_ptr<Aggregation>()> aggregation_callback)
120123
{
121124
auto it = hash_map_.find(attributes);
122125
if (it != hash_map_.end())
@@ -207,7 +210,7 @@ class AttributesHashMapWithCustomHash
207210
size_t attributes_limit_;
208211

209212
Aggregation *GetOrSetOveflowAttributes(
210-
std::function<std::unique_ptr<Aggregation>()> aggregation_callback)
213+
nostd::function_ref<std::unique_ptr<Aggregation>()> aggregation_callback)
211214
{
212215
auto agg = aggregation_callback();
213216
return GetOrSetOveflowAttributes(std::move(agg));

sdk/src/metrics/export/periodic_exporting_metric_reader.cc

Lines changed: 23 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <ostream>
1111
#include <ratio>
1212
#include <thread>
13-
#include <type_traits>
1413
#include <utility>
1514

1615
#include "opentelemetry/common/timestamp.h"
@@ -24,13 +23,6 @@
2423
#include "opentelemetry/sdk/metrics/push_metric_exporter.h"
2524
#include "opentelemetry/version.h"
2625

27-
#if defined(_MSC_VER)
28-
# pragma warning(suppress : 5204)
29-
# include <future>
30-
#else
31-
# include <future>
32-
#endif
33-
3426
#if OPENTELEMETRY_HAVE_EXCEPTIONS
3527
# include <exception>
3628
#endif
@@ -98,11 +90,9 @@ void PeriodicExportingMetricReader::DoBackgroundWork()
9890
worker_thread_instrumentation_->OnStart();
9991
}
10092
#endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
101-
10293
do
10394
{
10495
auto start = std::chrono::steady_clock::now();
105-
10696
#ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
10797
if (worker_thread_instrumentation_ != nullptr)
10898
{
@@ -134,7 +124,6 @@ void PeriodicExportingMetricReader::DoBackgroundWork()
134124
worker_thread_instrumentation_->BeforeWait();
135125
}
136126
#endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
137-
138127
std::unique_lock<std::mutex> lk(cv_m_);
139128
cv_.wait_for(lk, remaining_wait_interval_ms, [this]() {
140129
if (is_force_wakeup_background_worker_.load(std::memory_order_acquire))
@@ -151,7 +140,6 @@ void PeriodicExportingMetricReader::DoBackgroundWork()
151140
worker_thread_instrumentation_->AfterWait();
152141
}
153142
#endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
154-
155143
} while (IsShutdown() != true);
156144

157145
#ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
@@ -164,61 +152,39 @@ void PeriodicExportingMetricReader::DoBackgroundWork()
164152

165153
bool PeriodicExportingMetricReader::CollectAndExportOnce()
166154
{
167-
std::atomic<bool> cancel_export_for_timeout{false};
168-
169155
std::uint64_t notify_force_flush = force_flush_pending_sequence_.load(std::memory_order_acquire);
170-
std::unique_ptr<std::thread> task_thread;
171-
172156
#if OPENTELEMETRY_HAVE_EXCEPTIONS
173157
try
174158
{
175159
#endif
176-
std::promise<void> sender;
177-
auto receiver = sender.get_future();
178-
179-
task_thread.reset(
180-
new std::thread([this, &cancel_export_for_timeout, sender = std::move(sender)] {
181160
#ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
182-
if (collect_thread_instrumentation_ != nullptr)
183-
{
184-
collect_thread_instrumentation_->OnStart();
185-
collect_thread_instrumentation_->BeforeLoad();
186-
}
161+
if (collect_thread_instrumentation_ != nullptr)
162+
{
163+
collect_thread_instrumentation_->OnStart();
164+
collect_thread_instrumentation_->BeforeLoad();
165+
}
187166
#endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
188-
189-
this->Collect([this, &cancel_export_for_timeout](ResourceMetrics &metric_data) {
190-
if (cancel_export_for_timeout.load(std::memory_order_acquire))
191-
{
192-
OTEL_INTERNAL_LOG_ERROR(
193-
"[Periodic Exporting Metric Reader] Collect took longer configured time: "
194-
<< this->export_timeout_millis_.count() << " ms, and timed out");
195-
return false;
196-
}
197-
this->exporter_->Export(metric_data);
198-
return true;
199-
});
200-
201-
const_cast<std::promise<void> &>(sender).set_value();
167+
auto start = std::chrono::steady_clock::now();
168+
this->Collect([this, &start](ResourceMetrics &metric_data) {
169+
auto end = std::chrono::steady_clock::now();
170+
if ((end - start) > this->export_timeout_millis_)
171+
{
172+
OTEL_INTERNAL_LOG_ERROR(
173+
"[Periodic Exporting Metric Reader] Collect took longer configured time: "
174+
<< this->export_timeout_millis_.count() << " ms, and timed out");
175+
return false;
176+
}
177+
this->exporter_->Export(metric_data);
178+
return true;
179+
});
202180

203181
#ifdef ENABLE_THREAD_INSTRUMENTATION_PREVIEW
204-
if (collect_thread_instrumentation_ != nullptr)
205-
{
206-
collect_thread_instrumentation_->AfterLoad();
207-
collect_thread_instrumentation_->OnEnd();
208-
}
209-
#endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
210-
}));
211-
212-
std::future_status status;
213-
do
182+
if (collect_thread_instrumentation_ != nullptr)
214183
{
215-
status = receiver.wait_for(std::chrono::milliseconds(export_timeout_millis_));
216-
if (status == std::future_status::timeout)
217-
{
218-
cancel_export_for_timeout.store(true, std::memory_order_release);
219-
break;
220-
}
221-
} while (status != std::future_status::ready);
184+
collect_thread_instrumentation_->AfterLoad();
185+
collect_thread_instrumentation_->OnEnd();
186+
}
187+
#endif /* ENABLE_THREAD_INSTRUMENTATION_PREVIEW */
222188
#if OPENTELEMETRY_HAVE_EXCEPTIONS
223189
}
224190
catch (std::exception &e)
@@ -235,11 +201,6 @@ bool PeriodicExportingMetricReader::CollectAndExportOnce()
235201
}
236202
#endif
237203

238-
if (task_thread && task_thread->joinable())
239-
{
240-
task_thread->join();
241-
}
242-
243204
std::uint64_t notified_sequence = force_flush_notified_sequence_.load(std::memory_order_acquire);
244205
while (notify_force_flush > notified_sequence)
245206
{

sdk/test/metrics/BUILD

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,23 @@ cc_test(
4949
],
5050
)
5151

52+
cc_test(
53+
name = "stress_tests",
54+
timeout = "long",
55+
srcs = glob(["*_test_stress.cc"]),
56+
copts = [
57+
"-DUNIT_TESTING",
58+
],
59+
tags = [
60+
"metrics",
61+
"test",
62+
],
63+
deps = [
64+
"metrics_common_test_utils",
65+
"@com_google_googletest//:gtest_main",
66+
],
67+
)
68+
5269
otel_cc_benchmark(
5370
name = "attributes_processor_benchmark",
5471
srcs = [

sdk/test/metrics/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ foreach(
3333
metric_reader_test
3434
observable_registry_test
3535
periodic_exporting_metric_reader_test
36-
instrument_metadata_validator_test)
36+
instrument_metadata_validator_test
37+
metric_test_stress)
3738
add_executable(${testname} "${testname}.cc")
3839
target_link_libraries(
3940
${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}

sdk/test/metrics/attributes_hashmap_benchmark.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <thread>
1212
#include <vector>
1313

14+
#include "opentelemetry/nostd/function_ref.h"
1415
#include "opentelemetry/sdk/metrics/aggregation/aggregation.h"
1516
#include "opentelemetry/sdk/metrics/aggregation/drop_aggregation.h"
1617
#include "opentelemetry/sdk/metrics/state/attributes_hashmap.h"

0 commit comments

Comments
 (0)