← Back to all posts

Azure Alerts for Exceptions in .NET

Azure Alerts for Exceptions in .NET

Reading Time: 7 minutes

The Problem

Applications fail in production long before anyone opens the Azure portal.

An exception gets thrown, requests start failing, and the system is already in a degraded state before the team notices. The real issue is rarely just logging. Most teams already have logs somewhere. The problem is that logs on their own are passive.

What you actually want is this:

  • exceptions are captured automatically
  • the right failures are turned into alerts
  • alerts reach the right people quickly
  • noisy, low-value failures do not spam the whole team

Without that, exception monitoring usually falls into one of two bad states:

  • everything is logged but nothing is actioned
  • everything is alerted and people start ignoring the alerts

For .NET systems on Azure, the gap is usually between exception telemetry and operational alerting. Capturing exceptions is one concern. Routing useful signals to email, Teams, or Slack is another.

The Solution

The clean Azure-native model is:

  1. send application telemetry to Application Insights through Azure Monitor
  2. let exceptions flow into the exceptions telemetry table
  3. create an Azure Monitor alert rule based on that exception signal
  4. connect the alert rule to an action group
  5. use the action group to notify by email or call out to integration endpoints that post into Teams or Slack

This separation matters.

Your .NET application should focus on emitting telemetry correctly. Azure Monitor should decide when a condition is serious enough to alert. Action groups should decide who gets notified and through which channel.

That gives you a monitoring setup that is:

  • easier to manage centrally
  • safer to tune without redeploying code
  • less coupled to any single chat platform
  • easier to extend over time

Capture Exceptions in a .NET App

For an ASP.NET Core application, the first step is making sure exceptions are actually reaching Azure Monitor.

One solid approach is to use the Azure Monitor OpenTelemetry distribution.

Install the package:

dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore

Then configure it in Program.cs:

using Azure.Monitor.OpenTelemetry.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry().UseAzureMonitor(options =>
{
    options.ConnectionString = builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
});

var app = builder.Build();

app.MapGet("/", () => "Healthy");

app.MapGet("/boom", () =>
{
    throw new InvalidOperationException("Simulated production failure.");
});

app.Run();

For many ASP.NET Core failures, unhandled exceptions will automatically be captured once the telemetry pipeline is configured.

You can also record handled exceptions explicitly when you catch them and still want visibility:

using Microsoft.Extensions.Logging;

app.MapPost("/orders", (ILogger<Program> logger) =>
{
    try
    {
        throw new InvalidOperationException("Order processing failed.");
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Order processing failed.");
        return Results.Problem("The order could not be processed.");
    }
});

The important point is not to send emails or chat notifications from the application itself when an exception occurs. That creates duplicated logic, notification drift, and deployment-time coupling. Emit telemetry from the app, then let Azure Monitor own alerting.

Where the Exception Data Goes

Once Application Insights is connected, Azure Monitor stores exception telemetry where alert rules can evaluate it.

In practice, a common alert condition is based on:

  • exception count over a time window
  • specific exception types
  • a spike in server exceptions
  • failed request rate correlated with exception volume

This matters because not every exception deserves an alert.

Examples:

  • a one-off client cancellation probably should not page anyone
  • repeated SqlException failures in five minutes probably should
  • a burst of NullReferenceException after a deployment definitely deserves attention

That is why alert criteria should be deliberate rather than simply “alert on any exception.”

Creating the Alert Rule

In Azure, the alert usually lives in Azure Monitor Alerts and targets the Application Insights resource or the Log Analytics-backed telemetry data behind it.

Two common models are:

Metric-based alert

Use this when Azure already exposes a suitable metric and you want a straightforward threshold alert.

This is simple, but less flexible when you want to filter by exception type, operation name, or environment.

Log query alert

Use this when you need precision.

For example, you can alert only when a query over the exceptions table returns a count above some threshold.

A representative KQL query might look like this:

exceptions
| where timestamp > ago(5m)
| where type !in ("TaskCanceledException", "OperationCanceledException")
| summarize ExceptionCount = count() by type
| where ExceptionCount >= 5

This is usually the better pattern because it lets you filter noisy exception types and tune the threshold around real operational behavior.

Action Groups: Email, Teams, and Slack

Alert rules decide when to alert. Action groups decide what happens next.

This is the part that sends notifications outward.

Email

This is the simplest option.

Create or reuse an action group and add an Email/SMS/Push/Voice action. For many teams, email is still the right default for non-paging alerts such as:

  • repeated exceptions in a non-production environment
  • warning-level operational anomalies
  • release validation issues after deployment

Email is low-friction and built in.

Teams channel

Azure Monitor alerts do not need to be hardwired into your .NET application to reach Teams. The usual pattern is:

  1. the alert fires
  2. the action group calls an integration endpoint
  3. that integration posts a formatted message to Teams

In practice, teams commonly use one of these:

  • a Logic App that posts to Teams
  • a workflow endpoint that transforms the alert payload
  • a webhook-capable intermediary service

That indirection is useful because it lets you:

  • format the message cleanly
  • route alerts to different channels by severity
  • enrich the message with links to dashboards, KQL, or incident runbooks

Slack channel

Slack follows the same operational model.

The alert should trigger an action group, and the action group should call something that can post into Slack, such as:

  • a Logic App
  • an Azure Function
  • a secure webhook endpoint that forwards the message

This keeps Slack delivery outside the application and inside the monitoring workflow where it belongs.

Why Not Alert Directly from Application Code?

It is tempting to write code like this:

  • catch exception
  • call Slack webhook
  • send email
  • maybe also post to Teams

That is almost always the wrong design.

It causes several problems:

  • the app becomes responsible for notification policy
  • every service implements alerting differently
  • changing recipients requires code or configuration churn in each app
  • outages can break both the application and its alerting path at the same time

The application should emit telemetry. Azure Monitor should evaluate conditions. Action groups and downstream integrations should route the alert.

A Practical Alerting Strategy

A good default exception alert strategy for a .NET system might be:

  • capture all meaningful exceptions in Application Insights
  • exclude expected cancellation-style exceptions from alert queries
  • alert on repeated failures over a short time window rather than single isolated exceptions
  • send warning-level alerts to email
  • send higher-severity alerts to Teams or Slack through an action group integration
  • include direct links to the affected resource, query, and dashboard in the notification payload

That gives you signal without drowning the team in noise.

Example Operational Thresholds

These are not universal, but they are better than starting with “everything alerts”:

  • 5 or more unexpected exceptions in 5 minutes: notify email distribution list
  • 15 or more unexpected exceptions in 5 minutes: post to Teams or Slack operations channel
  • sustained exception spike for 15 minutes: escalate to on-call workflow

The exact numbers depend on traffic volume and application shape, but the idea is the same: tune alerts against patterns, not against isolated events.

Summary

Azure alerting for exceptions works best when you separate responsibilities clearly.

  • your .NET app emits telemetry to Application Insights
  • Azure Monitor evaluates exception conditions
  • alert rules trigger action groups
  • action groups send notifications to email or integration paths for Teams and Slack

That is the model that scales.

It avoids pushing notification logic into application code, gives you cleaner operational control, and makes exception monitoring something the platform can manage consistently across services.

If you want a robust setup, think in this order:

  1. collect exception telemetry correctly
  2. define alert conditions that reflect real incidents
  3. route alerts through action groups to the right channels
  4. tune out noise before people start ignoring the alerts

References