-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Add source generated metrics doc #45784
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
Merged
Merged
Changes from 12 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
b849816
adding source generated metrics docs
846cce5
updating links in docs/core/diagnostics/source-generated-metrics.md
0ed55f5
renamed as suggested
58653b6
update in doc
dff07e2
fixing docs
f35e3aa
moved code to snippets
f7cfad7
adding missing double quotes
4902730
fixes
ec7ed6e
fix
6f3754e
fix
a898474
fix
fbe0a3d
Apply suggestions from code review
IEvangelist 0aeec01
Apply suggestions from code review
IEvangelist a2839ef
Apply suggestions from code review
IEvangelist a507936
fixes
3d0c5bf
fixes
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| --- | ||
| title: Compile-time metric source generation | ||
| description: Learn how to use a source generator to create metrics in .NET | ||
| ms.date: 04/11/2025 | ||
| --- | ||
|
|
||
| # Compile-time metric source generation | ||
|
|
||
| .NET's metering infrastructure is designed to deliver a highly usable and high-performance metering solution for modern .NET applications. | ||
|
|
||
| To use source-generated metering, create a class that defines the names and dimensions of the metrics your code can produce. Then, create the class with `partial` method signatures. | ||
|
|
||
| The code generator automatically generates the code, which exposes strongly typed metering types and methods that you can invoke to record metric values. The generated methods are implemented in a highly efficient form, which reduces computation overhead as compared to traditional metering solutions. | ||
|
|
||
| ## Get started | ||
|
|
||
| To get started, install the [📦 Microsoft.Extensions.Telemetry.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions) NuGet package: | ||
|
|
||
| ### [.NET CLI](#tab/dotnet-cli) | ||
|
|
||
| ```dotnetcli | ||
| dotnet add package Microsoft.Extensions.Telemetry.Abstractions | ||
| ``` | ||
|
|
||
| ### [PackageReference](#tab/package-reference) | ||
|
|
||
| ```xml | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Extensions.Telemetry.Abstractions" | ||
| Version="*" /> | ||
| </ItemGroup> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
mariamgerges marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| For more information, see [dotnet add package](../tools/dotnet-package-add.md) or [Manage package dependencies in .NET applications](../tools/dependencies.md). | ||
|
|
||
| ## Generic attributes | ||
|
|
||
| Generic attributes require C# 11 or later. For C# 10 or earlier, use nongeneric attributes instead. | ||
|
|
||
| The following example shows a class that declares two metrics. The methods are marked with an attribute and are declared as `static` and `partial`. | ||
| The code generator runs at build time and provides an implementation of these methods, along with accompanying | ||
| types. | ||
|
|
||
| :::code language="csharp" source="snippets/MetricsGen/MetricConstants.cs" id="constants"::: | ||
|
|
||
| The following code demonstrates how to use the generator with primitive types: | ||
|
|
||
| :::code language="csharp" source="snippets/MetricsGen/Metrics.cs" id="metrics" ::: | ||
|
|
||
| The previous declaration automatically returns the following: | ||
|
|
||
| - `Latency` class with a `Record` method | ||
| - `TotalCount` class with an `Add` method | ||
| - `TotalFailures` class with a `Add` method. | ||
|
|
||
| The attributes indicate the set of dimensions that each metric uses. The signature for the generated types looks like this: | ||
|
|
||
| ```csharp | ||
| internal class TotalCount | ||
| { | ||
| public void Add(int value, object? env, object? region, object? requestName, object? requestStatus) | ||
| } | ||
|
|
||
| internal TotalFailures | ||
| { | ||
| public void Add(int value) | ||
| } | ||
|
|
||
| internal class Latency | ||
| { | ||
| public void Record(long value, object? requestName, object? duration); | ||
| } | ||
| ``` | ||
|
|
||
| The dimensions specified in the attributes have been turned into arguments to the `Add` and `Record` methods. You then use the generated methods to create instances of these types. With the instances created, you can call `Add` and `Record` to register metric values, as shown in the following example: | ||
|
|
||
| :::code language="csharp" source="snippets/MetricsGen/MyClass.cs" id ="creation"::: | ||
|
|
||
| ## Metric methods requirements | ||
mariamgerges marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Metric methods are constrained to the following: | ||
|
|
||
| - They must be `public static partial`. | ||
| - The return type must be unique. | ||
| - Their names must not start with an underscore. | ||
| - Their parameter names must not start with an underscore. | ||
| - Their first parameter must be <xref:System.Diagnostics.Metrics.Meter> type. | ||
| Metric methods are constrained to the following: | ||
|
|
||
| ## See also | ||
|
|
||
| For more information on the supported metrics, see [Types of instruments](metrics-instrumentation.md#types-of-instruments) to learn how to choose which instrument to use in different situations. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
docs/core/diagnostics/snippets/MetricsGen/MetricConstants.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| namespace MetricsGen; | ||
|
|
||
| // <constants> | ||
| internal class MetricConstants | ||
| { | ||
| public const string EnvironmentName = "env"; | ||
| public const string Region = "region"; | ||
| public const string RequestName = "requestName"; | ||
| public const string RequestStatus = "requestStatus"; | ||
| } | ||
| // </constants> | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| using Microsoft.Extensions.Diagnostics.Metrics; | ||
|
|
||
| namespace MetricsGen; | ||
|
|
||
| public class MetricTags : MetricParentTags | ||
IEvangelist marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| [TagName("Dim1DimensionName")] | ||
| public string? Dim1; // custom tag name via attribute | ||
| public Operations Operation { get; set; } // tag name defaults to "Operation" | ||
| public MetricChildTags? ChildTagsObject { get; set; } | ||
| } | ||
|
|
||
| public enum Operations | ||
| { | ||
| Unknown = 0, | ||
| Operation1 = 1, | ||
| } | ||
|
|
||
| public class MetricParentTags | ||
| { | ||
| [TagName("DimensionNameOfParentOperation")] | ||
| public string? ParentOperationName { get; set; } // custom tag name via attribute | ||
| public MetricTagsStruct ChildTagsStruct { get; set; } | ||
| } | ||
|
|
||
| public class MetricChildTags | ||
| { | ||
| public string? Dim2 { get; set; } // tag name defaults to "Dim2" | ||
| } | ||
|
|
||
| public struct MetricTagsStruct | ||
| { | ||
| public string Dim3 { get; set; } // tag name defaults to "Dim3" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #define FIRST // FIRST SECOND | ||
|
|
||
| #if FIRST | ||
| // <metrics> | ||
| using System.Diagnostics.Metrics; | ||
| using Microsoft.Extensions.Diagnostics.Metrics; | ||
|
|
||
| namespace MetricsGen; | ||
|
|
||
| internal static partial class Metric | ||
| { | ||
| // an explicit metric name is given | ||
| [Histogram<long>("requestName", "duration", Name = "MyCustomMetricName")] | ||
| public static partial Latency CreateLatency(Meter meter); | ||
|
|
||
| // no explicit metric name given, it is auto-generated from the method name | ||
| [Counter<int>(MetricConstants.EnvironmentName, MetricConstants.Region, MetricConstants.RequestName, MetricConstants.RequestStatus)] | ||
IEvangelist marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| public static partial TotalCount CreateTotalCount(Meter meter); | ||
|
|
||
| [Counter<int>] | ||
| public static partial TotalFailures CreateTotalFailures(this Meter meter); | ||
| } | ||
| // </metrics> | ||
| #elif SECOND | ||
|
|
||
| using MetricsGen; | ||
| // <tags> | ||
| using System.Diagnostics.Metrics; | ||
| using Microsoft.Extensions.Diagnostics.Metrics; | ||
|
|
||
| public static partial class Metric | ||
| { | ||
| [Histogram<long>(typeof(MetricTags))] | ||
| public static partial Latency CreateLatency(Meter meter); | ||
|
|
||
| [Counter<long>(typeof(MetricTags))] | ||
| public static partial TotalCount CreateTotalCount(Meter meter); | ||
|
|
||
| [Counter<int>(typeof(MetricTags))] | ||
| public static partial TotalFailures CreateTotalFailures(Meter meter); | ||
| } | ||
| // </tags> | ||
| #endif | ||
14 changes: 14 additions & 0 deletions
14
docs/core/diagnostics/snippets/MetricsGen/MetricsGen.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Library</OutputType> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.Extensions.Telemetry.Abstractions" Version="9.4.0" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.