WhatsApp Icon
Category:
|
Posted On:
|
Modified On:
|
Author
by

TL;DR


Metrics, logs, and traces from the .NET application are captured by Azure Monitor and saved in Log Analytics, and Application Insights is used as the app-layer experience. Currently, the recommended approach is to instrument using OpenTelemetry through Azure.Monitor.OpenTelemetry.AspNetCore distribution instead of the traditional Application Insights SDK.


Introduction


Most .NET monitoring guides walk you through installing a NuGet package and calling it done. That's the easy 20%. The hard part the part that actually matters when your API starts timing out at 2 a.m. on Black Friday is knowing which signal to look at first, how to write a KQL query under pressure, and how to keep your Application Insights bill from becoming a line item someone questions in a budget meeting.


This guide is written from that angle. We'll cover the architecture, the current OpenTelemetry-based setup path, and the operational muscle you need once the app is live: alerting without alert fatigue, sampling without losing the trace that matters, and reading a production incident the way an on-call engineer actually does.


What is Azure Monitor?


Azure Monitor is Microsoft's end-to-end observability platform that covers Azure and hybrid cloud deployments. It collects and analyzes telemetry metrics, logs, and traces from your infrastructure, platform services, and apps, thus giving you one location where you can detect, diagnose, and react to incidents.


It’s not one product but rather an umbrella under which Log Analytics (query and storage layer), Application Insights (application layer experience), Azure Monitor Metrics (numeric time series in near real-time), and Alerts (action layer) operate. Azure Monitor tends to be the default observability solution for .NET teams due to its tight integration with App Service, AKS, Azure SQL, and any other Azure resource you might have.


Why Monitoring Matters for .NET Applications


.NET applications fail in ways that are often invisible until they're expensive: a connection pool exhausting itself under load, an async method blocking a thread pool thread, a dependency call retrying silently into a death spiral. None of these shows up as an obvious crash. They show up as slow p95 latency, and by the time a user complains, you're already behind.


Monitoring closes that gap. Done well, it gives you three things a stack trace alone never will:


  1. Causality - which downstream dependency actually caused the slowdown, not just which endpoint was slow.
  2. Trend visibility - whether a regression started at deploy time, or crept in over the last two weeks.
  3. Business context - correlating technical failures (exceptions, timeouts) with business impact (checkout failures, abandoned carts).


Teams that treat monitoring as an afterthought tend to bolt it on after the first bad incident. Teams that build it in from day one spend far less time guessing during incidents and far more time fixing the actual problem.


Azure Monitor Architecture


At a high level, telemetry flows in one direction: from your application and infrastructure, through collection agents or SDKs, into storage, and out through query and visualization tools.


.NET App (OpenTelemetry) ──┐
Azure Resources (Platform) ─┼──► Azure Monitor ──► Log Analytics Workspace ──► Dashboards
Infrastructure (VMs/AKS) ──┘ │ └► Alerts / Action Groups
└──► Application Insights (app-layer view)



Azure Monitor Components


Azure Monitor


The umbrella service covering metrics, logs, alerts, and visualization for everything running in Azure.


Application Insights


Application Insights is the APM layer of Azure Monitor, designed explicitly for request, dependency, exception, and custom event tracking within your application. This is where you will do most of your troubleshooting and investigation.


Log Analytics


Log Analytics is the query and storage engine behind Azure Monitor, built on Kusto Query Language (KQL), that lets you search, correlate, and analyse log and trace data across your entire environment. Every Application Insights resource is backed by a Log Analytics workspace.


Azure Monitor Workspace


A distinct concept from a Log Analytics workspace, this one specifically backs Azure Monitor managed Prometheus metrics, mostly relevant if you're running AKS with Prometheus-style scraping.


Alerts


Rule-based conditions (metric thresholding, log query results, or activity log events) that result in notifications or automated actions via action groups.


Metrics


Numerical time series data: CPU percentage, request count, response time; stored with high resolution, cheap queries, and good for dashboarding and near real-time alerting.


Logs


Structured and queriable event data: requests, traces, exceptions, custom events; stored in the Log Analytics space and queried using KQL. More granular than metrics but also higher latency and cost.


Distributed Tracing


The concept of distributed tracing allows for a single logical request to be tracked from start to finish throughout many different services, assigning a unique trace identifier that allows the entire path of execution to be reconstructed. This is the end-to-end transaction in Application Insights.


