Standard monitoring tools give you fantastic out-of-the-box visibility into technical health: HTTP request latency, server CPU usage, memory consumption, and unhandled exception rates. However, technical metrics alone don't tell the whole story. As a software engineer building enterprise systems, you often need to track critical business KPIs—such as order processing durations, payment gateway response times, daily transaction volumes, or inventory checkout failures—right alongside your infrastructure telemetry.

With Azure Application Insights and ASP.NET Core, you can easily bridge this gap by injecting TelemetryClient to capture rich custom metrics, custom events, and performance counters.

In this comprehensive guide, we will walk through how to implement custom telemetry in your ASP.NET Core services and query them effectively in Azure.

The Role of Custom Telemetry in Enterprise Systems

While infrastructure metrics track how your server is performing, custom telemetry tracks what your application is achieving. By emitting custom metrics and events, you enable your product owners, support teams, and engineering leads to:

Step 1: Injecting TelemetryClient into Your Services

ASP.NET Core automatically registers TelemetryClient in the Dependency Injection container when you call builder.Services.AddApplicationInsightsTelemetry(). You can inject this client directly into your controllers, CQRS command handlers, or domain services.

C#

using Microsoft.ApplicationInsights;

namespace YourSolution.Application.Services
{
    public class OrderService
    {
        private readonly TelemetryClient _telemetryClient;

        public OrderService(TelemetryClient telemetryClient)
        {
            _telemetryClient = telemetryClient;
        }
    }
}

Step 2: Tracking High-Performance Custom Metrics with GetMetric

While Application Insights provides a basic _telemetryClient.TrackMetric("Name", value) method, the recommended high-performance approach for frequent metrics is the GetMetric API.

GetMetric pre-aggregates metric values in memory over time windows before transmitting them to Azure. This significantly reduces CPU overhead and network traffic compared to sending individual data points for every single operation.

C#

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Metrics;

namespace YourSolution.Application.Services
{
    public class OrderService
    {
        private readonly TelemetryClient _telemetryClient;
        private readonly Metric _orderProcessingTimer;

        public OrderService(TelemetryClient telemetryClient)
        {
            _telemetryClient = telemetryClient;
            
            // Cache the metric identifier for optimized high-throughput tracking
            _orderProcessingTimer = _telemetryClient.GetMetric("OrderProcessingDurationMs");
        }

        public async Task ProcessOrderAsync(Guid orderId, decimal totalAmount)
        {
            var stopwatch = System.Diagnostics.Stopwatch.StartNew();

            // Simulate core business logic or database operations
            await Task.Delay(120); 

            stopwatch.Stop();

            // 1. Track custom duration metric
            _orderProcessingTimer.TrackValue(stopwatch.ElapsedMilliseconds);
        }
    }
}

Step 3: Tracking Custom Events with Rich Dimensions

Custom events allow you to record significant discrete occurrences in your application (e.g., OrderCompleted, PaymentFailed, or UserRegistered). You can attach key-value pairs called dimensions to provide rich contextual metadata for filtering and analysis.

Extend your OrderService to track business events:

C#

public async Task ProcessOrderAsync(Guid orderId, decimal totalAmount)
{
    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
    // ... processing logic ...
    stopwatch.Stop();

    _orderProcessingTimer.TrackValue(stopwatch.ElapsedMilliseconds);

    // 2. Track custom business event with dimensional metadata
    _telemetryClient.TrackEvent("OrderCompleted", new Dictionary<string, string>
    {
        { "OrderId", orderId.ToString() },
        { "Amount", totalAmount.ToString("C") },
        { "Currency", "USD" },
        { "ProcessedByNode", Environment.MachineName }
    });
}

Step 4: Understanding Performance Counters (Windows vs. Linux Containers)

Application Insights automatically collects standard performance counters (such as CPU utilization, available memory, and request execution rates) out of the box when running on Windows-based App Services.

However, if your Clean Architecture API is containerized and running on Linux (e.g., Azure App Service Linux or Docker containers, as covered in previous guides), traditional Windows performance counters are unavailable. Instead, Application Insights automatically collects Linux-specific runtime performance telemetry (like GC memory usage and thread pool metrics).

If you need to fine-tune or adjust telemetry modules, you can configure them during service registration in Program.cs:

C#

using Microsoft.ApplicationInsights.Extensibility;

builder.Services.Configure<TelemetryConfiguration>(config =>
{
    // Custom telemetry initializers or sampling configurations can be wired here
});

Step 5: Querying Custom Telemetry in the Azure Portal

Once your application is deployed and generating traffic, you can query your custom metrics and events directly within the Azure Portal:

  1. Open your Application Insights resource in the Azure Portal.

  2. Navigate to Monitoring > Logs (Log Analytics workspace).

  3. Run a Kusto query to visualize your custom metrics over time:

    Code snippet

    customMetrics
    | where name == "OrderProcessingDurationMs"
    | summarize AverageDurationMs = avg(value) by bin(timestamp, 5m)
    | render timechart
    
  4. Query your custom business events:

    Code snippet

    customEvents
    | where name == "OrderCompleted"
    | extend OrderId = tostring(customDimensions.OrderId)
    | extend Amount = tostring(customDimensions.Amount)
    | project timestamp, OrderId, Amount
    | order by timestamp desc
    

Summary

By incorporating TelemetryClient, GetMetric, and custom event tracking into your ASP.NET Core Clean Architecture project, you bridge the gap between technical infrastructure and business intelligence. You gain instant insight into real-time operational KPIs, empowering your team to monitor performance and resolve bottlenecks proactively.