|
2 | 2 | title: Creating Metrics
|
3 | 3 | description: How to add new metrics to a .NET library or application
|
4 | 4 | ms.topic: tutorial
|
5 |
| -ms.date: 08/27/2024 |
| 5 | +ms.date: 11/19/2024 |
6 | 6 | ---
|
7 | 7 |
|
8 | 8 | # Creating metrics
|
@@ -224,6 +224,11 @@ Types of instruments currently available:
|
224 | 224 | <xref:System.Diagnostics.Metrics.Histogram%601.Record%2A> to record these measurements during the collection tool's update interval: 1,5,2,3,10,9,7,4,6,8. A collection tool
|
225 | 225 | might report that the 50th, 90th, and 95th percentiles of these measurements are 5, 9, and 9 respectively.
|
226 | 226 |
|
| 227 | + > [!NOTE] |
| 228 | + > For details about how to set the recommended bucket boundaries when creating |
| 229 | + > a Histogram instrument see: [Using Advice to customize Histogram |
| 230 | + > instruments](#using-advice-to-customize-histogram-instruments). |
| 231 | +
|
227 | 232 | ### Best practices when selecting an instrument type
|
228 | 233 |
|
229 | 234 | - For counting things, or any other value that solely increases over time, use Counter or ObservableCounter. Choose between Counter and ObservableCounter depending on which
|
@@ -542,6 +547,95 @@ Name Current Value
|
542 | 547 | > [!NOTE]
|
543 | 548 | > OpenTelemetry refers to tags as 'attributes'. These are two different names for the same functionality.
|
544 | 549 |
|
| 550 | +## Using Advice to customize Histogram instruments |
| 551 | + |
| 552 | +When using Histograms, it is the responsibility of the tool or library |
| 553 | +collecting the data to decide how best to represent the distribution of values |
| 554 | +that were recorded. A common strategy (and the [default mode when using |
| 555 | +OpenTelemetry](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#explicit-bucket-histogram-aggregation)) |
| 556 | +is to divide up the range of possible values into sub-ranges called buckets and |
| 557 | +report how many recorded values were in each bucket. For example a tool might |
| 558 | +divide numbers into three buckets, those less than 1, those between 1-10, and |
| 559 | +those greater than 10. If your app recorded the values 0.5, 6, 0.1, 12 then |
| 560 | +there would be two data points the first bucket, one in the second, and one in |
| 561 | +the 3rd. |
| 562 | + |
| 563 | +The tool or library collecting the Histogram data is responsible for defining |
| 564 | +the buckets it will use. The default bucket configuration when using |
| 565 | +OpenTelemetry is: `[ 0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, |
| 566 | +7500, 10000 ]`. |
| 567 | + |
| 568 | +The default values may not lead to the best granularity for every Histogram. For |
| 569 | +example, sub-second request durations would all fall into the `0` bucket. |
| 570 | + |
| 571 | +The tool or library collecting the Histogram data may offer mechanism(s) to |
| 572 | +allow users to customize the bucket configuration. For example, OpenTelemetry |
| 573 | +defines a [View |
| 574 | +API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#view). |
| 575 | +This however requires end user action and makes it the user's responsibility to |
| 576 | +understand the data distribution well enough to choose correct buckets. |
| 577 | + |
| 578 | +To improve the experience the `9.0.0` version of the |
| 579 | +`System.Diagnostics.DiagnosticSource` package introduced the |
| 580 | +(<xref:System.Diagnostics.Metrics.InstrumentAdvice`1>) API. |
| 581 | + |
| 582 | +The `InstrumentAdvice` API may be used by instrumentation authors to specify the |
| 583 | +set of recommended default bucket boundaries for a given Histogram. The tool or |
| 584 | +library collecting the Histogram data can then choose to use those values when |
| 585 | +configuring aggregation leading to a more seamless onboarding experience for |
| 586 | +users. This is supported in the [OpenTelemetry .NET SDK as of version |
| 587 | +1.10.0](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/metrics/customizing-the-sdk#configuring-the-aggregation-of-a-histogram). |
| 588 | + |
| 589 | +> [!IMPORTANT] |
| 590 | +> In general more buckets will lead to more precise data for a given Histogram |
| 591 | +> but each bucket requires memory to store the aggregated details and there is |
| 592 | +> CPU cost to find the correct bucket when processing a measurement. It is |
| 593 | +> important to understand the tradeoffs between precision and CPU/memory |
| 594 | +> consumption when choosing the number of buckets to recommend via the |
| 595 | +> `InstrumentAdvice` API. |
| 596 | +
|
| 597 | +The following code shows an example using the `InstrumentAdvice` API to set |
| 598 | +recommended default buckets. |
| 599 | + |
| 600 | +```csharp |
| 601 | +using System; |
| 602 | +using System.Diagnostics.Metrics; |
| 603 | +using System.Threading; |
| 604 | + |
| 605 | +class Program |
| 606 | +{ |
| 607 | + static Meter s_meter = new Meter("HatCo.Store"); |
| 608 | + static Histogram<double> s_orderProcessingTime = s_meter.CreateHistogram<double>( |
| 609 | + name: "hatco.store.order_processing_time", |
| 610 | + unit: "s", |
| 611 | + description: "Order processing duration", |
| 612 | + advice: new InstrumentAdvice<double> { HistogramBucketBoundaries = [0.01, 0.05, 0.1, 0.5, 1, 5] }); |
| 613 | + |
| 614 | + static Random s_rand = new Random(); |
| 615 | + |
| 616 | + static void Main(string[] args) |
| 617 | + { |
| 618 | + Console.WriteLine("Press any key to exit"); |
| 619 | + while (!Console.KeyAvailable) |
| 620 | + { |
| 621 | + // Pretend our store has one transaction each 100ms |
| 622 | + Thread.Sleep(100); |
| 623 | + |
| 624 | + // Pretend that we measured how long it took to do the transaction (for example we could time it with Stopwatch) |
| 625 | + s_orderProcessingTime.Record(s_rand.Next(5, 15) / 1000.0); |
| 626 | + } |
| 627 | + } |
| 628 | +} |
| 629 | +``` |
| 630 | + |
| 631 | +### Additional information |
| 632 | + |
| 633 | +For more details about explicit bucket Histograms in OpenTelemetry see: |
| 634 | + |
| 635 | +* [Why Histograms?](https://opentelemetry.io/blog/2023/why-histograms/) |
| 636 | + |
| 637 | +* [Histograms vs Summaries](https://opentelemetry.io/blog/2023/histograms-vs-summaries/) |
| 638 | + |
545 | 639 | ## Test custom metrics
|
546 | 640 |
|
547 | 641 | Its possible to test any custom metrics you add using <xref:Microsoft.Extensions.Diagnostics.Metrics.Testing.MetricCollector%601>. This type makes it easy to record the measurements from specific instruments and assert the values were correct.
|
|
0 commit comments