Live Metrics


A sub-second streaming view of requests, dependencies, and exceptions useful during a deployment or an active incident, but not a replacement for historical analysis.


OpenTelemetry


OpenTelemetry is an open-source vendor-neutral framework to generate and collect traces, metrics, and logs that is becoming the default instrumentation approach to send .NET applications' data to Azure Monitor. Microsoft is moving its Application Insights service onto OpenTelemetry as well as its data model.


Pro Tip: When starting a new project today, start instrumentation with OpenTelemetry right away. The old Microsoft.ApplicationInsights SDK is still available, but Microsoft is investing in OpenTelemetry distro, and lock-in is reduced drastically due to OTel exporters flexibility.


Azure Monitor vs Application Insights


A question that trips up a lot of teams new to Azure: are these competing products? No, Application Insights is a feature within Azure Monitor, scoped to application telemetry.


AspectAzure MonitorApplication Insights
ScopeFull Azure estate, infra, platform, appsApplication-layer only
Primary usersCloud/DevOps engineersDevelopers
Data typesMetrics, logs, activity logs, tracesRequests, dependencies, exceptions, traces
Query engineLog Analytics (KQL)Log Analytics (KQL), same backend
Setup unitAzure resource-level diagnosticsSDK/OTel instrumentation in code
Typical use caseVM/AKS health, resource alertsRequest latency, exception root cause


In practice, you'll use both together: Application Insights for what's happening inside your code, Azure Monitor's broader metrics and alerts for what's happening around it.


