From f8782a35e28eb497052c8d51a77ce8ad2909baee Mon Sep 17 00:00:00 2001 From: Reiley Yang Date: Thu, 16 Sep 2021 10:51:59 -0700 Subject: [PATCH] Improve the Metrics API/SDK spec wording --- specification/metrics/api.md | 176 +++++++++++++++++++---------------- specification/metrics/sdk.md | 45 ++++----- 2 files changed, 118 insertions(+), 103 deletions(-) diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 72034a15919..1fefb5e4a25 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -226,10 +226,10 @@ instrument. It MUST be treated as an opaque string from the API and SDK. * It MUST support [BMP (Unicode Plane 0)](https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane), which is basically only the first three bytes of UTF-8 (or `utf8mb3`). - Individual language clients can decide if they want to support more Unicode - [Planes](https://en.wikipedia.org/wiki/Plane_(Unicode)). -* It MUST support at least 1023 characters. Individual language clients can - decide if they want to support more. + [OpenTelemetry API](../overview.md#api) authors CAN decide if they want to + support more Unicode [Planes](https://en.wikipedia.org/wiki/Plane_(Unicode)). +* It MUST support at least 1023 characters. [OpenTelemetry + API](../overview.md#api) authors CAN decide if they want to support more. Instruments can be categorized based on whether they are synchronous or asynchronous: @@ -273,9 +273,9 @@ Example uses for `Counter`: There MUST NOT be any API for creating a `Counter` other than with a [`Meter`](#meter). This MAY be called `CreateCounter`. If strong type is -desired, the client can decide the language idiomatic name(s), for example -`CreateUInt64Counter`, `CreateDoubleCounter`, `CreateCounter`, -`CreateCounter`. +desired, [OpenTelemetry API](../overview.md#api) authors CAN decide the language +idiomatic name(s), for example `CreateUInt64Counter`, `CreateDoubleCounter`, +`CreateCounter`, `CreateCounter`. The API MUST accept the following parameters: @@ -286,7 +286,8 @@ The API MUST accept the following parameters: * An optional `description`, following the [instrument description rule](#instrument-description). -Here are some examples that individual language client might consider: +Here are some examples that [OpenTelemetry API](../overview.md#api) authors +might consider: ```python # Python @@ -322,15 +323,16 @@ Required parameters: * Optional [attributes](../common/common.md#attributes). * The increment amount, which MUST be a non-negative numeric value. -The client MAY decide to allow flexible +The [OpenTelemetry API](../overview.md#api) authors MAY decide to allow flexible [attributes](../common/common.md#attributes) to be passed in as arguments. If the attribute names and types are provided during the [counter -creation](#counter-creation), the client MAY allow attribute values to be passed -in using a more efficient way (e.g. strong typed struct allocated on the -callstack, tuple). The API MUST allow callers to provide flexible attributes at -invocation time rather than having to register all the possible attribute names -during the instrument creation. Here are some examples that individual language -client might consider: +creation](#counter-creation), the [OpenTelemetry API](../overview.md#api) +authors MAY allow attribute values to be passed in using a more efficient way +(e.g. strong typed struct allocated on the callstack, tuple). The API MUST allow +callers to provide flexible attributes at invocation time rather than having to +register all the possible attribute names during the instrument creation. Here +are some examples that [OpenTelemetry API](../overview.md#api) authors might +consider: ```python # Python @@ -366,9 +368,10 @@ Example uses for Asynchronous Counter: There MUST NOT be any API for creating an Asynchronous Counter other than with a [`Meter`](#meter). This MAY be called `CreateObservableCounter`. If strong type -is desired, the client can decide the language idiomatic name(s), for example -`CreateUInt64ObservableCounter`, `CreateDoubleObservableCounter`, -`CreateObservableCounter`, `CreateObservableCounter`. +is desired, [OpenTelemetry API](../overview.md#api) authors CAN decide the +language idiomatic name(s), for example `CreateUInt64ObservableCounter`, +`CreateDoubleObservableCounter`, `CreateObservableCounter`, +`CreateObservableCounter`. It is highly recommended that implementations use the name `ObservableCounter` (or any language idiomatic variation, e.g. `observable_counter`) unless there is @@ -389,8 +392,8 @@ The API MUST accept the following parameters: The `callback` function is responsible for reporting the [Measurement](#measurement)s. It will only be called when the Meter is being -observed. Individual language client SHOULD define whether this callback -function needs to be reentrant safe / thread safe or not. +observed. [OpenTelemetry API](../overview.md#api) authors SHOULD define whether +this callback function needs to be reentrant safe / thread safe or not. Note: Unlike [Counter.Add()](#add) which takes the increment/delta value, the callback function reports the absolute value of the counter. To determine the @@ -401,29 +404,31 @@ The callback function SHOULD NOT take indefinite amount of time. If multiple independent SDKs coexist in a running process, they MUST invoke the callback function(s) independently. -Individual language client can decide what is the idiomatic approach. Here are -some examples: +[OpenTelemetry API](../overview.md#api) authors CAN decide what is the idiomatic +approach. Here are some examples: * Return a list (or tuple, generator, enumerator, etc.) of `Measurement`s. * Use an observer argument to allow individual `Measurement`s to be reported. User code is recommended not to provide more than one `Measurement` with the -same `attributes` in a single callback. If it happens, the -[SDK](./README.md#sdk) can decide how to handle it. For example, during the -callback invocation if two measurements `value=1, attributes={pid:4, bitness:64}` -and `value=2, attributes={pid:4, bitness:64}` are reported, the SDK can decide -to simply let them pass through (so the downstream consumer can handle -duplication), drop the entire data, pick the last one, or something else. 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. - -The API SHOULD provide some way to pass `state` to the callback. Individual -language client can decide what is the idiomatic approach (e.g. it could be an -additional parameter to the callback function, or captured by the lambda -closure, or something else). - -Here are some examples that individual language client might consider: +same `attributes` in a single callback. If it happens, [OpenTelemetry +SDK](../overview.md#sdk) authors CAN decide how to handle it in the +[SDK](./README.md#sdk). For example, during the callback invocation if two +measurements `value=1, attributes={pid:4, bitness:64}` and `value=2, +attributes={pid:4, bitness:64}` are reported, [OpenTelemetry +SDK](../overview.md#sdk) authors CAN decide to simply let them pass through (so +the downstream consumer can handle duplication), drop the entire data, pick the +last one, or something else. 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. + +The API SHOULD provide some way to pass `state` to the callback. [OpenTelemetry +API](../overview.md#api) authors CAN decide what is the idiomatic approach (e.g. +it could be an additional parameter to the callback function, or captured by the +lambda closure, or something else). + +Here are some examples that [OpenTelemetry API](../overview.md#api) authors +might consider: ```python # Python @@ -487,9 +492,9 @@ Example uses for `Histogram`: There MUST NOT be any API for creating a `Histogram` other than with a [`Meter`](#meter). This MAY be called `CreateHistogram`. If strong type is -desired, the client can decide the language idiomatic name(s), for example -`CreateUInt64Histogram`, `CreateDoubleHistogram`, `CreateHistogram`, -`CreateHistogram`. +desired, [OpenTelemetry API](../overview.md#api) authors CAN decide the language +idiomatic name(s), for example `CreateUInt64Histogram`, `CreateDoubleHistogram`, +`CreateHistogram`, `CreateHistogram`. The API MUST accept the following parameters: @@ -500,7 +505,8 @@ The API MUST accept the following parameters: * An optional `description`, following the [instrument description rule](#instrument-description). -Here are some examples that individual language client might consider: +Here are some examples that [OpenTelemetry API](../overview.md#api) authors +might consider: ```python # Python @@ -536,11 +542,12 @@ Parameters: * The amount of the `Measurement`. * Optional [attributes](../common/common.md#attributes). -The client MAY decide to allow flexible +[OpenTelemetry API](../overview.md#api) authors MAY decide to allow flexible [attributes](../common/common.md#attributes) to be passed in as individual -arguments. The client MAY allow attribute values to be passed in using a more -efficient way (e.g. strong typed struct allocated on the callstack, tuple). Here -are some examples that individual language client might consider: +arguments. [OpenTelemetry API](../overview.md#api) authors MAY allow attribute +values to be passed in using a more efficient way (e.g. strong typed struct +allocated on the callstack, tuple). Here are some examples that [OpenTelemetry +API](../overview.md#api) authors might consider: ```python # Python @@ -577,9 +584,10 @@ Example uses for Asynchronous Gauge: There MUST NOT be any API for creating an Asynchronous Gauge other than with a [`Meter`](#meter). This MAY be called `CreateObservableGauge`. If strong type is -desired, the client can decide the language idiomatic name(s), for example -`CreateUInt64ObservableGauge`, `CreateDoubleObservableGauge`, -`CreateObservableGauge`, `CreateObservableGauge`. +desired, [OpenTelemetry API](../overview.md#api) authors CAN decide the language +idiomatic name(s), for example `CreateUInt64ObservableGauge`, +`CreateDoubleObservableGauge`, `CreateObservableGauge`, +`CreateObservableGauge`. It is highly recommended that implementations use the name `ObservableGauge` (or any language idiomatic variation, e.g. `observable_gauge`) unless there is @@ -600,15 +608,15 @@ The API MUST accept the following parameters: The `callback` function is responsible for reporting the [Measurement](#measurement)s. It will only be called when the Meter is being -observed. Individual language client SHOULD define whether this callback -function needs to be reentrant safe / thread safe or not. +observed. [OpenTelemetry API](../overview.md#api) authors SHOULD define whether +this callback function needs to be reentrant safe / thread safe or not. The callback function SHOULD NOT take indefinite amount of time. If multiple independent SDKs coexist in a running process, they MUST invoke the callback function(s) independently. -Individual language client can decide what is the idiomatic approach. Here are -some examples: +[OpenTelemetry API](../overview.md#api) authors CAN decide what is the idiomatic +approach. Here are some examples: * Return a list (or tuple, generator, enumerator, etc.) of `Measurement`s. * Use an observer result argument to allow individual `Measurement`s to be reported. @@ -620,16 +628,17 @@ callback invocation if two measurements `value=3.38, attributes={cpu:1, core:2}` and `value=3.51, attributes={cpu:1, core:2}` are reported, the SDK can decide to simply let them pass through (so the downstream consumer can handle duplication), drop the entire data, pick the last one, or something else. The -API must treat observations from a single callback as logically taking place at +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. -The API SHOULD provide some way to pass `state` to the callback. Individual -language client can decide what is the idiomatic approach (e.g. it could be an -additional parameter to the callback function, or captured by the lambda -closure, or something else). +The API SHOULD provide some way to pass `state` to the callback. [OpenTelemetry +API](../overview.md#api) authors CAN decide what is the idiomatic approach (e.g. +it could be an additional parameter to the callback function, or captured by the +lambda closure, or something else). -Here are some examples that individual language client might consider: +Here are some examples that [OpenTelemetry API](../overview.md#api) authors +might consider: ```python # Python @@ -756,9 +765,10 @@ def sell_item(color, material): There MUST NOT be any API for creating an `UpDownCounter` other than with a [`Meter`](#meter). This MAY be called `CreateUpDownCounter`. If strong type is -desired, the client can decide the language idiomatic name(s), for example -`CreateInt64UpDownCounter`, `CreateDoubleUpDownCounter`, -`CreateUpDownCounter`, `CreateUpDownCounter`. +desired, [OpenTelemetry API](../overview.md#api) authors CAN decide the language +idiomatic name(s), for example `CreateInt64UpDownCounter`, +`CreateDoubleUpDownCounter`, `CreateUpDownCounter`, +`CreateUpDownCounter`. The API MUST accept the following parameters: @@ -769,7 +779,8 @@ The API MUST accept the following parameters: * An optional `description`, following the [instrument description rule](#instrument-description). -Here are some examples that individual language client might consider: +Here are some examples that [OpenTelemetry API](../overview.md#api) authors +might consider: ```python # Python @@ -803,11 +814,12 @@ Parameters: * The amount to be added, can be positive, negative or zero. * Optional [attributes](../common/common.md#attributes). -The client MAY decide to allow flexible +[OpenTelemetry API](../overview.md#api) authors MAY decide to allow flexible [attributes](../common/common.md#attributes) to be passed in as individual -arguments. The client MAY allow attribute values to be passed in using a more -efficient way (e.g. strong typed struct allocated on the callstack, tuple). Here -are some examples that individual language client might consider: +arguments. [OpenTelemetry API](../overview.md#api) authors MAY allow attribute +values to be passed in using a more efficient way (e.g. strong typed struct +allocated on the callstack, tuple). Here are some examples that [OpenTelemetry +API](../overview.md#api) authors might consider: ```python # Python @@ -843,9 +855,10 @@ Example uses for Asynchronous UpDownCounter: There MUST NOT be any API for creating an Asynchronous UpDownCounter other than with a [`Meter`](#meter). This MAY be called `CreateObservableUpDownCounter`. If -strong type is desired, the client can decide the language idiomatic name(s), -for example `CreateUInt64ObservableUpDownCounter`, -`CreateDoubleObservableUpDownCounter`, `CreateObservableUpDownCounter`, +strong type is desired, [OpenTelemetry API](../overview.md#api) authors CAN +decide the language idiomatic name(s), for example +`CreateUInt64ObservableUpDownCounter`, `CreateDoubleObservableUpDownCounter`, +`CreateObservableUpDownCounter`, `CreateObservableUpDownCounter`. It is highly recommended that implementations use the name @@ -867,8 +880,8 @@ The API MUST accept the following parameters: The `callback` function is responsible for reporting the [Measurement](#measurement)s. It will only be called when the Meter is being -observed. Individual language client SHOULD define whether this callback -function needs to be reentrant safe / thread safe or not. +observed. [OpenTelemetry API](../overview.md#api) authors SHOULD define whether +this callback function needs to be reentrant safe / thread safe or not. Note: Unlike [UpDownCounter.Add()](#add) which takes the increment/delta value, the callback function reports the absolute value of the Asynchronous @@ -879,29 +892,30 @@ The callback function SHOULD NOT take indefinite amount of time. If multiple independent SDKs coexist in a running process, they MUST invoke the callback function(s) independently. -Individual language client can decide what is the idiomatic approach. Here are -some examples: +[OpenTelemetry API](../overview.md#api) authors CAN decide what is the idiomatic +approach. Here are some examples: * Return a list (or tuple, generator, enumerator, etc.) of `Measurement`s. * Use an observer argument to allow individual `Measurement`s to be reported. User code is recommended not to provide more than one `Measurement` with the same `attributes` in a single callback. If it happens, the -[SDK](./README.md#sdk) can decide how to handle it. For example, during the +[SDK](./README.md#sdk) CAN decide how to handle it. For example, during the callback invocation if two measurements `value=1, attributes={pid:4, bitness:64}` and `value=2, attributes={pid:4, bitness:64}` are reported, the SDK can decide to simply let them pass through (so the downstream consumer can handle duplication), drop the entire data, pick the last one, or something else. -The API must treat observations from a single callback as logically taking place +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. -The API SHOULD provide some way to pass `state` to the callback. Individual -language client can decide what is the idiomatic approach (e.g. it could be an -additional parameter to the callback function, or captured by the lambda -closure, or something else). +The API SHOULD provide some way to pass `state` to the callback. [OpenTelemetry +API](../overview.md#api) authors CAN decide what is the idiomatic approach (e.g. +it could be an additional parameter to the callback function, or captured by the +lambda closure, or something else). -Here are some examples that individual language client might consider: +Here are some examples that [OpenTelemetry API](../overview.md#api) authors +might consider: ```python # Python diff --git a/specification/metrics/sdk.md b/specification/metrics/sdk.md index 75b66129e69..ee1ddee6bd8 100644 --- a/specification/metrics/sdk.md +++ b/specification/metrics/sdk.md @@ -60,10 +60,10 @@ SHOULD return a valid no-op Meter for these calls, if possible. `Shutdown` SHOULD provide a way to let the caller know whether it succeeded, failed or timed out. -`Shutdown` SHOULD complete or abort within some timeout. `Shutdown` can be +`Shutdown` SHOULD complete or abort within some timeout. `Shutdown` CAN be implemented as a blocking API or an asynchronous API which notifies the caller -via a callback or an event. OpenTelemetry client authors can decide if they want -to make the shutdown timeout configurable. +via a callback or an event. [OpenTelemetry SDK](../overview.md#sdk) authors CAN +decide if they want to make the shutdown timeout configurable. `Shutdown` MUST be implemented at least by invoking `Shutdown` on all registered [MetricReader](#metricreader) and [MetricExporter](#metricexporter) instances. @@ -84,10 +84,10 @@ is an error condition; and if there is no error condition, it should return some **NO ERROR** status, language implementations MAY decide how to model **ERROR** and **NO ERROR**. -`ForceFlush` SHOULD complete or abort within some timeout. `ForceFlush` can be +`ForceFlush` SHOULD complete or abort within some timeout. `ForceFlush` CAN be implemented as a blocking API or an asynchronous API which notifies the caller -via a callback or an event. OpenTelemetry client authors can decide if they want -to make the flush timeout configurable. +via a callback or an event. [OpenTelemetry SDK](../overview.md#sdk) authors CAN +decide if they want to make the flush timeout configurable. `ForceFlush` MUST invoke `ForceFlush` on all registered [MetricReader](#metricreader) and [Push Metric Exporter](#push-metric-exporter) @@ -129,10 +129,10 @@ are the inputs: * The `name` of the Meter (optional). * The `version` of the Meter (optional). * The `schema_url` of the Meter (optional). - * Individual language client MAY choose to support more criteria. For example, - a strong typed language MAY support point type (e.g. allow the users to - select Instruments based on whether the underlying type is integer or - double). + * [OpenTelemetry SDK](../overview.md#sdk) authors MAY choose to support more + criteria. For example, a strong typed language MAY support point type (e.g. + allow the users to select Instruments based on whether the underlying type + is integer or double). * The criteria SHOULD be treated as additive, which means the Instrument has to meet _all_ the provided criteria. For example, if the criteria are _instrument name == "Foobar"_ and _instrument type is Histogram_, it will be @@ -582,8 +582,9 @@ to (Tn+1, Tn+2] - **ONLY** for this particular The SDK SHOULD provide a way to allow `MetricReader` to respond to [MeterProvider.ForceFlush](#forceflush) and [MeterProvider.Shutdown](#shutdown). -Individual language clients can decide the language idiomatic approach, for -example, as `OnForceFlush` and `OnShutdown` callback functions. +[OpenTelemetry SDK](../overview.md#sdk) authors CAN decide the language +idiomatic approach, for example, as `OnForceFlush` and `OnShutdown` callback +functions. ### MetricReader operations @@ -596,10 +597,10 @@ functions will be triggered. `Collect` SHOULD provide a way to let the caller know whether it succeeded, failed or timed out. -`Collect` does not have any required parameters, however, individual language -clients MAY choose to add parameters (e.g. callback, filter, timeout). -Individual language clients MAY choose the return value type, or do not return -anything. +`Collect` does not have any required parameters, however, [OpenTelemetry +SDK](../overview.md#sdk) authors MAY choose to add parameters (e.g. callback, +filter, timeout). [OpenTelemetry SDK](../overview.md#sdk) authors MAY choose the +return value type, or do not return anything. ### Periodic exporting MetricReader @@ -717,21 +718,21 @@ invocation, but before the exporter exports the completed metrics. `ForceFlush` SHOULD complete or abort within some timeout. `ForceFlush` can be implemented as a blocking API or an asynchronous API which notifies the caller -via a callback or an event. OpenTelemetry client authors can decide if they want -to make the flush timeout configurable. +via a callback or an event. [OpenTelemetry SDK](../overview.md#sdk) authors CAN +decide if they want to make the flush timeout configurable. ##### Shutdown() Shuts down the exporter. Called when SDK is shut down. This is an opportunity for exporter to do any cleanup required. -Shutdown should be called only once for each `MetricExporter` instance. After +Shutdown SHOULD be called only once for each `MetricExporter` instance. After the call to `Shutdown` subsequent calls to `Export` are not allowed and should return a Failure result. -`Shutdown` should not block indefinitely (e.g. if it attempts to flush the data -and the destination is unavailable). OpenTelemetry client authors can decide if -they want to make the shutdown timeout configurable. +`Shutdown` SHOULD NOT block indefinitely (e.g. if it attempts to flush the data +and the destination is unavailable). [OpenTelemetry SDK](../overview.md#sdk) +authors CAN decide if they want to make the shutdown timeout configurable. ### Pull Metric Exporter