Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Assert metric reader aggregation temporality selection influence on m…
…etric persistence and start time
  • Loading branch information
jack-berg committed Jul 28, 2023
commit 5575ea7c14ea3a7f38951a47e74537d2711b0d3c
17 changes: 8 additions & 9 deletions specification/metrics/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,7 @@ them up) when changes occur.

Note: If the values are additive (e.g. the process heap size - it makes sense to
report the heap size from multiple processes and sum them up, so we get the
total heap usage), use [Counter](#counter)
or [UpDownCounter](#asynchronous-updowncounter).
total heap usage), use [UpDownCounter](#asynchronous-updowncounter).

Note: Synchronous Gauge is normally used when the measurements are exposed via a
subscription to change events (
Expand Down Expand Up @@ -815,9 +814,9 @@ might consider:
```java
// Java

DoubleGauge componentTemperature = meter.gaugeBuilder("hw.temperature")
.setDescription("Temperature of hardware component")
.setUnit("C")
DoubleGauge backgroundNoiseLevel = meter.gaugeBuilder("facility.noise.level")
.setDescription("Background noise level of rooms")
.setUnit("B")
.build();
```

Expand Down Expand Up @@ -857,11 +856,11 @@ consider:

```java
// Java
Attributes memoryA = Attributes.builder().put("id", "P0 Channel A");
Attributes memoryB = Attributes.builder().put("id", "P0 Channel B");
Attributes roomA = Attributes.builder().put("room.id", "Rack A");
Attributes roomB = Attributes.builder().put("room.id", "Rack B");

componentTemperature.record(32.5, memoryA);
componentTemperature.record(31.9, memoryB);
backgroundNoiseLevel.record(4.3, roomA);
backgroundNoiseLevel.record(2.5, roomB);
```

### Asynchronous Gauge
Expand Down
8 changes: 4 additions & 4 deletions specification/metrics/data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,10 +436,10 @@ in OTLP represents a sampled value at a given time. A Gauge stream consists of:
- A set of data points, each containing:
- An independent set of Attribute name-value pairs.
- A sampled value (e.g. current CPU temperature)
- A time window (of `(start, end]`) time for which the Gauge was calculated.
- The time interval is inclusive of the end time.
- Times are specified in Value is UNIX Epoch time in nanoseconds since
`00:00:00 UTC on 1 January 1970`
- A timestamp when the value was sampled (`time_unix_nano`)
- (optional) A timestamp (`start_time_unix_nano`) which best represents the
first possible moment a measurement could be recorded. This is commonly
set to the timestamp when a metric collection system started.
- (optional) a set of examplars (see [Exemplars](#exemplars)).

In OTLP, a point within a Gauge stream represents the last-sampled event for a
Expand Down
42 changes: 36 additions & 6 deletions specification/metrics/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -939,18 +939,48 @@ to be used typically with push-based metrics collection.

The `MetricReader` MUST ensure that data points from OpenTelemetry
[instruments](./api.md#instrument) are output in the configured aggregation
temporality for each instrument kind. For synchronous instruments being output
with Cumulative temporality, this means converting [Delta to Cumulative](supplementary-guidelines.md#synchronous-example-cumulative-aggregation-temporality)
aggregation temporality. For asynchronous instruments being output
with Delta temporality, this means converting [Cumulative to
Delta](supplementary-guidelines.md#asynchronous-example-delta-temporality) aggregation
temporality.
temporality for each instrument kind. For synchronous instruments with
Cumulative aggregation temporality, this means
converting [Delta to Cumulative](supplementary-guidelines.md#synchronous-example-cumulative-aggregation-temporality)
aggregation temporality. For asynchronous instruments with Delta temporality,
this means
converting [Cumulative to Delta](supplementary-guidelines.md#asynchronous-example-delta-temporality)
aggregation temporality.

The `MetricReader` is not required to ensure data points from a non-SDK
[MetricProducer](#metricproducer) are output in the configured aggregation
temporality, as these data points are not collected using OpenTelemetry
instruments.

The `MetricReader` selection of `temporality` as a function of instrument kind
influences the persistence of metric data points across collections. For
synchronous instruments with Cumulative aggregation
temporality, [MetricReader.Collect](#collect) MUST receive data points exposed
in previous collections regardless of whether new measurements have been
recorded. For synchronous instruments with Delta aggregation
temporality, [MetricReader.Collect](#collect) MUST only receive data points with
measurements recorded since the previous collection. For asynchronous
instruments with Delta or Cumulative aggregation
temporality, [MetricReader.Collect](#collect) MUST only receive data points with
measurements recorded since the previous collection. These rules apply to all
metrics, not just those whose [point kinds](./data-model.md#point-kinds)
includes an aggregation temporality field.

The `MetricReader` selection of `temporality` as a function of instrument kind
influences the starting timestamp (i.e. `StartTimeUnixNano`) of metrics data
points received by [MetricReader.Collect](#collect). For instruments with
Cumulative aggregation temporality, successive data points received by
successive calls to [MetricReader.Collect](#collect) MUST repeat the same
starting timestamps (e.g. `(T0, T1], (T0, T2], (T0, T3]`). For instruments with
Delta aggregation temporality, successive data points received by successive
calls to [MetricReader.Collect](#collect) MUST advance the starting timestamp (
e.g. `(T0, T1], (T1, T2], (T2, T3]`). The ending timestamp (i.e. `TimeUnixNano`)
MUST always be equal to time the metric data point took effect, which is equal
to when [MetricReader.Collect](#collect) was invoked. These rules apply to all
metrics, not just those whose [point kinds](./data-model#point-kinds) includes
an aggregation temporality field.
See [data model temporality](./data-model.md#temporality) for more details.

The SDK MUST support multiple `MetricReader` instances to be registered on the
same `MeterProvider`, and the [MetricReader.Collect](#collect) invocation on one
`MetricReader` instance SHOULD NOT introduce side-effects to other `MetricReader`
Expand Down