Back to Blog
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.

Michael John Peña

Michael John Peña

Senior Data Engineer based in Sydney. Writing about data, cloud, and technology.