diff --git a/CHANGELOG.md b/CHANGELOG.md index a0911cc..db140dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -107,6 +107,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- The metrics API now documents that `APIMeterProvider`, `APIMeter` and the seven + instruments need to be safe for concurrent use, that an instrument `name` must + conform to the instrument name syntax, and that `Histogram.record` expects a + non-negative value. metrics/api.md makes the first a MUST and the other two a + SHOULD. Comments only, no behavior change + ([#141](https://github.com/MindfulSoftwareLLC/dartastic_opentelemetry_api/pull/141)). - `TraceState` construction (`fromMap`, `OTelAPI`/`OTelFactory` `traceState(...)`) now validates keys and values against the W3C tracestate grammar, dropping invalid entries instead of silently accepting them diff --git a/lib/src/api/metrics/counter.dart b/lib/src/api/metrics/counter.dart index 4ac87e3..0d1e14e 100644 --- a/lib/src/api/metrics/counter.dart +++ b/lib/src/api/metrics/counter.dart @@ -12,6 +12,11 @@ part 'counter_create.dart'; /// /// See the OpenTelemetry specification for more details: /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APICounter { /// The name of this counter instrument. final String _name; diff --git a/lib/src/api/metrics/gauge.dart b/lib/src/api/metrics/gauge.dart index a190f1a..581acdd 100644 --- a/lib/src/api/metrics/gauge.dart +++ b/lib/src/api/metrics/gauge.dart @@ -12,6 +12,11 @@ part 'gauge_create.dart'; /// /// See the OpenTelemetry specification for more details: /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#gauge +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIGauge { /// The name of this gauge instrument. final String _name; diff --git a/lib/src/api/metrics/histogram.dart b/lib/src/api/metrics/histogram.dart index c2cd017..567efe5 100644 --- a/lib/src/api/metrics/histogram.dart +++ b/lib/src/api/metrics/histogram.dart @@ -12,6 +12,11 @@ part 'histogram_create.dart'; /// /// See the OpenTelemetry specification for more details: /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#histogram +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIHistogram { /// The name of this histogram instrument. final String _name; @@ -70,6 +75,9 @@ class APIHistogram { /// Records a value in the histogram. /// + /// The value is expected to be non-negative. This API does not validate + /// that, which the specification leaves to implementations of the API. + /// /// [value] The value to record. /// [attributes] The set of attributes to associate with this value. void record(T value, [Attributes? attributes]) { @@ -78,6 +86,9 @@ class APIHistogram { /// Records a value with the given map of attributes. /// + /// The value is expected to be non-negative. This API does not validate + /// that, which the specification leaves to implementations of the API. + /// /// [value] The value to record. /// [attributeMap] A map of attribute key-value pairs. void recordWithMap(T value, Map attributeMap) { diff --git a/lib/src/api/metrics/meter.dart b/lib/src/api/metrics/meter.dart index 1013afb..239f578 100644 --- a/lib/src/api/metrics/meter.dart +++ b/lib/src/api/metrics/meter.dart @@ -27,6 +27,11 @@ part 'meter_create.dart'; /// an empty instrument name, and never logs or reports: metrics/noop.md says /// the Meter MUST NOT return a non-empty error or log any message. Name /// validation belongs to the SDK meter. +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIMeter { /// Gets the name of the meter, usually of a library, package or module final String name; @@ -64,7 +69,12 @@ class APIMeter { /// /// A Counter is a synchronous Instrument which supports non-negative increments. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument APICounter createCounter({ @@ -86,7 +96,12 @@ class APIMeter { /// /// An UpDownCounter is a synchronous Instrument which supports increments and decrements. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument APIUpDownCounter createUpDownCounter({ @@ -109,7 +124,12 @@ class APIMeter { /// A Histogram is a synchronous Instrument which can be used to report arbitrary values /// that are likely to be statistically meaningful. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument /// [boundaries] Optional explicit bucket boundaries for the histogram @@ -146,7 +166,12 @@ class APIMeter { /// A Gauge is a synchronous Instrument which can be used to record non-additive value(s) /// when changes occur. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument APIGauge createGauge({ @@ -169,7 +194,12 @@ class APIMeter { /// An ObservableCounter is an asynchronous Instrument which reports monotonically increasing /// value(s) when the instrument is being observed. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument /// [callback] Optional callback to provide measurements when the instrument is observed @@ -198,7 +228,12 @@ class APIMeter { /// An ObservableUpDownCounter is an asynchronous Instrument which reports values that increase /// or decrease when the instrument is being observed. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument /// [callback] Optional callback to provide measurements when the instrument is observed @@ -227,7 +262,12 @@ class APIMeter { /// An ObservableGauge is an asynchronous Instrument which reports non-additive value(s) /// when the instrument is being observed. /// - /// [name] The name of the instrument + /// [name] The name of the instrument. It must conform to the instrument + /// name syntax: not empty, first character an ASCII letter, the rest + /// letters, digits, `_`, `.`, `-` or `/`, at most 255 characters, and + /// compared case-insensitively. This API does not validate it; the SDK + /// meter does. See + /// [Instrument name syntax](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#instrument-name-syntax). /// [unit] Optional unit of the instrument (e.g., "ms" for milliseconds) /// [description] Optional description of the instrument /// [callback] Optional callback to provide measurements when the instrument is observed diff --git a/lib/src/api/metrics/meter_provider.dart b/lib/src/api/metrics/meter_provider.dart index 6216271..2f52da2 100644 --- a/lib/src/api/metrics/meter_provider.dart +++ b/lib/src/api/metrics/meter_provider.dart @@ -19,6 +19,11 @@ part 'meter_provider_create.dart'; /// ``` /// See [OTel] for creating meters in addition to the default. /// Use [OTelAPI] to run in no-op mode, as required by the specification. +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIMeterProvider { /// Creates a new [APIMeterProvider]. /// You cannot create a MeterProvider directly; you must use [OTelFactory]: diff --git a/lib/src/api/metrics/observable_counter.dart b/lib/src/api/metrics/observable_counter.dart index 8767aa5..f50ca7a 100644 --- a/lib/src/api/metrics/observable_counter.dart +++ b/lib/src/api/metrics/observable_counter.dart @@ -17,6 +17,11 @@ part 'observable_counter_create.dart'; /// An ObservableCounter is intended for capturing values that can only increase, /// such as the system uptime, the number of total bytes received, or the number /// of page faults. +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIObservableCounter implements APIObservableInstrument { final String _name; final String? _description; diff --git a/lib/src/api/metrics/observable_gauge.dart b/lib/src/api/metrics/observable_gauge.dart index a9bbbe3..b38d3ab 100644 --- a/lib/src/api/metrics/observable_gauge.dart +++ b/lib/src/api/metrics/observable_gauge.dart @@ -17,6 +17,11 @@ part 'observable_gauge_create.dart'; /// An ObservableGauge is intended for capturing values that are not meant to be combined /// across multiple entities, such as the current temperature, CPU usage percentage, or /// room occupancy. +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIObservableGauge implements APIObservableInstrument { final String _name; final String? _description; diff --git a/lib/src/api/metrics/observable_up_down_counter.dart b/lib/src/api/metrics/observable_up_down_counter.dart index fa4da91..917ff65 100644 --- a/lib/src/api/metrics/observable_up_down_counter.dart +++ b/lib/src/api/metrics/observable_up_down_counter.dart @@ -16,6 +16,11 @@ part 'observable_up_down_counter_create.dart'; /// /// An ObservableUpDownCounter is intended for capturing values that can increase or /// decrease, such as the current memory usage, active requests, or items in a queue. +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIObservableUpDownCounter implements APIObservableInstrument { final String _name; diff --git a/lib/src/api/metrics/up_down_counter.dart b/lib/src/api/metrics/up_down_counter.dart index 94806ff..19fda7e 100644 --- a/lib/src/api/metrics/up_down_counter.dart +++ b/lib/src/api/metrics/up_down_counter.dart @@ -12,6 +12,11 @@ part 'up_down_counter_create.dart'; /// /// See the OpenTelemetry specification for more details: /// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#updowncounter +/// +/// All methods of this class are safe for concurrent use by default: +/// implementations must remain correct when methods are invoked from +/// interleaved asynchronous tasks within an isolate. See +/// [Metrics API, concurrency requirements](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.60.0/specification/metrics/api.md#concurrency-requirements). class APIUpDownCounter { /// The name of this up-down counter instrument. final String _name;