Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename extra dimensions to extra attributes #2162

Merged
merged 4 commits into from
Dec 10, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
2 changes: 1 addition & 1 deletion specification/metrics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Given there are many well-established metrics solutions that exist today, it is
important to understand the goals of OpenTelemetry’s metrics effort:

* **Being able to connect metrics to other signals**. For example, metrics and
traces can be correlated via exemplars, and metrics dimensions can be enriched
traces can be correlated via exemplars, and metrics attributes can be enriched
via [Baggage](../baggage/api.md) and [Context](../context/context.md).
Additionally, [Resource](../resource/sdk.md) can be applied to
[logs](../overview.md#log-signal)/[metrics](../overview.md#metric-signal)/[traces](../overview.md#tracing-signal)
Expand Down
12 changes: 6 additions & 6 deletions specification/metrics/datamodel.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ collector. These transformations are:
1. Temporal reaggregation: Metrics that are collected at a high-frequency can be
re-aggregated into longer intervals, allowing low-resolution timeseries to be
pre-calculated or used in place of the original metric data.
2. Spatial reaggregation: Metrics that are produced with unwanted dimensions can
be re-aggregated into metrics having fewer dimensions.
2. Spatial reaggregation: Metrics that are produced with unwanted attributes can
be re-aggregated into metrics having fewer attributes.
3. Delta-to-Cumulative: Metrics that are input and output with Delta temporality
unburden the client from keeping high-cardinality state. The use of deltas
allows downstream services to bear the cost of conversion into cumulative
Expand All @@ -116,13 +116,13 @@ can be applied automatically to streams of the same type, subject to conditions
outlined below. Every OTLP data stream has an intrinsic
[decomposable aggregate function](https://en.wikipedia.org/wiki/Aggregate_function#Decomposable_aggregate_functions)
making it semantically well-defined to merge data points across both temporal
and spatial dimensions. Every OTLP data point also has two meaningful timestamps
and spatial attributes. Every OTLP data point also has two meaningful timestamps
which, combined with intrinsic aggregation, make it possible to carry out the
standard metric data transformations for each of the model’s basic points while
ensuring that the result carries the intended meaning.

As in OpenCensus Metrics, metrics data can be transformed into one or more
Views, just by selecting the aggregation interval and the desired dimensions.
Views, just by selecting the aggregation interval and the desired attributes.
One stream of OTLP data can be transformed into multiple timeseries outputs by
configuring different Views, and the required Views processing may be applied
inside the SDK or by an external collector.
Expand All @@ -136,9 +136,9 @@ breadth of OTel metrics usage.
1. OTel SDK exports 10 second resolution to a single OTel collector, using
cumulative temporality for a stateful client, stateless server:
- Collector passes-through original data to an OTLP destination
- Collector re-aggregates into longer intervals without changing dimensions
- Collector re-aggregates into longer intervals without changing attributes
- Collector re-aggregates into several distinct views, each with a subset of
the available dimensions, outputs to the same destination
the available attributes, outputs to the same destination
2. OTel SDK exports 10 second resolution to a single OTel collector, using delta
temporality for a stateless client, stateful server:
- Collector re-aggregates into 60 second resolution
Expand Down
18 changes: 9 additions & 9 deletions specification/metrics/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,17 @@ are output by the SDK. Here are some examples when a `View` might be needed:
library might expose HTTP client request duration as
[Histogram](./api.md#histogram) by default, but the application developer
might only want the total count of outgoing requests.
* Customize which attribute(s) are to be reported as metrics dimension(s). For
* Customize which attribute(s) are to be reported on metrics. For
example, an HTTP server library might expose HTTP verb (e.g. GET, POST) and
HTTP status code (e.g. 200, 301, 404). The application developer might only
care about HTTP status code (e.g. reporting the total count of HTTP requests
for each HTTP status code). There could also be extreme scenarios in which the
application developer does not need any dimension (e.g. just get the total
application developer does not need any attributes (e.g. just get the total
count of all incoming requests).
* Add additional dimension(s) from the [Context](../context/context.md). For
* Add additional attribute(s) from the [Context](../context/context.md). For
example, a [Baggage](../baggage/api.md) value might be available indicating
whether an HTTP request is coming from a bot/crawler or not. The application
developer might want this to be converted to a dimension for HTTP server
developer might want this to be converted to a attribute for HTTP server
metrics (e.g. the request/second from bots vs. real users).

The SDK MUST provide the means to register Views with a `MeterProvider`. Here
Expand Down Expand Up @@ -160,8 +160,8 @@ are the inputs:
not in the list will be ignored. If not provided, all the attribute keys
will be used by default (TODO: once the Hint API is available, the default
behavior should respect the Hint if it is available).
* The `extra dimensions` which come from Baggage/Context (optional). If not
provided, no extra dimension will be used. Please note that this only
* The `extra attributes` which come from Baggage/Context (optional). If not
reyang marked this conversation as resolved.
Show resolved Hide resolved
provided, no extra attributes will be used. Please note that this only
applies to [synchronous Instruments](./api.md#synchronous-instrument).
* The `aggregation` (optional) to be used. If not provided, the SDK SHOULD
apply a [default aggregation](#default-aggregation). If the aggregation
Expand All @@ -182,7 +182,7 @@ made with an Instrument:
* For each View, if the Instrument could match the instrument selection
criteria:
* Try to apply the View configuration. If there is an error (e.g. the View
asks for extra dimensions from the Baggage, but the Instrument is
asks for extra attributes from the Baggage, but the Instrument is
[asynchronous](./api.md#asynchronous-instrument) which doesn't have
Context) or a conflict (e.g. the View requires to export the metrics using
a certain name, but the name is already used by another View), provide a
Expand Down Expand Up @@ -243,7 +243,7 @@ meter_provider

```python
# Counter X will be exported as delta sum
# Histogram Y and Gauge Z will be exported with 2 dimensions (a and b)
# Histogram Y and Gauge Z will be exported with 2 attributes (a and b)
meter_provider
.add_view("X", aggregation=SumAggregation(DELTA))
.add_view("*", attribute_keys=["a", "b"])
Expand Down Expand Up @@ -746,7 +746,7 @@ Batch: | Metric | | Metric | ... | Metric |
+--> MetricPoints: | MetricPoint | | MetricPoint | ... | MetricPoint |
+-----+-------+ +-------------+ +-------------+
|
+--> timestamps, dimensions, value (or buckets), exemplars, ...
+--> timestamps, attributes, value (or buckets), exemplars, ...
```

Refer to the [Metric points](./datamodel.md#metric-points) section from the
Expand Down
2 changes: 1 addition & 1 deletion specification/metrics/semantic_conventions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ metrics.
Common attributes SHOULD be consistently named. This aids in discoverability and
disambiguates similar attributes to metric names.

["As a rule of thumb, **aggregations** over all the dimensions of a given
["As a rule of thumb, **aggregations** over all the attributes of a given
metric **SHOULD** be
meaningful,"](https://prometheus.io/docs/practices/naming/#metric-names) as
Prometheus recommends.
Expand Down
84 changes: 42 additions & 42 deletions specification/metrics/supplementary-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ Here is one way of choosing the correct instrument:
* I want to **record** or **time** something, and the **statistics** about this
thing are likely to be meaningful - use a [Histogram](./api.md#histogram).
* I want to **measure** something (by reporting an absolute value):
* If it makes NO sense to add up the values across different dimensions, use
* If it makes NO sense to add up the values across different sets of attributes, use
an [Asynchronous Gauge](./api.md#asynchronous-gauge).
* If it makes sense to add up the values across different dimensions:
* If it makes sense to add up the values across different sets of attributes:
* If the value is monotonically increasing - use an [Asynchronous
Counter](./api.md#asynchronous-counter).
* If the value is NOT monotonically increasing - use an [Asynchronous
Expand Down Expand Up @@ -177,20 +177,20 @@ and to simplify the story we will only have one histogram bucket `(-Inf, +Inf)`:
If we export the metrics using **Delta Temporality**:

* (T<sub>0</sub>, T<sub>1</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
`100 (ms)`
* dimensions: {verb = `GET`, status = `500`}, count: `1`, min: `1 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `1`, min: `1 (ms)`, max:
`1 (ms)`
* (T<sub>1</sub>, T<sub>2</sub>]
* nothing since we don't have any Measurement received
* (T<sub>2</sub>, T<sub>3</sub>]
* dimensions: {verb = `GET`, status = `500`}, count: `2`, min: `2 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `2`, min: `2 (ms)`, max:
`5 (ms)`
* (T<sub>3</sub>, T<sub>4</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `1`, min: `100 (ms)`,
* attributes: {verb = `GET`, status = `200`}, count: `1`, min: `100 (ms)`,
max: `100 (ms)`
* (T<sub>4</sub>, T<sub>5</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `3`, min: `30 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `3`, min: `30 (ms)`, max:
`100 (ms)`

You can see that the SDK **only needs to track what has happened after the
Expand All @@ -201,29 +201,29 @@ what has happened during (T<sub>0</sub>, T<sub>1</sub>].
If we export the metrics using **Cumulative Temporality**:

* (T<sub>0</sub>, T<sub>1</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
`100 (ms)`
* dimensions: {verb = `GET`, status = `500`}, count: `1`, min: `1 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `1`, min: `1 (ms)`, max:
`1 (ms)`
* (T<sub>0</sub>, T<sub>2</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
`100 (ms)`
* dimensions: {verb = `GET`, status = `500`}, count: `1`, min: `1 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `1`, min: `1 (ms)`, max:
`1 (ms)`
* (T<sub>0</sub>, T<sub>3</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `2`, min: `50 (ms)`, max:
`100 (ms)`
* dimensions: {verb = `GET`, status = `500`}, count: `3`, min: `1 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `3`, min: `1 (ms)`, max:
`5 (ms)`
* (T<sub>0</sub>, T<sub>4</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `3`, min: `50 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `3`, min: `50 (ms)`, max:
`100 (ms)`
* dimensions: {verb = `GET`, status = `500`}, count: `3`, min: `1 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `3`, min: `1 (ms)`, max:
`5 (ms)`
* (T<sub>0</sub>, T<sub>5</sub>]
* dimensions: {verb = `GET`, status = `200`}, count: `6`, min: `30 (ms)`, max:
* attributes: {verb = `GET`, status = `200`}, count: `6`, min: `30 (ms)`, max:
`100 (ms)`
* dimensions: {verb = `GET`, status = `500`}, count: `3`, min: `1 (ms)`, max:
* attributes: {verb = `GET`, status = `500`}, count: `3`, min: `1 (ms)`, max:
`5 (ms)`

You can see that we are performing Delta->Cumulative conversion, and the SDK
Expand All @@ -232,7 +232,7 @@ in the worst case, the SDK **will have to remember what has happened since the
beginning of the process**.

Imagine if we have a long running service and we collect metrics with 7
dimensions and each dimension can have 30 different values. We might eventually
attributes and each attribute can have 30 different values. We might eventually
end up having to remember the complete set of all `21,870,000,000` permutations!
This **cardinality explosion** is a well-known challenge in the metrics space.

Expand Down Expand Up @@ -281,20 +281,20 @@ thread ever started:
If we export the metrics using **Cumulative Temporality**:

* (T<sub>0</sub>, T<sub>1</sub>]
* dimensions: {pid = `1001`, tid = `1`}, sum: `50`
* dimensions: {pid = `1001`, tid = `2`}, sum: `30`
* attributes: {pid = `1001`, tid = `1`}, sum: `50`
* attributes: {pid = `1001`, tid = `2`}, sum: `30`
* (T<sub>0</sub>, T<sub>2</sub>]
* dimensions: {pid = `1001`, tid = `1`}, sum: `53`
* dimensions: {pid = `1001`, tid = `2`}, sum: `38`
* attributes: {pid = `1001`, tid = `1`}, sum: `53`
* attributes: {pid = `1001`, tid = `2`}, sum: `38`
* (T<sub>0</sub>, T<sub>3</sub>]
* dimensions: {pid = `1001`, tid = `1`}, sum: `56`
* dimensions: {pid = `1001`, tid = `2`}, sum: `42`
* attributes: {pid = `1001`, tid = `1`}, sum: `56`
* attributes: {pid = `1001`, tid = `2`}, sum: `42`
* (T<sub>0</sub>, T<sub>4</sub>]
* dimensions: {pid = `1001`, tid = `1`}, sum: `60`
* dimensions: {pid = `1001`, tid = `2`}, sum: `47`
* attributes: {pid = `1001`, tid = `1`}, sum: `60`
* attributes: {pid = `1001`, tid = `2`}, sum: `47`
* (T<sub>0</sub>, T<sub>5</sub>]
* dimensions: {pid = `1001`, tid = `2`}, sum: `53`
* dimensions: {pid = `1001`, tid = `3`}, sum: `5`
* attributes: {pid = `1001`, tid = `2`}, sum: `53`
* attributes: {pid = `1001`, tid = `3`}, sum: `5`

It is quite straightforward - we just take the data being reported from the
asynchronous instruments and send them. We might want to consider if [Resets and
Expand All @@ -305,20 +305,20 @@ operating system, and we probably don't want to confuse the metrics backend.
If we export the metrics using **Delta Temporality**:

* (T<sub>0</sub>, T<sub>1</sub>]
* dimensions: {pid = `1001`, tid = `1`}, delta: `50`
* dimensions: {pid = `1001`, tid = `2`}, delta: `30`
* attributes: {pid = `1001`, tid = `1`}, delta: `50`
* attributes: {pid = `1001`, tid = `2`}, delta: `30`
* (T<sub>1</sub>, T<sub>2</sub>]
* dimensions: {pid = `1001`, tid = `1`}, delta: `3`
* dimensions: {pid = `1001`, tid = `2`}, delta: `8`
* attributes: {pid = `1001`, tid = `1`}, delta: `3`
* attributes: {pid = `1001`, tid = `2`}, delta: `8`
* (T<sub>2</sub>, T<sub>3</sub>]
* dimensions: {pid = `1001`, tid = `1`}, delta: `3`
* dimensions: {pid = `1001`, tid = `2`}, delta: `4`
* attributes: {pid = `1001`, tid = `1`}, delta: `3`
* attributes: {pid = `1001`, tid = `2`}, delta: `4`
* (T<sub>3</sub>, T<sub>4</sub>]
* dimensions: {pid = `1001`, tid = `1`}, delta: `4`
* dimensions: {pid = `1001`, tid = `2`}, delta: `5`
* attributes: {pid = `1001`, tid = `1`}, delta: `4`
* attributes: {pid = `1001`, tid = `2`}, delta: `5`
* (T<sub>4</sub>, T<sub>5</sub>]
* dimensions: {pid = `1001`, tid = `2`}, delta: `6`
* dimensions: {pid = `1001`, tid = `3`}, delta: `5`
* attributes: {pid = `1001`, tid = `2`}, delta: `6`
* attributes: {pid = `1001`, tid = `3`}, delta: `5`

You can see that we are performing Cumulative->Delta conversion, and it requires
us to remember the last value of **every single permutation we've encountered so
Expand Down Expand Up @@ -368,13 +368,13 @@ collection.

**Limit the memory usage, and handle critical memory condition.** The general
expectation is that a telemetry SDK should not fail the application. This can be
done via some dimension-capping algorithm - e.g. start to combine/drop some data
done via some cardinality-capping algorithm - e.g. start to combine/drop some data
points when the SDK hits the memory limit, and provide a mechanism to report the
data loss.

**Provide configurations to the application owner.** The answer to _"what is an
efficient memory usage"_ is ultimately depending on the goal of the application
owner. For example, the application owners might want to spend more memory in
order to keep more permutations of metrics dimensions, or they might want to use
memory aggressively for certain dimensions that are important, and keep a
conservative limit for dimensions that are less important.
order to keep more permutations of metrics attributes, or they might want to use
memory aggressively for certain attributes that are important, and keep a
conservative limit for attributes that are less important.
4 changes: 2 additions & 2 deletions specification/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ The main classes used to record raw measurements are `Measure` and
`Measurement`. List of `Measurement`s alongside the additional context can be
recorded using OpenTelemetry API. So user may define to aggregate those
`Measurement`s and use the context passed alongside to define additional
dimensions of the resulting metric.
attributes of the resulting metric.

#### Measure

Expand Down Expand Up @@ -311,7 +311,7 @@ the same transaction. This helps to establish a causal relationship between thes
While `Baggage` can be used to prototype other cross-cutting concerns, this mechanism is primarily intended
to convey values for the OpenTelemetry observability systems.

These values can be consumed from `Baggage` and used as additional dimensions for metrics,
These values can be consumed from `Baggage` and used as additional attributes for metrics,
or additional context for logs and traces. Some examples:

- a web service can benefit from including context around what service has sent the request
Expand Down