|
12 | 12 | * [Pre-Aggregation](#pre-aggregation) |
13 | 13 | * [Cardinality Limits](#cardinality-limits) |
14 | 14 | * [Memory Preallocation](#memory-preallocation) |
| 15 | +* [Metrics Correlation](#metrics-correlation) |
| 16 | +* [Metrics Enrichment](#metrics-enrichment) |
15 | 17 |
|
16 | 18 | </details> |
17 | 19 | <!-- markdownlint-enable MD033 --> |
@@ -138,9 +140,9 @@ Here is the rule of thumb: |
138 | 140 |
|
139 | 141 | > [!NOTE] |
140 | 142 | > When reporting measurements with more than 8 tags, the API allocates memory on |
141 | | -the hot-path. You SHOULD try to keep the number of tags less than or equal to 8. |
142 | | -If you are exceeding this, check if you can model some of the tags as Resource, |
143 | | -as [shown here](#modeling-static-tags-as-resource). |
| 143 | + the hot-path. You SHOULD try to keep the number of tags less than or equal to 8. |
| 144 | + If you are exceeding this, check if you can model some of the tags as Resource, |
| 145 | + as [shown here](#metrics-enrichment). |
144 | 146 |
|
145 | 147 | ## MeterProvider Management |
146 | 148 |
|
@@ -397,12 +399,60 @@ SDK to reclaim unused metric points. |
397 | 399 |
|
398 | 400 | ### Memory Preallocation |
399 | 401 |
|
400 | | -### Modeling static tags as Resource |
| 402 | +OpenTelemetry .NET SDK aims to avoid memory allocation on the hot code path. |
| 403 | +When this is combined with [proper use of Metrics API](#metrics-api), heap |
| 404 | +allocation can be avoided on the hot code path. Refer to the [metrics benchmark |
| 405 | +results](../../test/Benchmarks/Metrics/MetricsBenchmarks.cs) to learn more. |
| 406 | + |
| 407 | +:heavy_check_mark: You should measure memory allocation on hot code path, and |
| 408 | +ideally avoid any heap allocation while using the metrics API and SDK, |
| 409 | +especially when you use metrics to measure the performance of your application |
| 410 | +(for example, you do not want to spend 2 seconds doing [garbage |
| 411 | +collection](https://learn.microsoft.com/dotnet/standard/garbage-collection/) |
| 412 | +while measuring an operation which normally takes 10 milliseconds). |
| 413 | + |
| 414 | +## Metrics Correlation |
| 415 | + |
| 416 | +In OpenTelemetry, metrics can be correlated to [traces](../trace/README.md) via |
| 417 | +[exemplars](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#exemplar). |
| 418 | +Check the [Exemplars](./exemplars/README.md) tutorial to learn more. |
| 419 | + |
| 420 | +## Metrics Enrichment |
| 421 | + |
| 422 | +When the metrics are being collected, they normally get stored in a [time series |
| 423 | +database](https://en.wikipedia.org/wiki/Time_series_database). From storage and |
| 424 | +consumption perspective, metrics can be multi-dimensional. Taking the [fruit |
| 425 | +example](#example), there are two dimensions - "name" and "color". For basic |
| 426 | +scenarios, all the dimensions can be reported during the [Metrics |
| 427 | +API](#metrics-api) invocation, however, for less trivial scenarios, the |
| 428 | +dimensions can come from different sources: |
| 429 | + |
| 430 | +* [Measurements](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#measurement) |
| 431 | + reported via the [Metrics API](#metrics-api). |
| 432 | +* [Resources](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md) |
| 433 | + configured at the `MeterProvider` level. Refer to this |
| 434 | + [doc](./customizing-the-sdk/README.md#resource) for details and examples. |
| 435 | +* Additional attributes provided by the exporter or collector. For example, |
| 436 | + [jobs and instances](https://prometheus.io/docs/concepts/jobs_instances/) in |
| 437 | + Prometheus. |
| 438 | + |
| 439 | +Here is the rule of thumb when modeling the dimensions: |
| 440 | + |
| 441 | +* If the dimension value is static throughout the process lifetime (e.g. the |
| 442 | + name of the machine, data center), model it as Resource, or even better, let |
| 443 | + the collector add these dimensions if feasible (e.g. a collector running in |
| 444 | + the same data center should know the name of the data center, rather than |
| 445 | + relying on / trusting each service instance to report the data center name). |
| 446 | +* If the dimension value is dynamic, report it via the [Metrics |
| 447 | + API](#metrics-api). |
401 | 448 |
|
402 | | -Tags such as `MachineName`, `Environment` etc. which are static throughout the |
403 | | -process lifetime should be be modeled as `Resource`, instead of adding them to |
404 | | -each metric measurement. Refer to this |
405 | | -[doc](./customizing-the-sdk/README.md#resource) for details and examples. |
| 449 | +> [!NOTE] |
| 450 | +> There were discussions around adding a new concept called |
| 451 | + `MeasurementProcessor`, which allows dimensions to be added to / removed from |
| 452 | + measurements dynamically. This idea did not get traction due to the complexity |
| 453 | + and performance implications, refer to this [pull |
| 454 | + request](https://github.com/open-telemetry/opentelemetry-specification/pull/1938) |
| 455 | + for more context. |
406 | 456 |
|
407 | 457 | ## Common issues that lead to missing metrics |
408 | 458 |
|
|
0 commit comments