Prerequisites


  1. .NET 6 or later (this guide targets .NET 8/9 conventions)
  2. An Azure subscription with a Log Analytics workspace
  3. An Application Insights resource (workspace-based)
  4. The Application Insights connection string (not the older instrumentation key; it's deprecated for new resources)
  5. Azure CLI or Azure Portal access to configure alerts


Step-by-Step Implementation


1. Create your Application Insights resource


az monitor app-insights component create \
--app my-dotnet-app-insights \
--location eastus \
--resource-group my-rg \
--application-type web \
--workspace my-log-analytics-workspace


This creates a workspace-based Application Insights resource, the current default and the only option Microsoft actively recommends going forward.


2. Install the Azure Monitor OpenTelemetry Distro


For an ASP.NET Core project:


dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore


This is not vanilla OpenTelemetry but rather a curated distro that includes the ASP.NET Core, HttpClient, and SQL Client libraries together with the Azure Monitor exporter, and therefore you have out-of-the-box request, outbound dependency, and SQL queries tracing enabled automatically.


3. Wire it into Program.cs


var builder = WebApplication.CreateBuilder(args);

// Enables Azure Monitor Distro: traces, metrics, and logs
builder.Services.AddOpenTelemetry().UseAzureMonitor();

var app = builder.Build();
app.MapControllers();
app.Run();


That one line UseAzureMonitor() configures the OpenTelemetry SDK with ASP.NET Core instrumentation, HTTP client instrumentation, and the Azure Monitor exporter, reading the connection string from the APPLICATIONINSIGHTS_CONNECTION_STRING environment variable.


4. Set the connection string


export APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=xxxx;IngestionEndpoint=https://..."


In App Service, set this as an application setting instead of baking it into code it changes between environments and shouldn't live in source control.


5. Add custom telemetry where the automatic instrumentation isn't enough


public class OrderService
{
private readonly ActivitySource _activitySource = new("OrderService");

public async Task ProcessOrder(int orderId)
{
using var activity = _activitySource.StartActivity("ProcessOrder");
activity?.SetTag("order.id", orderId);

try
{
// business logic
}
catch (Exception ex)
{
activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
throw;
}
}
}


Register the custom ActivitySource name in your OpenTelemetry configuration so these spans are actually exported:


builder.Services.AddOpenTelemetry()
.UseAzureMonitor()
.WithTracing(tracing => tracing.AddSource("OrderService"));


Common Mistake: Creating a custom ActivitySource and forgetting to register it with AddSource(). The spans will exist locally but never reach Azure Monitor a silent failure that's maddening to debug.


6. Adjust sampling before you ship to production


builder.Services.AddOpenTelemetry().UseAzureMonitor(options =>
{
options.SamplingRatio = 0.2F; // sample 20% of traces
});


Full sampling (100%) is fine in dev and staging. In production under real load, it inflates cost and can push you toward Log Analytics ingestion throttling without much diagnostic upside; see the cost section below for how to think about this properly.


Viewing Metrics, Logs and Traces


Once telemetry is flowing, three views cover most day-to-day work:


  1. Application Map - a visual dependency graph showing which services call which, with latency and failure rate per edge. Start here when you don't know where the problem is.
  2. Transaction Search / End-to-end transaction details - drill into a single request and see every dependency call, exception, and timing breakdown inside it.
  3. Logs (KQL) - the most powerful and most underused view. Everything else is a pre-built query on top of this.


A KQL query you'll write constantly: slowest dependency calls in the last hour:


dependencies
| where timestamp > ago(1h)
| where duration > 1000
| summarize count(), avg(duration) by name, target
| order by avg_duration desc


And one for exception rate by operation, which is usually the first query worth running when something feels off:


exceptions
| where timestamp > ago(24h)
| summarize ExceptionCount = count() by operation_Name, type
| order by ExceptionCount desc


Creating Alerts


Alerts come in three flavours relevant to .NET apps:


Alert TypeTrigger SourceTypical Use
Metric alertAzure Monitor Metrics (near-real-time)CPU, request rate, response time thresholds
Log alertScheduled KQL queryCustom conditions like "5xx rate above 2%"
Activity log alertAzure control-plane eventsResource deletion, scaling events, service health


A log-based alert for elevated server error rate:


requests
| where timestamp > ago(5m)
| summarize Total = count(), Failed = countif(success == false)
| extend FailureRate = todouble(Failed) / Total * 100
| where FailureRate > 5


Wire this to an action group (email, SMS, webhook, or Logic App) with a 5-minute evaluation frequency.


Warning: Don't alert on every exception. A single handled exception in a retry loop is normal; a spike is not. Alert on rate and rate-of-change, not raw counts, or your on-call rotation will burn out within a month.


Creating Dashboards


Azure Monitor Workbooks are the right tool here over classic dashboards; they support parameterised queries, tabs, and mixed KQL/metric visualisations in one place. A solid starting workbook for a .NET API includes:


  1. Request rate and average duration, split by endpoint
  2. Dependency failure rate, split by dependency name
  3. Exception count trend over the last 7 days
  4. Server response time percentiles (p50/p95/p99), averages hide the problem


Best Practices


  1. Instrument with OpenTelemetry, not the legacy SDK, for anything greenfield.
  2. Set SamplingRatio deliberately; don't leave it at the default without thinking about cost.
  3. Use resource attributes (service.name, service.version, deployment.environment) to tell environments and versions apart in queries.
  4. Correlate custom business events (OrderPlaced, PaymentFailed) with technical telemetry; it turns an exception count into a revenue number.
  5. Set retention deliberately per data type; hot troubleshooting data doesn't need the same retention as compliance-driven audit logs.


Common Mistakes


  1. Leaving default 100% sampling running in production for months, then being surprised by the bill.
  2. Alerting on absolute counts instead of rates, causing alert fatigue that gets alerts muted entirely.
  3. Not registering custom ActivitySources, so custom spans silently vanish.
  4. Treating Application Insights and infrastructure logs as separate silos instead of joining them in one workspace.
  5. Forgetting to tagdeployment.environment, so dev and prod telemetry blend together in the same views.


Troubleshooting Guide


Telemetry isn't showing up at all. Make sure the connection string is set in the actual environment and not the local environment; verify that there is no firewall or NSG blocking access to the ingestion endpoint; and check Live Metrics, because it does not require batching delay.


Traces show gaps between services. Usually a missing traceparent header propagation; confirm all services are on OpenTelemetry-compatible instrumentation and that nothing (a proxy, a legacy gateway) is stripping headers in between.


High-cardinality warnings or unexpectedly high cost: Check custom dimensions for values like user IDs or request IDs used as dimension keys instead of values; this is the single most common cause of runaway ingestion volume.


Dependency shows as failed, but the call actually succeeded. Check the status code mapping; some HTTP clients report non-2xx as failed dependencies even when the caller treats it as an expected business response (like a 404 on a "check if exists" call).


Cost Optimization Tips


Azure Monitor cost scales with ingestion volume, not compute, which surprises a lot of teams the first time they see the bill.


  1. Adaptive sampling - reduces trace volume while preserving statistical accuracy; start here before reaching for aggressive fixed-rate sampling.
  2. Set daily caps - on the Log Analytics workspace as a safety net, not a primary strategy; a cap kicking in mid-incident is the worst possible time to lose data.
  3. Separate retention policies by table - requests and exceptions might need 90 days for trend analysis, while verbose traces might only need 30.
  4. Filter noisy dependencies at the source - health check pings and readiness probes rarely need full tracing.
  5. Review Log Analytics usage by table monthly - it's a five-minute check that regularly surfaces one noisy service dominating the bill.


Real-world Production Example: E-commerce API Under Black Friday Load


A mid-size e-commerce API starts showing p95 latency climbing from 200ms to 4 seconds two hours into peak traffic. Here's how the same signals get used in sequence during triage:


  1. Live Metrics confirms request volume is genuinely 6x normal, not a client-side retry storm, ruling out one hypothesis immediately.
  2. Application Map shows the SQL dependency node lighting up red, while the payment gateway dependency stays green, narrowing the search to the database layer in under a minute.
  3. A KQL query against dependencies filtered to type == "SQL" and sorted by duration surfaces one query, an order-lookup call, dominating total time.
  4. Distributed tracing on a sample slow request shows the query itself is fast, but there's a queuing delay before it even executes, pointing to connection pool exhaustion rather than query performance.
  5. Root cause: the connection pool max size was left at its default, tuned for normal traffic, not a 6x spike. Exceptions in the pool wait queue confirm it.


The fix was a pool size increase and a circuit breaker around the order-lookup path, but the diagnosis took eleven minutes because the telemetry from step 1 to step 4 already existed. Without it, this is a multi-hour incident spent guessing.


Security & Compliance Considerations


  1. Application Insights connection strings are not secrets in the traditional sense, but treat them as configuration, not committed source; rotate if leaked.
  2. Be deliberate about what goes into custom telemetry properties; request bodies, PII, and auth tokens should never land in trace data. Use telemetry initializers or processors to scrub sensitive fields before export.
  3. Log Analytics workspace access should follow least-privilege RBAC; not every engineer needs write access to alert rules or retention settings.
  4. For regulated industries, confirm your Log Analytics workspace region aligns with data residency requirements before ingestion starts, not after.


Monitoring Checklist


  1. OpenTelemetry distro installed and connection string configured per environment
  2. Sampling ratio deliberately set, not left at default
  3. Custom ActivitySources registered
  4. Alerts configured on rate-based thresholds, not raw counts
  5. Action groups tested end-to-end (not just created)
  6. Retention policy set per table, not globally
  7. PII scrubbing in place for custom telemetry
  8. Dashboard/workbook covering latency percentiles, not just averages


Conclusion


Azure Monitor has been transformed into an efficient observability tool for modern .NET applications, integrating metrics, logs, distributed traces, and alerting all at once. Nevertheless, the power of Azure Monitor lies not in the mere collection of telemetry but in leveraging such data to spot problems in advance, cut down the time required for debugging, and improve application performance.


Whether you are developing a cloud-native microservices application or maintaining an existing ASP.NET Core enterprise application, a well-conceived monitoring solution will pay off in reliability, scalability, and end-user experience. Adopting OpenTelemetry, setting up insightful dashboards, and configuring helpful alerts will increase your chances of keeping your applications working smoothly as they scale. At Avidclan Technologies, we consider observability a fundamental aspect of any modern .NET development process.

Don’t miss out – share this now!
Link copied!
Author
Rushil Bhuptani

"Rushil is a dynamic Project Orchestrator passionate about driving successful software development projects. His enriched 11 years of experience and extensive knowledge spans NodeJS, ReactJS, PHP & frameworks, PgSQL, Docker, version control, and testing/debugging."

FREQUENTLY ASKED QUESTIONS (FAQs)

To revolutionize your business with digital innovation. Let's connect!

Require a solution to your software problems?

Want to get in touch?

Have an idea? Do you need some help with it? Avidclan Technologies would love to help you! Kindly click on ‘Contact Us’ to reach us and share your query.

© 2026 Avidclan Technologies, All Rights Reserved.