4 min read
Application Performance Monitoring with Azure Application Insights
With distributed teams and remote operations, visibility into application performance has become critical. Azure Application Insights provides comprehensive monitoring for your applications. Here is how to set it up effectively.
Setting Up Application Insights
# Create Application Insights resource
az monitor app-insights component create \
--app myapp-insights \
--location australiaeast \
--resource-group rg-monitoring \
--kind web
# Get the instrumentation key
az monitor app-insights component show \
--app myapp-insights \
--resource-group rg-monitoring \
--query instrumentationKey
.NET Core Integration
Add the NuGet package:
dotnet add package Microsoft.ApplicationInsights.AspNetCore
Configure in Startup.cs:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddApplicationInsightsTelemetry();
// Or with configuration options
services.AddApplicationInsightsTelemetry(options =>
{
options.EnableAdaptiveSampling = true;
options.EnableQuickPulseMetricStream = true;
options.EnableDebugLogger = false;
});
}
}
In appsettings.json:
{
"ApplicationInsights": {
"InstrumentationKey": "your-instrumentation-key"
}
}
Custom Telemetry
Track custom events and metrics:
public class OrderService
{
private readonly TelemetryClient _telemetry;
public OrderService(TelemetryClient telemetry)
{
_telemetry = telemetry;
}
public async Task<Order> CreateOrderAsync(OrderRequest request)
{
var stopwatch = Stopwatch.StartNew();
try
{
var order = await ProcessOrderAsync(request);
// Track custom event
_telemetry.TrackEvent("OrderCreated", new Dictionary<string, string>
{
{ "OrderId", order.Id.ToString() },
{ "CustomerId", request.CustomerId },
{ "ProductCount", request.Items.Count.ToString() }
});
// Track custom metric
_telemetry.TrackMetric("OrderValue", order.TotalAmount);
return order;
}
catch (Exception ex)
{
_telemetry.TrackException(ex, new Dictionary<string, string>
{
{ "Operation", "CreateOrder" },
{ "CustomerId", request.CustomerId }
});
throw;
}
finally
{
stopwatch.Stop();
_telemetry.TrackMetric("OrderProcessingTime", stopwatch.ElapsedMilliseconds);
}
}
}
Dependency Tracking
Track external service calls:
public class ExternalApiService
{
private readonly HttpClient _httpClient;
private readonly TelemetryClient _telemetry;
public async Task<ApiResponse> CallExternalApiAsync(string endpoint)
{
using var operation = _telemetry.StartOperation<DependencyTelemetry>("ExternalAPI");
operation.Telemetry.Type = "HTTP";
operation.Telemetry.Target = endpoint;
try
{
var response = await _httpClient.GetAsync(endpoint);
operation.Telemetry.Success = response.IsSuccessStatusCode;
operation.Telemetry.ResultCode = ((int)response.StatusCode).ToString();
return await response.Content.ReadAsAsync<ApiResponse>();
}
catch (Exception ex)
{
operation.Telemetry.Success = false;
_telemetry.TrackException(ex);
throw;
}
}
}
Custom Telemetry Initializer
Add custom properties to all telemetry:
public class CustomTelemetryInitializer : ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var context = _httpContextAccessor.HttpContext;
if (context == null) return;
// Add custom properties
if (telemetry is ISupportProperties propTelemetry)
{
propTelemetry.Properties["Environment"] = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
if (context.User.Identity?.IsAuthenticated == true)
{
propTelemetry.Properties["UserId"] = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
}
}
// Set cloud role for better filtering
telemetry.Context.Cloud.RoleName = "MyApp-API";
}
}
// Register in Startup.cs
services.AddSingleton<ITelemetryInitializer, CustomTelemetryInitializer>();
Availability Tests
Create availability tests via Azure CLI:
az monitor app-insights web-test create \
--resource-group rg-monitoring \
--app-insights myapp-insights \
--web-test-name "Homepage-Ping" \
--web-test-kind "ping" \
--location "Australia East" \
--url "https://myapp.azurewebsites.net" \
--frequency 300 \
--timeout 30
KQL Queries for Insights
Query your telemetry data:
// Failed requests by endpoint
requests
| where success == false
| summarize count() by name, resultCode
| order by count_ desc
// Slow dependencies
dependencies
| where duration > 1000
| summarize avg(duration), count() by target, name
| order by avg_duration desc
// Exception trends
exceptions
| summarize count() by type, bin(timestamp, 1h)
| render timechart
// User sessions by country
requests
| summarize sessions = dcount(session_Id) by client_CountryOrRegion
| order by sessions desc
Alerts Configuration
# Create an alert for high failure rate
az monitor metrics alert create \
--name "High-Failure-Rate" \
--resource-group rg-monitoring \
--scopes "/subscriptions/{sub}/resourceGroups/rg-monitoring/providers/microsoft.insights/components/myapp-insights" \
--condition "avg requests/failed > 10" \
--window-size 5m \
--evaluation-frequency 1m \
--action-group "/subscriptions/{sub}/resourceGroups/rg-monitoring/providers/microsoft.insights/actionGroups/ops-team"
Sampling Configuration
For high-volume applications:
services.AddApplicationInsightsTelemetry(options =>
{
options.EnableAdaptiveSampling = true;
});
// Or configure fixed-rate sampling
services.Configure<TelemetryConfiguration>(config =>
{
var builder = config.DefaultTelemetrySink.TelemetryProcessorChainBuilder;
builder.UseSampling(10); // 10% of telemetry
builder.Build();
});
Application Insights provides the visibility needed to maintain application health and quickly diagnose issues, essential for teams operating remotely.