diff --git a/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj
index 96a0b5ad693b3..682198480e815 100644
--- a/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj
+++ b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj b/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj
index 511f970bbb758..1dc474c719eb3 100644
--- a/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj
+++ b/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj
@@ -11,8 +11,8 @@
-
-
+
+
diff --git a/docs/ai/quickstarts/snippets/function-calling/openai/FunctionCallingAI.csproj b/docs/ai/quickstarts/snippets/function-calling/openai/FunctionCallingAI.csproj
index 87423eecfb998..5715db4be3b8c 100644
--- a/docs/ai/quickstarts/snippets/function-calling/openai/FunctionCallingAI.csproj
+++ b/docs/ai/quickstarts/snippets/function-calling/openai/FunctionCallingAI.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj b/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj
index 857a2242e3ed8..062c21dbe91e3 100644
--- a/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj
+++ b/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md
index 71ea580006906..ae0764521affc 100644
--- a/docs/azure/includes/dotnet-all.md
+++ b/docs/azure/includes/dotnet-all.md
@@ -18,7 +18,7 @@
| Communication Email | NuGet [1.0.1](https://www.nuget.org/packages/Azure.Communication.Email/1.0.1)
NuGet [1.1.0-beta.2](https://www.nuget.org/packages/Azure.Communication.Email/1.1.0-beta.2) | [docs](/dotnet/api/overview/azure/Communication.Email-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Email_1.0.1/sdk/communication/Azure.Communication.Email/)
GitHub [1.1.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Email_1.1.0-beta.2/sdk/communication/Azure.Communication.Email/) |
| Communication Identity | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Communication.Identity/1.3.1) | [docs](/dotnet/api/overview/azure/Communication.Identity-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Identity_1.3.1/sdk/communication/Azure.Communication.Identity/) |
| Communication JobRouter | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Communication.JobRouter/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.Communication.JobRouter/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.JobRouter-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.JobRouter_1.0.0/sdk/communication/Azure.Communication.JobRouter/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.JobRouter_1.1.0-beta.1/sdk/communication/Azure.Communication.JobRouter/) |
-| Communication Messages | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Communication.Messages/1.1.0)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.Communication.Messages/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.Messages-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.1.0/sdk/communication/Azure.Communication.Messages/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.2.0-beta.1/sdk/communication/Azure.Communication.Messages/) |
+| Communication Messages | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Communication.Messages/1.1.0)
NuGet [1.3.0-beta.1](https://www.nuget.org/packages/Azure.Communication.Messages/1.3.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.Messages-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.1.0/sdk/communication/Azure.Communication.Messages/)
GitHub [1.3.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.3.0-beta.1/sdk/communication/Azure.Communication.Messages/) |
| Communication Phone Numbers | NuGet [1.3.0](https://www.nuget.org/packages/Azure.Communication.PhoneNumbers/1.3.0) | [docs](/dotnet/api/overview/azure/Communication.PhoneNumbers-readme) | GitHub [1.3.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.PhoneNumbers_1.3.0/sdk/communication/Azure.Communication.PhoneNumbers/) |
| Communication Rooms | NuGet [1.2.0](https://www.nuget.org/packages/Azure.Communication.Rooms/1.2.0) | [docs](/dotnet/api/overview/azure/Communication.Rooms-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Rooms_1.2.0/sdk/communication/Azure.Communication.Rooms/) |
| Communication SMS | NuGet [1.0.1](https://www.nuget.org/packages/Azure.Communication.Sms/1.0.1)
NuGet [1.1.0-beta.2](https://www.nuget.org/packages/Azure.Communication.Sms/1.1.0-beta.2) | [docs](/dotnet/api/overview/azure/Communication.Sms-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Sms_1.0.1/sdk/communication/Azure.Communication.Sms/)
GitHub [1.1.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Sms_1.1.0-beta.2/sdk/communication/Azure.Communication.Sms/) |
@@ -66,7 +66,7 @@
| Maps Geolocation | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Maps.Geolocation/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Maps.Geolocation-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Geolocation_1.0.0-beta.3/sdk/maps/Azure.Maps.Geolocation/) |
| Maps Render | NuGet [2.0.0-beta.1](https://www.nuget.org/packages/Azure.Maps.Rendering/2.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Maps.Rendering-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Rendering_2.0.0-beta.1/sdk/maps/Azure.Maps.Rendering/) |
| Maps Route | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.Maps.Routing/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/Maps.Routing-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Routing_1.0.0-beta.4/sdk/maps/Azure.Maps.Routing/) |
-| Maps Search | NuGet [2.0.0-beta.4](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.4) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.4/sdk/maps/Azure.Maps.Search/) |
+| Maps Search | NuGet [2.0.0-beta.5](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.5) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.5/sdk/maps/Azure.Maps.Search/) |
| Media Analytics Edge | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.Media.Analytics.Edge/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Media.Analytics.Edge-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Media.Analytics.Edge_1.0.0-beta.1/sdk/mediaservices/Azure.Media.Analytics.Edge) |
| Metrics Advisor | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.MetricsAdvisor/1.1.0) | [docs](/dotnet/api/overview/azure/AI.MetricsAdvisor-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.MetricsAdvisor_1.1.0/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/) |
| Microsoft Playwright Testing | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/Developer.MicrosoftPlaywrightTesting.TestLogger-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger_1.0.0-beta.4/sdk/playwrighttesting/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/) |
@@ -502,8 +502,8 @@
| Functions extension for Azure SQL and SQL Server | NuGet [3.1.376](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Sql/3.1.376) | | |
| Functions extension for Cosmos DB | NuGet [4.9.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.CosmosDB/4.9.0) | | GitHub [4.9.0](https://github.com/Azure/azure-webjobs-sdk-extensions/tree/cosmos-v3.0.7/src/WebJobs.Extensions.CosmosDB) |
| Functions extension for DocumentDB | NuGet [1.3.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.DocumentDB/1.3.0) | | GitHub [1.3.0](https://github.com/Azure/azure-webjobs-sdk-extensions) |
-| Functions extension for Durable Task Framework | NuGet [3.0.4](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.DurableTask/3.0.4) | [docs](/dotnet/api/overview/azure/functions) | GitHub [3.0.4](https://github.com/Azure/azure-functions-durable-extension/tree/v2.2.2/src/WebJobs.Extensions.DurableTask) |
-| Functions extension for Durable Task Framework - isolated worker | NuGet [1.2.3](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.DurableTask/1.2.3) | | |
+| Functions extension for Durable Task Framework | NuGet [3.1.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.DurableTask/3.1.0) | [docs](/dotnet/api/overview/azure/functions) | GitHub [3.1.0](https://github.com/Azure/azure-functions-durable-extension/tree/v2.2.2/src/WebJobs.Extensions.DurableTask) |
+| Functions extension for Durable Task Framework - isolated worker | NuGet [1.3.0](https://www.nuget.org/packages/Microsoft.Azure.Functions.Worker.Extensions.DurableTask/1.3.0) | | |
| Functions extension for HTTP | NuGet [3.2.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Http/3.2.0) | | GitHub [3.2.0](https://github.com/Azure/azure-webjobs-sdk-extensions/tree/v3.0.2/src/WebJobs.Extensions.Http) |
| Functions extension for IoT Edge | NuGet [1.0.7](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EdgeHub/1.0.7) | | GitHub [1.0.7](https://github.com/Azure/iotedge/tree/1.0.7/edge-hub) |
| Functions extension for Kafka | NuGet [4.1.0](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.Kafka/4.1.0) | | GitHub [4.1.0](https://github.com/Azure/azure-functions-kafka-extension/tree/3.0.0/src/Microsoft.Azure.WebJobs.Extensions.Kafka) |
diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md
index ad3887e5e52ec..37b815356ef25 100644
--- a/docs/azure/includes/dotnet-new.md
+++ b/docs/azure/includes/dotnet-new.md
@@ -18,7 +18,7 @@
| Communication Email | NuGet [1.0.1](https://www.nuget.org/packages/Azure.Communication.Email/1.0.1)
NuGet [1.1.0-beta.2](https://www.nuget.org/packages/Azure.Communication.Email/1.1.0-beta.2) | [docs](/dotnet/api/overview/azure/Communication.Email-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Email_1.0.1/sdk/communication/Azure.Communication.Email/)
GitHub [1.1.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Email_1.1.0-beta.2/sdk/communication/Azure.Communication.Email/) |
| Communication Identity | NuGet [1.3.1](https://www.nuget.org/packages/Azure.Communication.Identity/1.3.1) | [docs](/dotnet/api/overview/azure/Communication.Identity-readme) | GitHub [1.3.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Identity_1.3.1/sdk/communication/Azure.Communication.Identity/) |
| Communication JobRouter | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Communication.JobRouter/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.Communication.JobRouter/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.JobRouter-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.JobRouter_1.0.0/sdk/communication/Azure.Communication.JobRouter/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.JobRouter_1.1.0-beta.1/sdk/communication/Azure.Communication.JobRouter/) |
-| Communication Messages | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Communication.Messages/1.1.0)
NuGet [1.2.0-beta.1](https://www.nuget.org/packages/Azure.Communication.Messages/1.2.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.Messages-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.1.0/sdk/communication/Azure.Communication.Messages/)
GitHub [1.2.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.2.0-beta.1/sdk/communication/Azure.Communication.Messages/) |
+| Communication Messages | NuGet [1.1.0](https://www.nuget.org/packages/Azure.Communication.Messages/1.1.0)
NuGet [1.3.0-beta.1](https://www.nuget.org/packages/Azure.Communication.Messages/1.3.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.Messages-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.1.0/sdk/communication/Azure.Communication.Messages/)
GitHub [1.3.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Messages_1.3.0-beta.1/sdk/communication/Azure.Communication.Messages/) |
| Communication Network Traversal | NuGet [1.0.0](https://www.nuget.org/packages/Azure.Communication.NetworkTraversal/1.0.0)
NuGet [1.1.0-beta.1](https://www.nuget.org/packages/Azure.Communication.NetworkTraversal/1.1.0-beta.1) | [docs](/dotnet/api/overview/azure/Communication.NetworkTraversal-readme) | GitHub [1.0.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.NetworkTraversal_1.0.0/sdk/communication/Azure.Communication.NetworkTraversal/)
GitHub [1.1.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.NetworkTraversal_1.1.0-beta.1/sdk/communication/Azure.Communication.NetworkTraversal/) |
| Communication Phone Numbers | NuGet [1.3.0](https://www.nuget.org/packages/Azure.Communication.PhoneNumbers/1.3.0) | [docs](/dotnet/api/overview/azure/Communication.PhoneNumbers-readme) | GitHub [1.3.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.PhoneNumbers_1.3.0/sdk/communication/Azure.Communication.PhoneNumbers/) |
| Communication Rooms | NuGet [1.2.0](https://www.nuget.org/packages/Azure.Communication.Rooms/1.2.0) | [docs](/dotnet/api/overview/azure/Communication.Rooms-readme) | GitHub [1.2.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Communication.Rooms_1.2.0/sdk/communication/Azure.Communication.Rooms/) |
@@ -67,7 +67,7 @@
| Maps Geolocation | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Maps.Geolocation/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Maps.Geolocation-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Geolocation_1.0.0-beta.3/sdk/maps/Azure.Maps.Geolocation/) |
| Maps Render | NuGet [2.0.0-beta.1](https://www.nuget.org/packages/Azure.Maps.Rendering/2.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Maps.Rendering-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Rendering_2.0.0-beta.1/sdk/maps/Azure.Maps.Rendering/) |
| Maps Route | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.Maps.Routing/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/Maps.Routing-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Routing_1.0.0-beta.4/sdk/maps/Azure.Maps.Routing/) |
-| Maps Search | NuGet [2.0.0-beta.4](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.4) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.4/sdk/maps/Azure.Maps.Search/) |
+| Maps Search | NuGet [2.0.0-beta.5](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.5) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.5](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.5/sdk/maps/Azure.Maps.Search/) |
| Media Analytics Edge | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.Media.Analytics.Edge/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Media.Analytics.Edge-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Media.Analytics.Edge_1.0.0-beta.1/sdk/mediaservices/Azure.Media.Analytics.Edge) |
| Metrics Advisor | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.MetricsAdvisor/1.1.0) | [docs](/dotnet/api/overview/azure/AI.MetricsAdvisor-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.MetricsAdvisor_1.1.0/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/) |
| Microsoft Playwright Testing | NuGet [1.0.0-beta.4](https://www.nuget.org/packages/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/1.0.0-beta.4) | [docs](/dotnet/api/overview/azure/Developer.MicrosoftPlaywrightTesting.TestLogger-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.4](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger_1.0.0-beta.4/sdk/playwrighttesting/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/) |
diff --git a/docs/core/diagnostics/diagnostics-in-containers.md b/docs/core/diagnostics/diagnostics-in-containers.md
index 1c7143d3e5315..3c60b1740cd52 100644
--- a/docs/core/diagnostics/diagnostics-in-containers.md
+++ b/docs/core/diagnostics/diagnostics-in-containers.md
@@ -1,33 +1,45 @@
---
-title: Collect diagnostics in containers
-description: Learn how .NET diagnostics tools for gathering performance traces and collecting dumps can be used in Docker containers.
-ms.date: 09/01/2020
+title: Collect diagnostics in Linux containers
+description: Learn how .NET diagnostics tools for gathering performance traces and collecting dumps can be used in Linux containers.
+ms.date: 04/16/2025
---
-# Collect diagnostics in containers
+# Collect diagnostics in Linux containers
-The same diagnostics tools that are useful for diagnosing .NET issues in other scenarios also work in Docker containers. However, some of the tools require special steps to work in a container. This article covers how tools for gathering performance traces and collecting dumps can be used in Docker containers.
+The same diagnostics tools that are useful for diagnosing .NET issues in other scenarios also work in containers. The tools can be run in the same container as the target process, from the host, or from a sidecar container.
## Use .NET CLI tools in a container
**These tools apply to: ✔️** .NET Core 3.1 SDK and later versions
-The .NET global CLI diagnostic tools ([dotnet-counters](dotnet-counters.md), [dotnet-dump](dotnet-dump.md), [dotnet-gcdump](dotnet-gcdump.md), [dotnet-monitor](dotnet-monitor.md), and [dotnet-trace](dotnet-trace.md)) are designed to work in a wide variety of environments and should all work directly in Docker containers. Because of this, these tools are the preferred method of collecting diagnostic information for .NET scenarios targeting .NET Core 3.1 or later in containers.
+All of the [dotnet-* CLI diagnostic tools](tools-overview.md#cli-tools) can work when run within the same container as the application they are inspecting but beware these potential trouble spots:
-You can also install these tools without the .NET SDK by downloading the single-file variants from the links in the previous paragraph. These installs require a global install of the .NET runtime version 3.1 or later, which you can acquire following any of the prescribed methods in the [.NET installation documentation](../install/index.yml) or by consuming any of the official runtime containers.
+- Tools run inside a container will be subject to container resource limits. The tools may run slowly or fail if the resource limits are too low. Most of the tools have modest requirements but `dotnet-dump` and `dotnet-gcdump` can use considerable memory and disk space when targeting a process that has a large memory footprint. `dotnet-trace` and `dotnet-counters` might also create large files if they are configured to capture a large amount of trace events or metric time-series data.
+- `dotnet-dump` will cause a helper process to run that needs ptrace permissions. Linux has numerous security configuration options that can affect whether this is successful so in some cases you may need to adjust the container's security configuration. See the [dump FAQ](faq-dumps.yml) for more guidance on diagnosing security privileges.
+- When running tools inside the container you can either install them in advance when building the container or download them on-demand. Installing them in advance makes it easier when you need them but increases the size of the container and creates a larger attack surface that malicious actors could attempt to exploit.
-### Use .NET global CLI tools in a sidecar container
+## Use .NET CLI tools in a sidecar container or from the host
-If you would like to use .NET global CLI diagnostic tools to diagnose processes in a different container, bear the following additional requirements in mind:
+The [dotnet-* CLI diagnostic tools](tools-overview.md#cli-tools) also support running from the host or in a sidecar container. This largely avoids the size, security, and resource limitations of running in the same container but has some additional requirements for the tools to communicate successfully.
-1. The containers must [share a process namespace](https://docs.docker.com/reference/cli/docker/container/run/#pid) (so that tools in the sidecar container can access processes in the target container).
-2. The .NET global CLI diagnostic tools need access to files the .NET runtime writes to the /tmp directory, so the /tmp directory must be shared between the target and sidecar container via a volume mount. This could be done, for example, by having the containers share a common [volume](https://docs.docker.com/storage/volumes/#create-and-manage-volumes) or a Kubernetes [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume. If you attempt to use the diagnostic tools from a sidecar container without sharing the /tmp directory, you will get an error about the process "not running compatible .NET runtime."
+When identifying a target process to inspect using the `--process-id` or `--name` tool command-line arguments, this requires:
+
+1. The containers must [share a process namespace](https://docs.docker.com/reference/cli/docker/container/run/#pid) so that tools in the sidecar container can access processes in the target container.
+2. The tools need access to the [diagnostic port](diagnostic-port.md) Unix Domain Socket which the .NET runtime writes to the */tmp* directory, so the */tmp* directory must be shared between the target and sidecar container via a volume mount. This could be done, for example, by having the containers share a common [volume](https://docs.docker.com/storage/volumes/#create-and-manage-volumes) or a Kubernetes [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume. If you attempt to use the diagnostic tools from a sidecar container without sharing the */tmp* directory, you will get an error about the process "not running compatible .NET runtime."
+
+If you don't want to share process namespace and the */tmp* directory, many of the tools also support a more advanced `--diagnostic-port` command-line option. This allows you to directly specify the path to the target process' [diagnostic port](diagnostic-port.md) within the filesystem of the host or sidecar. The target container's /tmp directory will need to be mapped somewhere for this path to exist, but it doesn't have to be shared with the host or sidecar */tmp*.
+
+> [!NOTE]
+> Even when running the diagnostic tools from the host or sidecar, the target process may still be requested to do work which increases its resource usage inside the target container. We have observed dotnet-dump may cause the target process to page in substantial virtual memory when collecting a dump. Other tools may cause smaller impacts though we haven't seen these cause problems in practice. For example, `dotnet-trace` requests the target process to allocate an event buffer and `dotnet-counters` requests a small memory region where metric data is aggregated. We recommend testing to ensure your memory limits aren't so tight that running the tools causes the OS to terminate your containers.
+
+> [!NOTE]
+> When `dotnet-dump` writes a dump file to disk, the output path is interpreted in the context of the target process' view of the file system. This may differ from the host or sidecar container.
## Use `PerfCollect` in a container
**This tool applies to: ✔️** .NET Core 2.1 and later versions
-The [`PerfCollect`](./trace-perfcollect-lttng.md) script is useful for collecting performance traces and is the recommended tool for collecting traces prior to .NET Core 3.0. If using `PerfCollect` in a container, keep the following requirements in mind:
+The [`PerfCollect`](./trace-perfcollect-lttng.md) script is useful for collecting performance traces that contain kernel events such as CPU samples or context switches. If using `PerfCollect` in a container, keep the following requirements in mind:
- `PerfCollect` requires additional capabilities to run the `perf` tool. The minimal set of capabilities required is [`PERFMON`](https://man7.org/linux/man-pages/man7/capabilities.7.html) and [`SYS_PTRACE`](https://man7.org/linux/man-pages/man7/capabilities.7.html). Some environments require [`SYS_ADMIN`](https://man7.org/linux/man-pages/man7/capabilities.7.html). Be sure to start the container with [the necessary capabilities](https://docs.docker.com/engine/security/#linux-kernel-capabilities). If the minimal set doesn't work, then try with the full set.
diff --git a/docs/core/diagnostics/metrics-generator.md b/docs/core/diagnostics/metrics-generator.md
new file mode 100644
index 0000000000000..cd340a1b9d1ed
--- /dev/null
+++ b/docs/core/diagnostics/metrics-generator.md
@@ -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 source 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
+
+
+
+```
+
+---
+
+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 three 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
+
+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 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.
diff --git a/docs/core/diagnostics/metrics-strongly-typed.md b/docs/core/diagnostics/metrics-strongly-typed.md
index 2d3fe8defb655..d2871191458c1 100644
--- a/docs/core/diagnostics/metrics-strongly-typed.md
+++ b/docs/core/diagnostics/metrics-strongly-typed.md
@@ -11,95 +11,56 @@ Modern .NET applications can capture metrics using the [!NOTE]
> In the context of metrics, a tag is sometimes also called a "dimension." This article uses "tag" for clarity and consistency with .NET metrics terminology.
-## Tag name defaults and customization
-
-By default, the source generator derives metric tag names from the field and property names of your tag class. In other words, each public field or property in the strongly-typed tag object becomes a tag name by default. You can override this by using the on a field or property to specify a custom tag name. In the examples below, you’ll see both approaches in action.
+## Get started
-## Example 1: Basic metric with a single tag
+To get started, install the [📦 Microsoft.Extensions.Telemetry.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions) NuGet package:
-The following example demonstrates a simple counter metric with one tag. In this scenario, we want to count the number of processed requests and categorize them by a `Region` tag:
+### [.NET CLI](#tab/dotnet-cli)
-```csharp
-public struct RequestTags
-{
- public string Region { get; set; }
-}
-
-public static partial class MyMetrics
-{
- [Counter(typeof(RequestTags))]
- public static partial RequestCount CreateRequestCount(Meter meter);
-}
+```dotnetcli
+dotnet add package Microsoft.Extensions.Telemetry.Abstractions
```
-In the code above, `RequestTags` is a strongly-typed tag struct with a single property `Region`. The `CreateRequestCount` method is marked with where `T` is an `int`, indicating it generates a **Counter** instrument that tracks `int` values. The attribute references `typeof(RequestTags)`, meaning the counter will use the tags defined in `RequestTags` when recording metrics. The source generator will produce a strongly-typed instrument class (named `RequestCount`) with an `Add` method that accepts integer value and `RequestTags` object.
+### [PackageReference](#tab/package-reference)
-To use the generated metric, create a and record measurements as shown below:
+```xml
+
+
+
+```
-```csharp
-Meter meter = new Meter("MyCompany.MyApp", "1.0");
-RequestCount requestCountMetric = MyMetrics.CreateRequestCount(meter);
+---
-// Create a tag object with the relevant tag value
-var tags = new RequestTags { Region = "NorthAmerica" };
+For more information, see [dotnet add package](../tools/dotnet-package-add.md) or [Manage package dependencies in .NET applications](../tools/dependencies.md).
-// Record a metric value with the associated tag
-requestCountMetric.Add(1, tags);
-```
-
-In this usage example, calling `MyMetrics.CreateRequestCount(meter)` creates a counter instrument (via the `Meter`) and returns a `RequestCount` metric object. When you call `requestCountMetric.Add(1, tags)`, the metric system records a count of 1 associated with the tag `Region="NorthAmerica"`. You can reuse the `RequestTags` object or create new ones to record counts for different regions, and the tag name `Region` will consistently be applied to every measurement.
+## Tag name defaults and customization
-## Example 2: Metric with nested tag objects
+By default, the source generator derives metric tag names from the field and property names of your tag class. In other words, each public field or property in the strongly-typed tag object becomes a tag name by default. You can override this by using the on a field or property to specify a custom tag name. In the examples below, you’ll see both approaches in action.
-For more complex scenarios, you can define tag classes that include multiple tags, nested objects, or even inherited properties. This allows a group of related metrics to share a common set of tags easily. In the next example, we define a set of tag classes and use them for three different metrics:
+## Example 1: Basic metric with a single tag
-```csharp
-public class MetricTags : MetricParentTags
-{
- [TagName("Dim1DimensionName")]
- public string? Dim1; // custom tag name via attribute
+The following example demonstrates a simple counter metric with one tag. In this scenario, we want to count the number of processed requests and categorize them by a `Region` tag:
- public Operations Operation { get; set; } // tag name defaults to "Operation"
+:::code language="csharp" source="snippets/MetricsGen/MyMetrics.cs" id= "tag":::
- public MetricChildTags? ChildTagsObject { get; set; }
-}
+In the preceding code, `RequestTags` is a strongly-typed tag struct with a single property `Region`. The `CreateRequestCount` method is marked with where `T` is an `int`, indicating it generates a `Counter` instrument that tracks `int` values. The attribute references `typeof(RequestTags)`, meaning the counter uses the tags defined in `RequestTags` when recording metrics. The source generator produces a strongly-typed instrument class (named `RequestCount`) with an `Add` method that accepts integer value and `RequestTags` object.
-public enum Operations
-{
- Unknown = 0,
- Operation1 = 1,
-}
+To use the generated metric, create a and record measurements as shown below:
-public class MetricParentTags
-{
- [TagName("DimensionNameOfParentOperation")]
- public string? ParentOperationName { get; set; } // custom tag name via attribute
+:::code language="csharp" source="snippets/MetricsGen/MyClass.cs" id ="tag":::
- public MetricTagsStruct ChildTagsStruct { get; set; }
-}
+In this usage example, calling `MyMetrics.CreateRequestCount(meter)` creates a counter instrument (via the `Meter`) and returns a `RequestCount` metric object. When you call `requestCountMetric.Add(1, tags)`, the metric system records a count of 1 associated with the tag `Region="NorthAmerica"`. You can reuse the `RequestTags` object or create new ones to record counts for different regions, and the tag name `Region` will consistently be applied to every measurement.
-public class MetricChildTags
-{
- public string? Dim2 { get; set; } // tag name defaults to "Dim2"
-}
+## Example 2: Metric with nested tag objects
-public struct MetricTagsStruct
-{
- public string Dim3 { get; set; } // tag name defaults to "Dim3"
-}
+For more complex scenarios, you can define tag classes that include multiple tags, nested objects, or even inherited properties. This allows a group of related metrics to effectively share a common set of tags. In the next example, you define a set of tag classes and use them for three different metrics:
-public static partial class Metric
-{
- [Histogram(typeof(MetricTags))]
- public static partial Latency CreateLatency(Meter meter);
+:::code language="csharp" source="snippets/MetricsGen/MetricTags.cs" :::
- [Counter(typeof(MetricTags))]
- public static partial TotalCount CreateTotalCount(Meter meter);
+The preceding code defines the metric inheritance and object shapes. The following code demonstrates how to use these shapes with the generator, as shown in the `Metric` class:
- [Counter(typeof(MetricTags))]
- public static partial TotalFailures CreateTotalFailures(Meter meter);
-}
-```
+:::code language="csharp" source="snippets/MetricsGen/Metrics.cs" id="tags" :::
In this example, `MetricTags` is a tag class that inherits from `MetricParentTags` and also contains a nested tag object (`MetricChildTags`) and a nested struct (`MetricTagsStruct`). The tag properties demonstrate both default and customized tag names:
@@ -113,55 +74,7 @@ All three metric definitions `CreateLatency`, `CreateTotalCount`, and `CreateTot
The following code shows how to create and use these metrics in a class:
-```csharp
-internal class MyClass
-{
- private readonly Latency _latencyMetric;
- private readonly TotalCount _totalCountMetric;
- private readonly TotalFailures _totalFailuresMetric;
-
- public MyClass(Meter meter)
- {
- // Create metric instances using the source-generated factory methods
- _latencyMetric = Metric.CreateLatency(meter);
- _totalCountMetric = Metric.CreateTotalCount(meter);
- _totalFailuresMetric = Metric.CreateTotalFailures(meter);
- }
-
- public void DoWork()
- {
- var stopwatch = new Stopwatch();
- stopwatch.Start();
- bool requestSuccessful = true;
- // ... perform some operation ...
- stopwatch.Stop();
-
- // Create a tag object with values for all tags
- var tags = new MetricTags
- {
- Dim1 = "Dim1Value",
- Operation = Operations.Operation1,
- ParentOperationName = "ParentOpValue",
- ChildTagsObject = new MetricChildTags
- {
- Dim2 = "Dim2Value",
- },
- ChildTagsStruct = new MetricTagsStruct
- {
- Dim3 = "Dim3Value"
- }
- };
-
- // Record the metric values with the associated tags
- _latencyMetric.Record(stopwatch.ElapsedMilliseconds, tags);
- _totalCountMetric.Add(1, tags);
- if (!requestSuccessful)
- {
- _totalFailuresMetric.Add(1, tags);
- }
- }
-}
-```
+:::code language="csharp" source="snippets/MetricsGen/MyClass.cs" id ="creationwithtags":::
In the preceding `MyClass.DoWork` method, a `MetricTags` object is populated with values for each tag. This single `tags` object is then passed to all three instruments when recording data. The `Latency` metric (a histogram) records the elapsed time, and both counters (`TotalCount` and `TotalFailures`) record occurrence counts. Because all metrics share the same tag object type, the tags (`Dim1DimensionName`, `Operation`, `Dim2`, `Dim3`, `DimensionNameOfParentOperation`) are present on every measurement.
@@ -184,6 +97,7 @@ Adhering to these requirements ensures that the source generator can successfull
## See also
+- [Source generated metrics in .NET](metrics-generator.md)
- [Creating metrics in .NET (Instrumentation tutorial)](metrics-instrumentation.md)
- [Collecting metrics in .NET (Using MeterListener and exporters)](metrics-collection.md)
- [Logging source generation in .NET](../extensions/logger-message-generator.md) (for a similar source-generation approach applied to logging)
diff --git a/docs/core/diagnostics/metrics.md b/docs/core/diagnostics/metrics.md
index a383d3321b3e5..d87498f4cf497 100644
--- a/docs/core/diagnostics/metrics.md
+++ b/docs/core/diagnostics/metrics.md
@@ -28,6 +28,7 @@ There are two parts to using metrics in a .NET app:
- [Instrumentation tutorial](metrics-instrumentation.md) - How to create new metrics in code
- [Collection tutorial](metrics-collection.md) - How to store and view metric data for your app
+- [Source generated metrics](metrics-generator.md) - How to use source generator to create metrics
- [Source-generated metrics with strongly-typed tags](metrics-strongly-typed.md) - How to use source-generated metrics with strongly-typed tags
- [Built-in metrics](built-in-metrics.md) - Discover metrics that are ready for use in .NET runtime libraries
- [Compare metric APIs](compare-metric-apis.md)
diff --git a/docs/core/diagnostics/snippets/MetricsGen/MetricConstants.cs b/docs/core/diagnostics/snippets/MetricsGen/MetricConstants.cs
new file mode 100644
index 0000000000000..066fd6072af11
--- /dev/null
+++ b/docs/core/diagnostics/snippets/MetricsGen/MetricConstants.cs
@@ -0,0 +1,12 @@
+namespace MetricsGen;
+
+//
+internal class MetricConstants
+{
+ public const string EnvironmentName = "env";
+ public const string Region = "region";
+ public const string RequestName = "requestName";
+ public const string RequestStatus = "requestStatus";
+}
+//
+
diff --git a/docs/core/diagnostics/snippets/MetricsGen/MetricTags.cs b/docs/core/diagnostics/snippets/MetricsGen/MetricTags.cs
new file mode 100644
index 0000000000000..adf4305cdf7e9
--- /dev/null
+++ b/docs/core/diagnostics/snippets/MetricsGen/MetricTags.cs
@@ -0,0 +1,34 @@
+using Microsoft.Extensions.Diagnostics.Metrics;
+
+namespace MetricsGen;
+
+public class MetricTags : MetricParentTags
+{
+ [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"
+}
diff --git a/docs/core/diagnostics/snippets/MetricsGen/Metrics.cs b/docs/core/diagnostics/snippets/MetricsGen/Metrics.cs
new file mode 100644
index 0000000000000..95ef6f3739127
--- /dev/null
+++ b/docs/core/diagnostics/snippets/MetricsGen/Metrics.cs
@@ -0,0 +1,47 @@
+#define FIRST // FIRST SECOND
+
+#if FIRST
+//
+using System.Diagnostics.Metrics;
+using Microsoft.Extensions.Diagnostics.Metrics;
+
+namespace MetricsGen;
+
+internal static partial class Metric
+{
+ // an explicit metric name is given
+ [Histogram("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(
+ MetricConstants.EnvironmentName,
+ MetricConstants.Region,
+ MetricConstants.RequestName,
+ MetricConstants.RequestStatus)]
+ public static partial TotalCount CreateTotalCount(Meter meter);
+
+ [Counter]
+ public static partial TotalFailures CreateTotalFailures(this Meter meter);
+}
+//
+#elif SECOND
+
+using MetricsGen;
+//
+using System.Diagnostics.Metrics;
+using Microsoft.Extensions.Diagnostics.Metrics;
+
+public static partial class Metric
+{
+ [Histogram(typeof(MetricTags))]
+ public static partial Latency CreateLatency(Meter meter);
+
+ [Counter(typeof(MetricTags))]
+ public static partial TotalCount CreateTotalCount(Meter meter);
+
+ [Counter(typeof(MetricTags))]
+ public static partial TotalFailures CreateTotalFailures(Meter meter);
+}
+//
+#endif
diff --git a/docs/core/diagnostics/snippets/MetricsGen/MetricsGen.csproj b/docs/core/diagnostics/snippets/MetricsGen/MetricsGen.csproj
new file mode 100644
index 0000000000000..322d2afb6d583
--- /dev/null
+++ b/docs/core/diagnostics/snippets/MetricsGen/MetricsGen.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Library
+ net9.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/docs/core/diagnostics/snippets/MetricsGen/MyClass.cs b/docs/core/diagnostics/snippets/MetricsGen/MyClass.cs
new file mode 100644
index 0000000000000..0457511aa8889
--- /dev/null
+++ b/docs/core/diagnostics/snippets/MetricsGen/MyClass.cs
@@ -0,0 +1,126 @@
+#define FIRST // FIRST SECOND THIRD
+#if FIRST
+using System.Diagnostics.Metrics;
+
+namespace MetricsGen;
+
+//
+internal class MyClass
+{
+ // these variable are for example purposes, the dimensions values should depend on your business logic.
+ private string envName = "envValue";
+ private string regionName = "regionValue";
+ private string requestName = "requestNameValue";
+ private string status = "requestStatusValue";
+ private string duration = "1:00:00";
+
+ private readonly Latency _latencyMetric;
+ private readonly TotalCount _totalCountMetric;
+ private readonly TotalFailures _totalFailuresMetric;
+
+ public MyClass(Meter meter)
+ {
+ // Create metric instances using the source-generated factory methods
+ _latencyMetric = Metric.CreateLatency(meter);
+ _totalCountMetric = Metric.CreateTotalCount(meter);
+ // This syntax is available since `CreateTotalFailures` is defined as an extension method
+ _totalFailuresMetric = meter.CreateTotalFailures();
+ }
+
+ public void ReportSampleRequestCount()
+ {
+ // method logic ...
+
+ // Invoke Add on the counter and pass the dimension values you need.
+ _totalCountMetric.Add(1, envName, regionName, requestName, status);
+ }
+
+ public void ReportSampleLatency()
+ {
+ // method logic ...
+
+ // Invoke Record on the histogram and pass the dimension values you need.
+ _latencyMetric.Record(1, requestName, duration);
+ }
+
+ public void ReportSampleFailuresCount()
+ {
+ // method logic ...
+
+ // Invoke Add on the counter and pass the dimension values you need.
+ _totalFailuresMetric.Add(1);
+ }
+}
+//
+
+#elif SECOND
+
+using System.Diagnostics;
+using System.Diagnostics.Metrics;
+using MetricsGen;
+
+//
+internal class MyClass
+{
+ private readonly Latency _latencyMetric;
+ private readonly TotalCount _totalCountMetric;
+ private readonly TotalFailures _totalFailuresMetric;
+
+ public MyClass(Meter meter)
+ {
+ // Create metric instances using the source-generated factory methods
+ _latencyMetric = Metric.CreateLatency(meter);
+ _totalCountMetric = Metric.CreateTotalCount(meter);
+ _totalFailuresMetric = Metric.CreateTotalFailures(meter);
+ }
+
+ public void DoWork()
+ {
+ var startingTimestamp = Stopwatch.GetTimestamp();
+ bool requestSuccessful = true;
+ // Perform some operation to measure
+ var elapsedTime = Stopwatch.GetElapsedTime(startingTimestamp);
+
+ // Create a tag object with values for all tags
+ var tags = new MetricTags
+ {
+ Dim1 = "Dim1Value",
+ Operation = Operations.Operation1,
+ ParentOperationName = "ParentOpValue",
+ ChildTagsObject = new MetricChildTags
+ {
+ Dim2 = "Dim2Value",
+ },
+ ChildTagsStruct = new MetricTagsStruct
+ {
+ Dim3 = "Dim3Value"
+ }
+ };
+
+ // Record the metric values with the associated tags
+ _latencyMetric.Record(elapsedTime.ElapsedMilliseconds, tags);
+ _totalCountMetric.Add(1, tags);
+ if (!requestSuccessful)
+ {
+ _totalFailuresMetric.Add(1, tags);
+ }
+ }
+}
+//
+#elif THIRD
+
+using MetricsGen;
+using System.Diagnostics.Metrics;
+
+//
+Meter meter = new("MyCompany.MyApp", "1.0");
+RequestCount requestCountMetric = MyMetrics.CreateRequestCount(meter);
+
+// Create a tag object with the relevant tag value
+var tags = new RequestTags { Region = "NorthAmerica" };
+
+// Record a metric value with the associated tag
+requestCountMetric.Add(1, tags);
+
+//
+#endif
diff --git a/docs/core/diagnostics/snippets/MetricsGen/MyMetrics.cs b/docs/core/diagnostics/snippets/MetricsGen/MyMetrics.cs
new file mode 100644
index 0000000000000..870da3cce32bf
--- /dev/null
+++ b/docs/core/diagnostics/snippets/MetricsGen/MyMetrics.cs
@@ -0,0 +1,16 @@
+using System.Diagnostics.Metrics;
+using Microsoft.Extensions.Diagnostics.Metrics;
+
+namespace MetricsGen;
+//
+public struct RequestTags
+{
+ public string Region { get; set; }
+}
+
+public static partial class MyMetrics
+{
+ [Counter(typeof(RequestTags))]
+ public static partial RequestCount CreateRequestCount(Meter meter);
+}
+//
diff --git a/docs/core/diagnostics/snippets/Microsoft.Diagnostics.NETCore.Client/csharp/Microsoft.Diagnostics.NETCore.Client.Samples.csproj b/docs/core/diagnostics/snippets/Microsoft.Diagnostics.NETCore.Client/csharp/Microsoft.Diagnostics.NETCore.Client.Samples.csproj
index 917de7a3edaf7..c6455cc1d11ee 100644
--- a/docs/core/diagnostics/snippets/Microsoft.Diagnostics.NETCore.Client/csharp/Microsoft.Diagnostics.NETCore.Client.Samples.csproj
+++ b/docs/core/diagnostics/snippets/Microsoft.Diagnostics.NETCore.Client/csharp/Microsoft.Diagnostics.NETCore.Client.Samples.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/docs/core/extensions/snippets/ai/AI.Shared/AI.Shared.csproj b/docs/core/extensions/snippets/ai/AI.Shared/AI.Shared.csproj
index b712edbad894f..87a26052eb37c 100644
--- a/docs/core/extensions/snippets/ai/AI.Shared/AI.Shared.csproj
+++ b/docs/core/extensions/snippets/ai/AI.Shared/AI.Shared.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/docs/core/extensions/snippets/ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj b/docs/core/extensions/snippets/ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj
index 48801c052aec2..6d87d65be1031 100644
--- a/docs/core/extensions/snippets/ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj
+++ b/docs/core/extensions/snippets/ai/ConsoleAI.CacheResponses/ConsoleAI.CacheResponses.csproj
@@ -1,4 +1,4 @@
-
+
Exe
@@ -8,7 +8,7 @@
-
+
diff --git a/docs/core/extensions/snippets/ai/ConsoleAI.ConsumeClientMiddleware/ConsoleAI.ConsumeClientMiddleware.csproj b/docs/core/extensions/snippets/ai/ConsoleAI.ConsumeClientMiddleware/ConsoleAI.ConsumeClientMiddleware.csproj
index 4bda88e2c053a..bec56340237d7 100644
--- a/docs/core/extensions/snippets/ai/ConsoleAI.ConsumeClientMiddleware/ConsoleAI.ConsumeClientMiddleware.csproj
+++ b/docs/core/extensions/snippets/ai/ConsoleAI.ConsumeClientMiddleware/ConsoleAI.ConsumeClientMiddleware.csproj
@@ -1,4 +1,4 @@
-
+
Exe
@@ -8,7 +8,7 @@
-
+
diff --git a/docs/core/extensions/snippets/ai/ConsoleAI.CustomEmbeddingsMiddle/ConsoleAI.CustomEmbeddingsMiddle.csproj b/docs/core/extensions/snippets/ai/ConsoleAI.CustomEmbeddingsMiddle/ConsoleAI.CustomEmbeddingsMiddle.csproj
index 1688c6ce81f3c..354ee27b280e2 100644
--- a/docs/core/extensions/snippets/ai/ConsoleAI.CustomEmbeddingsMiddle/ConsoleAI.CustomEmbeddingsMiddle.csproj
+++ b/docs/core/extensions/snippets/ai/ConsoleAI.CustomEmbeddingsMiddle/ConsoleAI.CustomEmbeddingsMiddle.csproj
@@ -1,4 +1,4 @@
-
+
Exe
@@ -8,7 +8,7 @@
-
+
diff --git a/docs/core/extensions/snippets/ai/ConsoleAI.DependencyInjection/ConsoleAI.DependencyInjection.csproj b/docs/core/extensions/snippets/ai/ConsoleAI.DependencyInjection/ConsoleAI.DependencyInjection.csproj
index 0b19a4cfb8fe7..4ac04759c2475 100644
--- a/docs/core/extensions/snippets/ai/ConsoleAI.DependencyInjection/ConsoleAI.DependencyInjection.csproj
+++ b/docs/core/extensions/snippets/ai/ConsoleAI.DependencyInjection/ConsoleAI.DependencyInjection.csproj
@@ -1,4 +1,4 @@
-
+
Exe
@@ -8,8 +8,8 @@
-
-
+
+
diff --git a/docs/core/extensions/snippets/ai/ConsoleAI.FunctionalityPipelines/ConsoleAI.FunctionalityPipelines.csproj b/docs/core/extensions/snippets/ai/ConsoleAI.FunctionalityPipelines/ConsoleAI.FunctionalityPipelines.csproj
index 3619b4ff0d9de..2f427e6cd9a87 100644
--- a/docs/core/extensions/snippets/ai/ConsoleAI.FunctionalityPipelines/ConsoleAI.FunctionalityPipelines.csproj
+++ b/docs/core/extensions/snippets/ai/ConsoleAI.FunctionalityPipelines/ConsoleAI.FunctionalityPipelines.csproj
@@ -1,4 +1,4 @@
-
+
Exe
@@ -8,7 +8,7 @@
-
+
diff --git a/docs/core/testing/microsoft-testing-platform-intro.md b/docs/core/testing/microsoft-testing-platform-intro.md
index f9e761fad09ad..21f5e558f600a 100644
--- a/docs/core/testing/microsoft-testing-platform-intro.md
+++ b/docs/core/testing/microsoft-testing-platform-intro.md
@@ -251,7 +251,7 @@ The list below described only the platform options. To see the specific options
Prints out a description of how to use the command.
-- **`-ignore-exit-code`**
+- **`--ignore-exit-code`**
Allows some non-zero exit codes to be ignored, and instead returned as `0`. For more information, see [Ignore specific exit codes](./microsoft-testing-platform-exit-codes.md#ignore-specific-exit-codes).
diff --git a/docs/navigate/tools-diagnostics/toc.yml b/docs/navigate/tools-diagnostics/toc.yml
index bb73a0430b9eb..7e1847f52adf6 100644
--- a/docs/navigate/tools-diagnostics/toc.yml
+++ b/docs/navigate/tools-diagnostics/toc.yml
@@ -391,7 +391,9 @@ items:
displayName: exception summarization,exception summary,exception summarizer,ExceptionSummary
- name: Collection
href: ../../core/diagnostics/metrics-collection.md
- - name: Source-generated metrics
+ - name: Compile-time metric source generation
+ href: ../../core/diagnostics/metrics-generator.md
+ - name: Strongly typed source-generated metrics
displayName: strongly-typed tags,dimensions
href: ../../core/diagnostics/metrics-strongly-typed.md
- name: Built-in metrics