Welcome back! In our last lesson, we saw how to enable Application Insights for an App Service using the "codeless" autoinstrumentation approach. This gives us a fantastic baseline of telemetry out-of-the-box—requests, dependencies, exceptions, and performance counters.
While this automatic data is essential for understanding operational health, it doesn't tell the whole story. It doesn't know about your specific business logic. This is where you, as a developer, can significantly enrich the monitoring data.
Today's lesson addresses exactly that. We'll move from configuration to coding to instrument a .NET application with custom events, metrics, and telemetry using the Application Insights SDK. You'll learn how to send application-specific data that bridges the gap between system performance and business outcomes. Since this involves working with a .NET SDK and dependency injection, the patterns will be very familiar to you.
1. The Key to Custom Telemetry: TelemetryClient
All custom telemetry in Application Insights is sent via the TelemetryClient class. In a modern ASP.NET Core application, the framework manages the lifecycle of this client for you.
As we touched on in the last lesson, once you've installed the Microsoft.ApplicationInsights.AspNetCore NuGet package and registered the service in Program.cs with builder.Services.AddApplicationInsightsTelemetry(), a singleton instance of TelemetryClient becomes available in the dependency injection container.
You can then inject it into any controller, service, or other class where you need to send custom telemetry.
public class MyController : ControllerBase
{
private readonly TelemetryClient _telemetryClient;
// Inject TelemetryClient via the constructor
public MyController(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient;
}
// ... your methods will use _telemetryClient to send data
}
This is the standard and recommended practice. Creating your own instances of TelemetryClient is discouraged as it can lead to incorrect configuration and data loss, especially in short-lived applications like Azure Functions.
2. Tracking Custom Events
The automatically collected data tells you what happened (e.g., a request failed), but custom events tell you why in the context of your business logic. A custom event is a record of a discrete action occurring in your application.
Think of events like:
User Signed UpProduct Added To CartPayment FailedReport Generated
These are far more meaningful for understanding user behavior and business flows than a simple HTTP request count.
To get a practical walkthrough of implementing custom events, let's watch a detailed video.
Custom Events and Metrics :: Application Insights (5 of 6)
This video from Kevin Griffin provides an excellent developer-focused guide to custom telemetry in .NET. He starts with the core concepts and then moves into a live coding demonstration.
First, watch the concept of events to understand what custom events are and how TelemetryClient is used. Then, watch the practical demonstration from the live coding demo. Pay close attention to how he first tracks a simple event and then enriches it with a dictionary of custom properties.
As the video demonstrates, you send events using the TrackEvent method. While you can send just the event name, the real power comes from adding context through properties and measurements.
Here’s a concise example, similar to the one in the video, but focused on a common e-commerce scenario.
[HttpPost]
public async Task<IActionResult> PlaceOrder([FromBody] OrderRequest request)
{
// ... logic to create the order ...
// Define properties (string values) for context
var eventProperties = new Dictionary<string, string>
{
{ "PaymentMethod", request.PaymentMethod },
{ "ShippingRegion", request.ShippingRegion }
};
// Define measurements (numeric values) associated with the event
var eventMetrics = new Dictionary<string, double>
{
{ "ItemCount", order.Items.Count },
{ "OrderTotal", (double)order.Total }
};
// Track the event with its context
_telemetryClient.TrackEvent("OrderPlaced", eventProperties, eventMetrics);
return Ok();
}
- Properties (
customDimensionsin Application Insights) are string key-value pairs used for filtering and segmenting your data.ShippingRegionis a perfect example. - Measurements (
customMeasurementsin Application Insights) are numeric values associated with the event. They are useful for analysis (e.g., calculating the averageOrderTotalfor allOrderPlacedevents).
A key best practice is to use consistent, PascalCase naming for your events and to avoid high-cardinality values (like User IDs or Order IDs) as property keys or values if you intend to group by them, as this can negatively impact query performance and cost.
3. Tracking Custom Metrics
While events track occurrences, custom metrics track numeric measurements over time. They are optimized for aggregation (sum, average, min, max, count) and are ideal for performance indicators or business KPIs.
Good examples of metrics include:
- Queue depth
- Cache hit rate
- Batch processing time in milliseconds
- Number of active user sessions
How to Track Custom Events and Metrics in Azure Application Insights
This article from OneUptime provides a very clear and concise distinction between events and metrics.
Read the section "Custom Events vs Custom Metrics" to solidify your understanding of when to use one over the other.
As you'll see in the next video segment, Application Insights supports both single-dimensional and multi-dimensional metrics. A single-dimensional metric is a simple value, like "ProcessingTime." A multi-dimensional metric allows you to slice that value by different attributes, such as "ProcessingTime by BatchType."
Custom Events and Metrics :: Application Insights (5 of 6)
Let's return to Kevin Griffin's video for a deep dive into metrics. He covers both the theory and the implementation.
First, watch the metric concepts section where he explains single vs. multi-dimensional metrics and the importance of pre-aggregation. Next, see a practical example of a single-dimensional metric (AverageDelay). Notice how he aggregates the values over a minute before sending a single point to Application Insights. This is a crucial efficiency pattern. Finally, watch the powerful demonstration of multi-dimensional metrics (ApiHits by State and City). This shows how you can analyze your data from different perspectives in the Azure portal.
The video highlights two key points:
- Pre-aggregation is vital: You should not call
TrackMetricfor every single occurrence in a high-frequency scenario. Instead, collect values over an interval (e.g., one minute), calculate an aggregate (like an average or sum), and send that single data point. TheGetMetric(...).TrackValue(...)API helps with this by handling the aggregation for you, making it the preferred method for high-throughput metrics. - Multi-dimensional metrics are powerful: By adding dimensions, you can easily filter and split your metric charts in the Azure portal without writing complex queries. For example, you could track a
FileSizemetric with aFileTypedimension (.jpg,.pdf,.zip).
4. Other Useful Telemetry Types
The Application Insights SDK provides a few other Track* methods for specific scenarios that are good to be aware of.
Custom Events and Metrics :: Application Insights (5 of 6)
The final segment of the video briefly covers other common telemetry types you might need.
Watch the quick overview from other tracking methods.
Here is a quick summary of those methods:
TrackException(): Use this inside acatchblock to log exceptions that you handle gracefully but still want to record in Application Insights. Unhandled exceptions are logged automatically, but handled ones are not.TrackTrace(): Sends a custom log message, similar to usingILogger. These appear in thetracestable in Application Insights and are useful for diagnostic "breadcrumb" style logging.TrackDependency(): While most dependencies (SQL, HTTP calls) are tracked automatically, you might use this to manually time and record calls to a dependency that isn't auto-detected, such as a call to a TCP service or a local file system.
Conclusion
In this lesson, you've learned how to elevate your application monitoring from the generic to the specific. By instrumenting your .NET code with custom telemetry, you can capture the business-critical signals that autoinstrumentation alone cannot provide.
Key Takeaways:
- Custom telemetry is sent using an instance of
TelemetryClient, which should be acquired via dependency injection in ASP.NET Core. TrackEventis used for discrete business occurrences. Use properties (string dictionaries) and measurements (double dictionaries) to add rich context.TrackMetricis used for numeric values that you want to aggregate and analyze over time. Use theGetMetric().TrackValue()API for efficient pre-aggregation.- Metrics can be multi-dimensional, allowing you to easily slice and dice the data in the Azure portal.
- Methods like
TrackExceptionandTrackTraceprovide further control for logging handled errors and diagnostic messages.
You now have the tools to generate incredibly rich data about your application's behavior. But generating data is only half the battle. The next step is to analyze it. In our next lesson, we will dive into the Kusto Query Language (KQL) to write queries that filter, aggregate, and visualize the custom events and metrics you've just learned how to create.