diff --git a/specification/metrics/api.md b/specification/metrics/api.md index 663e4d46a17..5bac1968ec0 100644 --- a/specification/metrics/api.md +++ b/specification/metrics/api.md @@ -19,9 +19,7 @@ linkTitle: API * [Meter operations](#meter-operations) - [Instrument](#instrument) * [General characteristics](#general-characteristics) - + [Instrument type conflict detection](#instrument-type-conflict-detection) - + [Instrument namespace](#instrument-namespace) - + [Instrument naming rule](#instrument-naming-rule) + + [Instrument name syntax](#instrument-name-syntax) + [Instrument unit](#instrument-unit) + [Instrument description](#instrument-description) + [Synchronous and Asynchronous instruments](#synchronous-and-asynchronous-instruments) @@ -115,30 +113,16 @@ The `MeterProvider` MUST provide the following functions: This API MUST accept the following parameters: -* `name`: This name SHOULD uniquely identify the [instrumentation +* `name`: This name uniquely identifies the [instrumentation scope](../glossary.md#instrumentation-scope), such as the [instrumentation library](../glossary.md#instrumentation-library) (e.g. `io.opentelemetry.contrib.mongodb`), package, module or class name. If an application or library has built-in OpenTelemetry instrumentation, both [Instrumented library](../glossary.md#instrumented-library) and [Instrumentation - library](../glossary.md#instrumentation-library) may refer to the same + library](../glossary.md#instrumentation-library) can refer to the same library. In that scenario, the `name` denotes a module name or component name - within that library or application. In case an invalid name (null or empty - string) is specified, a working Meter implementation MUST be returned as a - fallback rather than returning null or throwing an exception, its `name` - property SHOULD keep the original invalid value, and a message reporting that - the specified value is invalid SHOULD be logged. A library, implementing the - OpenTelemetry API *may* also ignore this name and return a default instance - for all calls, if it does not support "named" functionality (e.g. an - implementation which is not even observability-related). A MeterProvider could - also return a no-op Meter here if application owners configure the SDK to - suppress telemetry produced by this library. - - The `name` needs to be provided by a user. If possible, the API SHOULD be - structured so a user is obligated to provide this parameter. If it is not - possible to structurally enforce this obligation, the API MUST be documented - in a way to communicate to users that this parameter is needed. + within that library or application. * `version`: Specifies the version of the instrumentation scope if the scope has a version (e.g. a library version). Example value: `1.0.0`. @@ -168,23 +152,6 @@ The term *identical* applied to Meters describes instances where all identifying fields are equal. The term *distinct* applied to Meters describes instances where at least one identifying field has a different value. -Implementations MUST NOT require users to repeatedly obtain a `Meter` with -the same identity to pick up configuration changes. This can be -achieved either by allowing to work with an outdated configuration or by -ensuring that new configuration applies also to previously returned `Meter`s. - -Note: This could, for example, be implemented by storing any mutable -configuration in the `MeterProvider` and having `Meter` implementation objects -have a reference to the `MeterProvider` from which they were obtained. If -configuration must be stored per-meter (such as disabling a certain meter), the -meter could, for example, do a look-up with its identity in a map -in the `MeterProvider`, or the `MeterProvider` could maintain a registry of all -returned `Meter`s and actively update their configuration if it changes. - -The effect of associating a Schema URL with a `Meter` MUST be that the telemetry -emitted using the `Meter` will be associated with the Schema URL, provided that -the emitted data format is capable of representing such association. - ## Meter The meter is responsible for creating [Instruments](#instrument). @@ -224,42 +191,10 @@ floating point numbers SHOULD be considered as identifying. ### General characteristics -#### Instrument type conflict detection - -When more than one Instrument of the same `name` is created for -identical Meters, denoted *duplicate instrument registration*, the -implementation MUST create a valid Instrument in every case. Here, -"valid" means an instrument that is functional and can be expected to -export data, despite potentially creating a [semantic error in the -data -model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations). +#### Instrument name syntax -It is unspecified whether or under which conditions the same or -different Instrument instance will be returned as a result of -duplicate instrument registration. The term *identical* applied to -Instruments describes instances where all identifying fields are -equal. The term *distinct* applied to Instruments describes instances -where at least one field value is different. - -When more than one distinct Instrument is registered with the same -`name` for identical Meters, the implementation SHOULD emit a warning -to the user informing them of duplicate registration conflict(s). -The warning helps to avoid the semantic error state described in the -[OpenTelemetry Metrics data -model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations) -when more than one `Metric` is written for a given instrument `name` -and Meter identity by the same MeterProvider. - -#### Instrument namespace - -Distinct Meters MUST be treated as separate namespaces for the -purposes of detecting [duplicate instrument registration -conflicts](#instrument-type-conflict-detection). - -#### Instrument naming rule - -Instrument names MUST conform to the following syntax (described using the -[Augmented Backus-Naur Form](https://tools.ietf.org/html/rfc5234)): +The instrument name syntax is defined below using the [Augmented Backus-Naur +Form](https://tools.ietf.org/html/rfc5234): ```abnf instrument-name = ALPHA 0*62 ("_" / "." / "-" / ALPHA / DIGIT) @@ -277,12 +212,9 @@ DIGIT = %x30-39 ; 0-9 #### Instrument unit -The `unit` is an optional string provided by the author of the Instrument. It -SHOULD be treated as an opaque string from the API and SDK (e.g. the SDK is not -expected to validate the unit of measurement, or perform the unit conversion). +The `unit` is an optional string provided by the author of the Instrument. The +API SHOULD treat it as an opaque string. -* If the `unit` is not provided or the `unit` is null, the API and SDK MUST make - sure that the behavior is the same as an empty `unit` string. * It MUST be case-sensitive (e.g. `kb` and `kB` are different units), ASCII string. * It can have a maximum length of 63 characters. The number 63 is chosen to @@ -293,11 +225,8 @@ expected to validate the unit of measurement, or perform the unit conversion). #### Instrument description The `description` is an optional free-form text provided by the author of the -instrument. It MUST be treated as an opaque string from the API and SDK. +instrument. The API MUST treat it as an opaque string. -* If the `description` is not provided or the `description` is null, the API and - SDK MUST make sure that the behavior is the same as an empty `description` - string. * 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`). @@ -340,11 +269,10 @@ The API to construct synchronous instruments MUST accept the following parameter possible to structurally enforce this obligation, the API MUST be documented in a way to communicate to users that this parameter is needed. - The `name` needs to follow the [instrument naming - rule](#instrument-naming-rule). The API SHOULD be documented in a way to - communicate to users that this parameter needs to conform to the linked - syntax. The API SHOULD NOT validate the `name`, that is left to - implementations of the API. + The API SHOULD be documented in a way to communicate to users that the `name` + parameter needs to conform to the [instrument name + syntax](#instrument-name-syntax). The API SHOULD NOT validate the `name`; + that is left to implementations of the API. * A `unit` of measure. Users can provide a `unit`, but it is up to their discretion. Therefore, this @@ -383,11 +311,10 @@ The API to construct asynchronous instruments MUST accept the following paramete possible to structurally enforce this obligation, the API MUST be documented in a way to communicate to users that this parameter is needed. - The `name` needs to follow the [instrument naming - rule](#instrument-naming-rule). The API SHOULD be documented in a way to - communicate to users that this parameter needs to conform to the linked - syntax. The API SHOULD NOT validate the `name`, that is left to - implementations of the API. + The API SHOULD be documented in a way to communicate to users that the `name` + parameter needs to conform to the [instrument name + syntax](#instrument-name-syntax). The API SHOULD NOT validate the `name`, + that is left to implementations of the API. * A `unit` of measure. Users can provide a `unit`, but it is up to their discretion. Therefore, this diff --git a/specification/metrics/noop.md b/specification/metrics/noop.md new file mode 100644 index 00000000000..94e72b70325 --- /dev/null +++ b/specification/metrics/noop.md @@ -0,0 +1,289 @@ + + +# Metrics No-Op API Implementation + +**Status**: [Experimental](../document-status.md) + +
+ Table of Contents + + + +- [MeterProvider](#meterprovider) + * [Meter Creation](#meter-creation) +- [Meter](#meter) + * [Counter Creation](#counter-creation) + * [UpDownCounter Creation](#updowncounter-creation) + * [Histogram Creation](#histogram-creation) + * [Asynchronous Counter Creation](#asynchronous-counter-creation) + * [Asynchronous UpDownCounter Creation](#asynchronous-updowncounter-creation) + * [Asynchronous Gauge Creation](#asynchronous-gauge-creation) +- [Instruments](#instruments) + * [Counter](#counter) + + [Counter Add](#counter-add) + * [UpDownCounter](#updowncounter) + + [UpDownCounter Add](#updowncounter-add) + * [Histogram](#histogram) + + [Histogram Record](#histogram-record) + * [Asynchronous Counter](#asynchronous-counter) + * [Asynchronous Counter Observations](#asynchronous-counter-observations) + * [Asynchronous UpDownCounter](#asynchronous-updowncounter) + * [Asynchronous UpDownCounter Observations](#asynchronous-updowncounter-observations) + * [Asynchronous Gauge](#asynchronous-gauge) + * [Asynchronous Gauge Observations](#asynchronous-gauge-observations) + + + +
+ +Users of OpenTelemetry need a way to disable the API from actually +performing any operations. The No-Op OpenTelemetry API implementation +(henceforth referred to as the No-Op) provides users with this +functionally. It implements the OpenTelemetry API so that no telemetry +is produced and computation resources are minimized. + +All language implementations of OpenTelemetry MUST provide a No-Op. + +## MeterProvider + +The No-Op MUST allow the creation of multiple MeterProviders. + +The MeterProviders created by the No-Op needs to hold as small a memory +footprint as possible. Therefore, all MeterProviders created MUST NOT +hold configuration or operational state. + +Since all MeterProviders hold the same empty state, a No-Op MAY +provide the same MeterProvider instances to all creation requests. + +The No-Op is used by OpenTelemetry users to disable OpenTelemetry +computation overhead and eliminate OpenTelemetry related output. For +this reason, the MeterProvider MUST NOT return a non-empty error or log +any message for any operations it performs. + +All operations a MeterProvider provides MUST be safe to be run +concurrently. + +### Meter Creation + +[New Meter instances are always created with a +MeterProvider](./api.md#meterprovider). Therefore, MeterProviders MUST +allow for the creation of Meters. All Meters created MUST be an instance of the +[No-Op Meter](#meter). + +Since all Meters will hold the same empty state, a MeterProvider MAY +return the same Meter instances to all creation requests. + +[The API specifies multiple parameters](./api.md#meterprovider) that +need to be accepted by the creation operation. The MeterProvider MUST +accept these parameters. However, the MeterProvider MUST NOT validate +any argument it receives. + +## Meter + +A Meter is always created by a MeterProvider. The No-Op MUST NOT provide +a way for a user to create a Meter other than by a No-Op MeterProvider. + +The Meters created by the No-Op need to hold as small a memory +footprint as possible. Therefore, all Meters created MUST NOT hold +configuration or operational state. + +The Meter MUST NOT return a non-empty error or log any message for any +operations it performs. + +All operations a Meter provides MUST be safe to be run concurrently. + +### Counter Creation + +The No-Op Meter MUST allow for the creation of a [Counter +instrument](#counter). + +Since all Counters hold the same empty state, a Meter MAY return the +same Counter instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#synchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives. + +### UpDownCounter Creation + +The No-Op Meter MUST allow for the creation of a [UpDownCounter +instrument](#updowncounter). + +Since all UpDownCounters hold the same empty state, a Meter MAY return +the same UpDownCounter instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#synchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives. + +### Histogram Creation + +The No-Op Meter MUST allow for the creation of a [Histogram +instrument](#histogram). + +Since all Histograms hold the same empty state, a Meter MAY return the +same Histogram instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#synchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives. + +### Asynchronous Counter Creation + +The No-Op Meter MUST allow for the creation of an [Asynchronous Counter +instrument](#asynchronous-counter). + +Since all Asynchronous Counters hold the same empty state, a Meter MAY +return the same Asynchronous Counter instance to all creation requests. + +[The API specifies multiple +parameters](./api.md#asynchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives and it MUST NOT hold any reference to the passed callbacks. + +### Asynchronous UpDownCounter Creation + +The No-Op Meter MUST allow for the creation of an [Asynchronous +UpDownCounter instrument](#asynchronous-updowncounter). + +Since all Asynchronous UpDownCounters hold the same empty state, a Meter +MAY return the same Asynchronous UpDownCounter instance to all creation +requests. + +[The API specifies multiple +parameters](./api.md#asynchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives and it MUST NOT hold any reference to the passed callbacks. + +### Asynchronous Gauge Creation + +The No-Op Meter MUST allow for the creation of an [Asynchronous Gauge +instrument](#asynchronous-gauge). + +Since all Asynchronous Gauges hold the same empty state, a Meter MAY +return the same Asynchronous UpDownCounter instance to all creation +requests. + +[The API specifies multiple +parameters](./api.md#asynchronous-instrument-api) that need to be +accepted by the creation operation. The Meter MUST accept these +parameters. However, the Meter MUST NOT validate any argument it +receives and it MUST NOT hold any reference to the passed callbacks. + +## Instruments + +Instruments are used to make measurements and report telemetry for a +system. However, the No-Op is used to disable this production of +telemetry. Because of this, all instruments the No-Op provides MUST NOT +hold any configuration or operational state including the aggregation of +telemetry. + +### Counter + +Counters are always created by a Meter, the No-Op MUST NOT provide a way +for a user to create a Counter other than by a No-Op Meter. + +Counters MUST NOT return a non-empty error or log any message for any +operations they perform. + +All operations a Counter provides MUST be safe to be run concurrently. + +#### Counter Add + +The No-Op Counter MUST provide the user an interface to Add that +implements the [API](./api.md#add). It MUST NOT validate or retain any +state about the arguments it receives. + +### UpDownCounter + +UpDownCounters are always created by a Meter, the No-Op MUST NOT provide +a way for a user to create a UpDownCounter other than by a No-Op Meter. + +UpDownCounters MUST NOT return a non-empty error or log any message for +any operations they perform. + +All operations an UpDownCounter provides MUST be safe to be run +concurrently. + +#### UpDownCounter Add + +The No-Op UpDownCounter MUST provide the user an interface to Add that +implements the [API](./api.md#add-1). It MUST NOT validate or retain any +state about the arguments it receives. + +### Histogram + +Histograms are always created by a Meter, the No-Op MUST NOT provide a +way for a user to create a Histogram other than by a No-Op Meter. + +Histograms MUST NOT return a non-empty error or log any message for any +operations they perform. + +All operations a Histogram provides MUST be safe to be run concurrently. + +#### Histogram Record + +The No-Op Histogram MUST provide the user an interface to Record that +implements the [API](./api.md#record). It MUST NOT validate or retain +any state about the arguments it receives. + +### Asynchronous Counter + +Asynchronous Counters are always created by a Meter, the No-Op MUST NOT +provide a way for a user to create a Asynchronous Counter other than by +a No-Op Meter. + +Asynchronous Counters MUST NOT return a non-empty error or log any +message for any operations they perform. + +All operations an Asynchronous Counter provides MUST be safe to be run +concurrently. + +### Asynchronous Counter Observations + +The No-Op Asynchronous Counter MUST NOT validate or retain any state +about observations made for the instrument. + +### Asynchronous UpDownCounter + +Asynchronous UpDownCounters are always created by a Meter, the No-Op +MUST NOT provide a way for a user to create a Asynchronous UpDownCounter +other than by a No-Op Meter. + +Asynchronous UpDownCounters MUST NOT return a non-empty error or log any +message for any operations they perform. + +All operations an Asynchronous UpDownCounter provides MUST be safe to be +run concurrently. + +### Asynchronous UpDownCounter Observations + +The No-Op Asynchronous UpDownCounter MUST NOT validate or retain any +state about observations made for the instrument. + +### Asynchronous Gauge + +Asynchronous Gauges are always created by a Meter, the No-Op MUST NOT +provide a way for a user to create a Asynchronous Gauge other than by a +No-Op Meter. + +Asynchronous Gauges MUST NOT return a non-empty error or log any message +for any operations they perform. + +All operations an Asynchronous Gauge provides MUST be safe to be run +concurrently. + +### Asynchronous Gauge Observations + +The No-Op Asynchronous Gauge MUST NOT validate or retain any state about +observations made for the instrument. diff --git a/specification/metrics/sdk.md b/specification/metrics/sdk.md index f9e358e1542..092c17e1969 100644 --- a/specification/metrics/sdk.md +++ b/specification/metrics/sdk.md @@ -30,7 +30,11 @@ linkTitle: SDK * [Use the maximum scale for single measurements](#use-the-maximum-scale-for-single-measurements) * [Maintain the ideal scale](#maintain-the-ideal-scale) * [Observations inside asynchronous callbacks](#observations-inside-asynchronous-callbacks) - * [Resolving duplicate instrument registration conflicts](#resolving-duplicate-instrument-registration-conflicts) +- [Meter](#meter) + * [Duplicate instrument registration](#duplicate-instrument-registration) + * [Instrument name](#instrument-name) + * [Instrument unit](#instrument-unit) + * [Instrument description](#instrument-description) - [Attribute limits](#attribute-limits) - [Exemplar](#exemplar) * [ExemplarFilter](#exemplarfilter) @@ -65,6 +69,13 @@ linkTitle: SDK +Users of OpenTelemetry need a way for instrumentation interactions with the +OpenTelemetry API to actually produce telemetry. The OpenTelemetry SDK +(henceforth referred to as the SDK) is an implementation of the OpenTelemetry +API that provides users with this functionally. + +All language implementations of OpenTelemetry MUST provide an SDK. + ## MeterProvider **Status**: [Stable](../document-status.md) @@ -88,6 +99,15 @@ the `MeterProvider` MUST be used to create an [`InstrumentationScope`](../glossary.md#instrumentation-scope) instance which is stored on the created `Meter`. +In the case where an invalid `name` (null or empty string) is specified, a +working Meter MUST be returned as a fallback rather than returning null or +throwing an exception, its `name` SHOULD keep the original invalid value, and a +message reporting that the specified value is invalid SHOULD be logged. + +When a Schema URL is passed as an argument when creating a `Meter` the emitted +telemetry for that `Meter` MUST be associated with the Schema URL, provided +that the emitted data format is capable of representing such association. + Configuration (i.e., [MetricExporters](#metricexporter), [MetricReaders](#metricreader) and [Views](#view)) MUST be managed solely by the `MeterProvider` and the SDK MUST provide a way to configure all options that are @@ -560,33 +580,67 @@ execution. The implementation MUST complete the execution of all callbacks for a given instrument before starting a subsequent round of collection. -### Resolving duplicate instrument registration conflicts +## Meter + +Distinct meters MUST be treated as separate namespaces for the purposes of detecting +[duplicate instrument registrations](#duplicate-instrument-registration). + +### Duplicate instrument registration + +When more than one Instrument of the same `name` is created for identical +Meters, denoted _duplicate instrument registration_, the Meter MUST create a +valid Instrument in every case. Here, "valid" means an instrument that is +functional and can be expected to export data, despite potentially creating a +[semantic error in the data +model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations). -As [stated in the API -specification](api.md#instrument-type-conflict-detection), -implementations are REQUIRED to create valid instruments in case of -duplicate instrument registration, and the [data model includes -RECOMMENDATIONS on how to treat the consequent duplicate -conflicting](data-model.md#opentelemetry-protocol-data-model-producer-recommendations) -`Metric` definitions. +It is unspecified whether or under which conditions the same or +different Instrument instance will be returned as a result of +duplicate instrument registration. The term _identical_ applied to +Instruments describes instances where all [identifying +fields](./api.md#instrument) are equal. The term _distinct_ applied +to Instruments describes instances where at least one field value is +different. -The implementation MUST aggregate data from identical Instruments -together in its export pipeline. +Based on [the recommendations from the data +model](data-model.md#opentelemetry-protocol-data-model-producer-recommendations), +the SDK MUST aggregate data from identical Instruments together in its export +pipeline. -The implementation SHOULD assist the user in managing conflicts by -reporting each duplicate-conflicting instrument registration that was -not corrected by a View as follows. When a potential conflict arises -between two non-identical `Metric` instances having the same `name`: +When a duplicate instrument registration occurs, and it is not corrected with a +View, a warning SHOULD be emitted. The emitted warning SHOULD include +information for the user on how to resolve the conflict, if possible. 1. If the potential conflict involves multiple `description` properties, setting the `description` through a configured View SHOULD avoid the warning. 2. If the potential conflict involves instruments that can be distinguished by a supported View selector (e.g., instrument type) - a View recipe SHOULD be printed advising the user how to avoid the - warning by renaming one of the conflicting instruments. -3. Otherwise (e.g., use of multiple units), the implementation SHOULD - pass through the data by reporting both `Metric` objects. + a renaming View recipe SHOULD be included in the warning. +3. Otherwise (e.g., use of multiple units), the SDK SHOULD pass through the + data by reporting both `Metric` objects and emit a generic warning + describing the duplicate instrument registration. + +### Instrument name + +When a Meter creates an instrument, it SHOULD validate the instrument name +conforms to the [instrument name syntax](./api.md#instrument-name-syntax) + +If the instrument name does not conform to this syntax, the Meter SHOULD emit +an error notifying the user about the invalid name. It is left unspecified if a +valid instrument is also returned. + +### Instrument unit + +When a Meter creates an instrument, it SHOULD NOT validate the instrument unit. +If a unit is not provided or the unit is null, the Meter MUST treat it the same +as an empty unit string. + +### Instrument description + +When a Meter creates an instrument, it SHOULD NOT validate the instrument +description. If a description is not provided or the description is null, the +Meter MUST treat it the same as an empty description string. ## Attribute limits