From 8f7d29b4034f27e1f3788b0be02971289a1e6f8e Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Thu, 17 Feb 2022 17:31:45 -0800 Subject: [PATCH 1/8] Add an option for multi-instrument callbacks --- CHANGELOG.md | 1 + specification/metrics/api.md | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae1cd8d2b6..85d7c2d8d64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ release. - Introduce the concept of Instrumentation Scope to replace/extend Instrumentation Library. The Meter is now associated with Instrumentation Scope ([#2276](https://github.com/open-telemetry/opentelemetry-specification/pull/2276)). +- Add optional API support for multi-instrument callbacks. ### Logs diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 4af98ad46b7..5ca841cfd52 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -36,6 +36,7 @@ + [Asynchronous UpDownCounter creation](#asynchronous-updowncounter-creation) + [Asynchronous UpDownCounter operations](#asynchronous-updowncounter-operations) - [Measurement](#measurement) + * [Multiple-instrument callbacks](#multiple-instrument-callbacks) - [Compatibility requirements](#compatibility-requirements) - [Concurrency requirements](#concurrency-requirements) @@ -321,6 +322,12 @@ instrument callbacks. The resulting behavior when a callback observes multiple values for identical instrument and attributes is explicitly not specified. +Where idiomatic, a secondary callback API MAY be provided that enables +the use of multiple asynchronous instruments from individual +callbacks. When registering callbacks associated with multiple +instruments, the API MUST make the association between instruments and +callbacks explicit. See the [Multiple-instrument callbacks](#multiple-instrument-callbacks) section below. + ### Counter `Counter` is a [synchronous Instrument](#synchronous-instrument) which supports @@ -1108,6 +1115,47 @@ for the interaction between the API and SDK. * A value * [`Attributes`](../common/common.md#attributes) +### Multiple-instrument callbacks + +Where idiomatic, [the Metrics API supports an option to use multiple +instruments from a single registered +callback](#asynchronous-instrument). The key requirement for the API +is that the association between Callbacks and Instruments be explicit +so that the SDK knows which callbacks to execute when observing +specific instruments. + +Some suggestions for the API author: + +* the Observable result used in multi-instrument callbacks receives an + additional instrument argument +* asynchronous instruments have an `Observe()` method that can be used + from appropriately registered callbacks. + +This interface is typically a more performant way to report multiple +measurements when they are obtained through an expensive process, such +as reading `/proc` files or probing the garbage collection subsystem. + +For example, + +```Python +# Python +class Device: + """A device with two instruments""" + + def __init__(self, meter, proeprty): + self.property = property + self.usage = meter.create_observable_counter(name="usage", description="count of items used") + self.pressure = meter.create_observable_gauge(name="pressure", description="force per unit area") + + # Note the two associated instruments are passed to the callback. + meter.register_callback([self.usage, self.pressure], self.observe) + + def observe(self, result): + usage, pressure = expensive_system_call() + self.usage.observe(result, usage, {'property', self.property}) + self.pressure.observe(result, pressure, {'property', self.property}) +``` + ## Compatibility requirements All the metrics components SHOULD allow new APIs to be added to From 07569a3597ff6f60ae01345fca81ade18a685184 Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Thu, 17 Feb 2022 17:33:36 -0800 Subject: [PATCH 2/8] PR num --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85d7c2d8d64..4c0c6ffed91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ release. Library. The Meter is now associated with Instrumentation Scope ([#2276](https://github.com/open-telemetry/opentelemetry-specification/pull/2276)). - Add optional API support for multi-instrument callbacks. + ([#2263](https://github.com/open-telemetry/opentelemetry-specification/pull/2263)). ### Logs From 9cfcaad1cc100cab934b23e734aac59a8417d69e Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Tue, 1 Mar 2022 15:38:31 -0800 Subject: [PATCH 3/8] draft --- specification/metrics/api.md | 45 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index db162a1020f..d0c74b96b7a 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -338,19 +338,27 @@ The API to construct asynchronous instruments MUST accept the following paramete rule](#instrument-unit). * An optional `description`, following the [instrument description rule](#instrument-description). -* Zero or more `callback` functions. +* Zero or more `callback` functions, responsible for reporting + [Measurement](#measurement) values of the created instrument. The API MUST support creation of asynchronous instruments by passing -zero or more callback functions to be permanently registered to the +zero or more `callback` functions to be permanently registered to the newly created instrument. -The API SHOULD support registration of callback functions to +The API SHOULD support registration of `callback` functions associated with asynchronous instruments after they are created. -Where the API supports registration of callback functions after +Where the API supports registration of `callback` functions after asynchronous instrumentation creation, it MUST return something (e.g., a registration handle, receipt or token) to the user that supports -undoing the effect of callback registation. +undoing the effect of `callback` registation. + +A Callback is the conceptual entity created each time a `callback` +function is registered through an OpenTelemetry API. + +Every currently registered Callback associated with an instrument MUST +be evaluted exactly once during collection prior to reading data for +that instrument. Callback functions MUST be documented as follows for the end user: @@ -364,20 +372,27 @@ Callback functions MUST be documented as follows for the end user: The resulting behavior when a callback violates any of these RECOMMENDATIONS is explicitly not specified at the API level. -Where idiomatic, a secondary callback API MAY be provided that enables -the use of multiple asynchronous instruments from individual -callbacks. When registering callbacks associated with multiple -instruments, the API MUST make the association between instruments and -callbacks explicit. See the [Multiple-instrument callbacks](#multiple-instrument-callbacks) section below. - [OpenTelemetry API](../overview.md#api) authors MAY decide what is the idiomatic approach for capturing measurements from callback functions. Here are some examples: -* Return a list (or tuple, generator, enumerator, etc.) of `Measurement`s. -* Use an observable result argument to allow individual `Measurement`s to be - reported. +* Return a list (or tuple, generator, enumerator, etc.) of individual + `Measurement` values. +* Pass an *Observable Result* as a formal parameter of the callback, + where `result.Observe()` captures individual `Measurement` values. + +Callbacks registered at the time of instrument creation MUST apply to +the single instruments which is under construction. + +Callbacks registered after the time of instrument creation MAY be +associated with multiple instruments. + +Idiomatic APIs for multiple-instrument Callbacks MUST distinguish the +instrument associated with each observed `Measurement` value. + +Multiple-instrument Callbacks MUST be associated with a pre-determined +set of asynchronous instruments from the same `Meter` instance. -The API MUST treat observations from a single callback as logically +The API MUST treat observations from a single Callback as logically taking place at a single instant, such that when recorded, observations from a single callback MUST be reported with identical timestamps. From be29eb7955ae598acf5746a5853bd98e1f32541c Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Wed, 2 Mar 2022 12:35:28 -0800 Subject: [PATCH 4/8] rephase multi-inst section --- specification/metrics/api.md | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index d0c74b96b7a..60edcdda738 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -389,8 +389,12 @@ associated with multiple instruments. Idiomatic APIs for multiple-instrument Callbacks MUST distinguish the instrument associated with each observed `Measurement` value. -Multiple-instrument Callbacks MUST be associated with a pre-determined -set of asynchronous instruments from the same `Meter` instance. +Multiple-instrument Callbacks MUST be associated at the time of +registration with a declared set of asynchronous instruments from the +same `Meter` instance. This REQUIREMENT that Instruments be +declaratively associated with Callbacks allows an SDK to execute only +those Callbacks that are necessary to evaluate instruments that are in +use by a configured [View](sdk.md#view). The API MUST treat observations from a single Callback as logically taking place at a single instant, such that when recorded, @@ -1087,19 +1091,21 @@ for the interaction between the API and SDK. ### Multiple-instrument callbacks -Where idiomatic, [the Metrics API supports an option to use multiple +[The Metrics API MAY support an interface allowing the use of multiple instruments from a single registered -callback](#asynchronous-instrument). The key requirement for the API -is that the association between Callbacks and Instruments be explicit -so that the SDK knows which callbacks to execute when observing -specific instruments. +Callback](#asynchronous-instrument-api). The API to register a new +Callback SHOULD accept: -Some suggestions for the API author: +- A `callback` function +- A list (or tuple, etc.) of Instruments used in the `callback` function. -* the Observable result used in multi-instrument callbacks receives an - additional instrument argument -* asynchronous instruments have an `Observe()` method that can be used - from appropriately registered callbacks. +It is RECOMMENDED that the API authors use one of the following forms +for the `callback` function: + +* The list (or tuple, etc.) returned by the `callback` function + contains `(Instrument, Measurement)` pairs. +* the Observable Result parameter receives an additional `(Instrument, + Measurement)` pairs This interface is typically a more performant way to report multiple measurements when they are obtained through an expensive process, such From a7a08e11e7a5988adf9dc83f11bd57c0e5110c6f Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Wed, 2 Mar 2022 12:36:16 -0800 Subject: [PATCH 5/8] re-order example API to match single-instrument observable result --- specification/metrics/api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 60edcdda738..9bbd5fa2d13 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -1128,8 +1128,8 @@ class Device: def observe(self, result): usage, pressure = expensive_system_call() - self.usage.observe(result, usage, {'property', self.property}) - self.pressure.observe(result, pressure, {'property', self.property}) + result.observe(self.usage, usage, {'property', self.property}) + result.observe(self.pressure, pressure, {'property', self.property}) ``` ## Compatibility requirements From 5d2a3f210e2107ea46397c9002ffdcf6be1a0dce Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Fri, 1 Apr 2022 13:14:50 -0700 Subject: [PATCH 6/8] Update specification/metrics/api.md Co-authored-by: Diego Hurtado --- specification/metrics/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 9bbd5fa2d13..3d1b643b17b 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -391,7 +391,7 @@ instrument associated with each observed `Measurement` value. Multiple-instrument Callbacks MUST be associated at the time of registration with a declared set of asynchronous instruments from the -same `Meter` instance. This REQUIREMENT that Instruments be +same `Meter` instance. This requirement that Instruments be declaratively associated with Callbacks allows an SDK to execute only those Callbacks that are necessary to evaluate instruments that are in use by a configured [View](sdk.md#view). From 29d21e5d7865eebda0eddc7634fd3cbd3e3ae1b6 Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Fri, 1 Apr 2022 14:12:34 -0700 Subject: [PATCH 7/8] edits --- specification/metrics/api.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 3d1b643b17b..2533aa2687d 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -345,16 +345,15 @@ The API MUST support creation of asynchronous instruments by passing zero or more `callback` functions to be permanently registered to the newly created instrument. +A Callback is the conceptual entity created each time a `callback` +function is registered through an OpenTelemetry API. + The API SHOULD support registration of `callback` functions associated with asynchronous instruments after they are created. Where the API supports registration of `callback` functions after -asynchronous instrumentation creation, it MUST return something (e.g., -a registration handle, receipt or token) to the user that supports -undoing the effect of `callback` registation. - -A Callback is the conceptual entity created each time a `callback` -function is registered through an OpenTelemetry API. +asynchronous instrumentation creation, the user MUST be able to undo +registration of the specific callback after its registration somehow. Every currently registered Callback associated with an instrument MUST be evaluted exactly once during collection prior to reading data for From 80191b0a7a462c016eca78ce28acbdd5e1f3dc41 Mon Sep 17 00:00:00 2001 From: Joshua MacDonald Date: Mon, 4 Apr 2022 10:27:50 -0700 Subject: [PATCH 8/8] edit --- specification/metrics/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 2533aa2687d..31a31507434 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -353,7 +353,7 @@ asynchronous instruments after they are created. Where the API supports registration of `callback` functions after asynchronous instrumentation creation, the user MUST be able to undo -registration of the specific callback after its registration somehow. +registration of the specific callback after its registration by some means. Every currently registered Callback associated with an instrument MUST be evaluted exactly once during collection prior to reading data for