Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0209a3d
[SDK] Support MeterConfigurator updates and example
adityabavadekar Jul 27, 2026
cb51dcd
Merge branch 'main' into add_meter_configurator_update
adityabavadekar Jul 28, 2026
ab71694
Fixing ci build errors
adityabavadekar Jul 28, 2026
19936ab
Merge branch 'main' into add_meter_configurator_update
adityabavadekar Jul 28, 2026
805a57f
[SDK] Address review feedback on MeterConfigurator updates
adityabavadekar Aug 19, 2026
6ab48d0
Merge branch 'main' into add_meter_configurator_update
dbarker Aug 25, 2026
de1103e
Merge branch 'main' into add_meter_configurator_update
dbarker Aug 30, 2026
72dcda8
Merge branch 'main' into add_meter_configurator_update
dbarker Aug 31, 2026
594ddfe
Merge branch 'main' into add_meter_configurator_update
dbarker Sep 11, 2026
cb99048
[SDK] Support meter re-enabling for bound metric handles
adityabavadekar Sep 11, 2026
0c31e6b
[SDK] Fix include-what-you-use and clang-tidy diagnostics
adityabavadekar Sep 12, 2026
3698bbb
Merge branch 'main' into add_meter_configurator_update
adityabavadekar Sep 20, 2026
b2194c5
[SDK] Fix include-what-you-use diagnostics
adityabavadekar Sep 20, 2026
db44782
[CHANGELOG] Fix the Unreleased entry for this change
adityabavadekar Sep 21, 2026
7ee466e
Merge branch 'main' into add_meter_configurator_update
adityabavadekar Sep 21, 2026
e837c7b
Merge branch 'main' into add_meter_configurator_update
dbarker Sep 22, 2026
73d225b
Merge branch 'main' into add_meter_configurator_update
dbarker Sep 27, 2026
ea6d6dc
Address review feedback on meter enabled state
adityabavadekar Oct 6, 2026
69abbab
Merge branch 'main' into add_meter_configurator_update
adityabavadekar Oct 6, 2026
76c3f70
Merge branch 'main' into add_meter_configurator_update
dbarker Oct 9, 2026
4e1a5d5
Apply batched suggestions from code review
marcalff Oct 10, 2026
b69f445
Apply batched suggestions from code review
marcalff Oct 10, 2026
b2e1b52
Apply suggestion from @marcalff
marcalff Oct 10, 2026
520322d
Merge branch 'main' into add_meter_configurator_update
marcalff Oct 10, 2026
fb8dda3
Apply batched suggestions from code review
marcalff Oct 11, 2026
d2fd244
Apply batched suggestions from code review
marcalff Oct 11, 2026
22e5761
Merge branch 'main' into add_meter_configurator_update
marcalff Oct 11, 2026
120f23c
Apply batched suggestions from code review
marcalff Oct 11, 2026
504882c
Merge branch 'main' into add_meter_configurator_update
marcalff Oct 11, 2026
e180a74
Merge branch 'main' into add_meter_configurator_update
dbarker Oct 14, 2026
bb593af
Merge remote-tracking branch 'upstream/main' into add_meter_configura…
adityabavadekar Oct 17, 2026
93930f1
Check values are not recorded when meter is disabled
adityabavadekar Oct 17, 2026
8c4c270
Merge branch 'main' into add_meter_configurator_update
dbarker Oct 18, 2026
4e69db2
Fix test build on older GCC
adityabavadekar Oct 20, 2026
86b8516
Merge branch 'main' into add_meter_configurator_update
adityabavadekar Oct 20, 2026
4c237ef
Merge branch 'main' into add_meter_configurator_update
marcalff Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ Increment the:
[#4573](https://github.com/open-telemetry/opentelemetry-cpp/pull/4573)
* [API] Remove regex from trace_state.h
[#4570](https://github.com/open-telemetry/opentelemetry-cpp/pull/4570)
* [SDK] Add `MeterProvider::UpdateMeterConfigurator()` and example. Instruments
observe the enabled state of the Meter that created them, so they do not
have to be recreated. Data recorded before a Meter is disabled is still
exported
[#4313](https://github.com/open-telemetry/opentelemetry-cpp/pull/4313)

* [API] `TraceState::Set` now overwrites an entry with the same key, and
`TraceState::FromHeader` discards duplicate keys.
Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_subdirectory(multi_processor)
add_subdirectory(environment_carrier)
add_subdirectory(tracer_configurator)
add_subdirectory(logger_configurator)
add_subdirectory(meter_configurator)
add_subdirectory(explicit_parent)

if(OTELCPP_WITH_EXAMPLES_HTTP)
Expand Down
2 changes: 0 additions & 2 deletions examples/logger_configurator/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
#include <thread>
#include <utility>

#include <string>
#include <vector>
#include "opentelemetry/sdk/logs/exporter.h"
#include "opentelemetry/sdk/logs/processor.h"

Expand Down
20 changes: 20 additions & 0 deletions examples/meter_configurator/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

load("@rules_cc//cc:cc_test.bzl", "cc_test")

cc_test(
name = "example_meter_configurator",
srcs = [
"main.cc",
],
tags = [
"ostream",
"tested_example",
],
deps = [
"//api",
"//exporters/ostream:ostream_metric_exporter",
"//sdk/src/metrics",
],
)
13 changes: 13 additions & 0 deletions examples/meter_configurator/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

add_executable(example_meter_configurator main.cc)
target_link_libraries(
example_meter_configurator
PRIVATE opentelemetry-cpp::metrics
opentelemetry-cpp::ostream_metrics_exporter)

if(BUILD_TESTING)
add_test(NAME examples.meter_configurator
COMMAND "$<TARGET_FILE:example_meter_configurator>")
endif()
291 changes: 291 additions & 0 deletions examples/meter_configurator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
# Meter Configurator Example

This example demonstrates how to set a `MeterConfigurator` on construction
of the `MeterProvider` and to update it at runtime using
`MeterProvider::UpdateMeterConfigurator` to enable or disable specific
meters without restarting the application or recreating the meters.

`MeterProvider::UpdateMeterConfigurator` recomputes and applies a new
`MeterConfig` to all existing meters, and the updated configurator is also
used for meters created afterwards. It is safe to call concurrently with
`MeterProvider::GetMeter` and with instrument creation and recording on
existing meters.

Three meters with unique instrumentation scope names are used to simulate
a user application:

- `my_application`: simulated user application
- `my_library`: simulated user library
- `external_library`: simulated external third-party library

The example walks through a simulated cost management and debugging
workflow in four stages:

- Stage 1: Startup. All meters are enabled and all three scopes report
metrics.
- Stage 2: Steady state. The noisy `external_library` metrics are not
needed, so its meter is disabled.
- Stage 3: A user reports unexpected behavior. Re-enable the
`external_library` meter to investigate.
- Stage 4: The investigation completes and the `external_library` meter is
disabled again.

Instruments observe the enabled state of the meter that created them, so
they do not need to be recreated after a configurator update. An instrument
created while its meter is disabled starts recording once the meter is
enabled, and stops again when the meter is disabled. This matters for
third-party instrumentation, which an application cannot force to rebuild
its instruments.

When a meter is disabled, new measurements are dropped and its asynchronous
callbacks are not called. Anything recorded before it was disabled is still
exported.

This example uses cumulative temporality, so while `external_library` is
disabled it keeps reporting its last total (`1` in stage 2, `2` in stage 4).
The measurement made during stage 2 is dropped, which is why stage 3 reports
`2` and not `3`.

## Build and run

```sh
~/build/examples/meter_configurator/example_meter_configurator
```

**Expected output:**

Metrics are exported to stdout via the `OStreamMetricExporter`. The example
calls `ForceFlush` at the end of each stage. The periodic reader also
collects once when it starts, so the exact number and ordering of exported
batches varies between runs; the transcript below shows one run and is not
an exact expected output.

```sh
Stage 1: startup, all meters enabled
my_application, my_library and external_library report metrics
{
scope name : my_application
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_application.work_items
description : Work items processed by the application
unit : {item}
type : SumPointData
value : 1
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : my_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_library.calls
description : Calls into the library
unit : {call}
type : SumPointData
value : 1
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : external_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : external_library.requests
description : Requests handled by the external library
unit : {request}
type : SumPointData
value : 1
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}

Stage 2: steady state, external_library meter disabled
external_library stops recording, its last value is still reported
{
scope name : my_application
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_application.work_items
description : Work items processed by the application
unit : {item}
type : SumPointData
value : 2
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : my_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_library.calls
description : Calls into the library
unit : {call}
type : SumPointData
value : 2
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : external_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : external_library.requests
description : Requests handled by the external library
unit : {request}
type : SumPointData
value : 1
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}

Stage 3: investigating, external_library meter re-enabled
external_library records again
{
scope name : my_application
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_application.work_items
description : Work items processed by the application
unit : {item}
type : SumPointData
value : 3
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : my_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_library.calls
description : Calls into the library
unit : {call}
type : SumPointData
value : 3
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : external_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : external_library.requests
description : Requests handled by the external library
unit : {request}
type : SumPointData
value : 2
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}

Stage 4: investigation complete, external_library meter disabled again
external_library stops recording, its last value is still reported
{
scope name : my_application
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_application.work_items
description : Work items processed by the application
unit : {item}
type : SumPointData
value : 4
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : my_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : my_library.calls
description : Calls into the library
unit : {call}
type : SumPointData
value : 4
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
{
scope name : external_library
schema url :
version :
start time : Mon Jul 27 09:32:35 2026
end time : Mon Jul 27 09:32:35 2026
instrument name : external_library.requests
description : Requests handled by the external library
unit : {request}
type : SumPointData
value : 2
attributes :
resources :
service.name: meter_configurator_example
telemetry.sdk.language: cpp
telemetry.sdk.name: opentelemetry
telemetry.sdk.version: 1.29.0-dev
}
```
Loading
Loading