Skip to content

Application Insights

Every Microtec environment has a dedicated Application Insights workspace that collects telemetry from all .NET backend services and Angular frontends. Application Insights is integrated with OpenTelemetry for backend services and with the Angular SDK for frontend correlation.


Per-Environment Workspaces

EnvironmentResource NameResource Group
devmic-erp-be-dev-aimic-erp-be-dev-monitoring-rg
stagemic-erp-be-stage-aimic-erp-be-stage-monitoring-rg
preprodmic-erp-be-preprod-aimic-erp-be-preprod-monitoring-rg
uatmic-erp-be-uat-aimic-erp-be-uat-monitoring-rg
productionmic-erp-be-prod-aimic-erp-be-prod-monitoring-rg

Each workspace is backed by a Log Analytics workspace with 90-day retention (dev/stage) or 180-day retention (prod/uat/preprod).


Connection String Injection

Application Insights connection strings are not hardcoded. They are stored in Key Vault and injected via Container App environment variable references:

KV Secret name: ApplicationInsights--ConnectionString
CAE env var:    ApplicationInsights__ConnectionString

Connection string format:

InstrumentationKey=<guid>;IngestionEndpoint=https://uksouth-1.in.applicationinsights.azure.com/;LiveEndpoint=https://uksouth.livediagnostics.monitor.azure.com/

Connection String vs Instrumentation Key

Always use the connection string (not the deprecated instrumentation key alone). The connection string includes the regional ingestion endpoint, which ensures data is routed to the correct region (UK South for Microtec) without latency. Using only the ikey routes through the global endpoint which adds ~50ms on average.


.NET Integration

Application Insights is wired up via OpenTelemetry in Program.cs using the Microtec.Web.Core shared package:

csharp
// In Microtec.Web.Core / ServiceCollectionExtensions.cs
builder.Services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddEntityFrameworkCoreInstrumentation()
        .AddAzureMonitorTraceExporter(opts =>
        {
            opts.ConnectionString = builder.Configuration
                ["ApplicationInsights:ConnectionString"]!;
        }))
    .WithMetrics(metrics => metrics
        .AddAspNetCoreInstrumentation()
        .AddRuntimeInstrumentation()
        .AddAzureMonitorMetricExporter(opts =>
        {
            opts.ConnectionString = builder.Configuration
                ["ApplicationInsights:ConnectionString"]!;
        }));

The shared package handles this automatically. Individual services do not configure Application Insights directly.


Angular Frontend Integration

The Angular applications use @microsoft/applicationinsights-web for browser-side telemetry:

typescript
// libs/shared-lib/src/lib/services/telemetry.service.ts
import { ApplicationInsights } from '@microsoft/applicationinsights-web';

@Injectable({ providedIn: 'root' })
export class TelemetryService {
  private appInsights: ApplicationInsights;

  constructor(private config: ConfigService) {
    this.appInsights = new ApplicationInsights({
      config: {
        connectionString: config.get('applicationInsightsConnectionString'),
        enableAutoRouteTracking: true,
        enableCorsCorrelation: true,
        correlationHeaderExcludedDomains: ['auth.microtecstage.com']
      }
    });
    this.appInsights.loadAppInsights();
  }
}

Frontend telemetry uses a separate connection string pointing to the same Application Insights resource but with a different role name (Angular) to distinguish frontend from backend telemetry.


Telemetry Types Collected

TypeBackendFrontend
RequestsAll HTTP requests with duration, statusPage views, route changes
DependenciesSQL queries, Redis calls, HTTP calls to other servicesXHR/fetch calls to API
ExceptionsUnhandled exceptions with stack tracesJS errors and unhandled promise rejections
Custom metricsBusiness metrics (tenants active, invoices processed/hour)User action metrics
TracesStructured log forwarding from SerilogConsole.error forwarding
AvailabilityHealth check pings (via Availability Tests)

Custom Dashboards

Three shared dashboards are pinned to the Azure Portal:

1. Operations Overview Dashboard

Available at Dashboards → Microtec ERP - Operations:

TileMetric
Request rateRequests/min across all services
Failure rate5xx responses as % of total
P95 latency95th percentile response time per service
Active exceptionsExceptions in last hour by service
Dependency healthSQL / Redis / ASB call success rate

2. Service Health Dashboard

Per-service latency, error rate, and dependency breakdown. Drill-down from Operations Overview.

3. Business Metrics Dashboard

Custom events tracked by the application:

  • Tenants active in last 24 hours
  • Invoices created per hour
  • Zatca submission success/failure rate
  • User login success/failure rate per realm

Availability Tests

Standard availability tests ping critical endpoints every 5 minutes from multiple Azure regions:

Test NameURLAlert threshold
Gateway Healthhttps://gateway.{domain}/health2 consecutive failures
Keycloak Readyhttps://auth.{domain}/health/ready2 consecutive failures
Frontendhttps://erp.{domain}/index.html3 consecutive failures

Failures trigger alerts via the alerting action groups.


Sampling

To control costs, Application Insights uses adaptive sampling in all environments:

EnvironmentSampling rate
dev100% (no sampling)
stage100% (no sampling)
preprod50%
uat100% (for UAT accuracy)
productionAdaptive (10–100% based on volume)

Production sampling is configured to always include:

  • All failed requests (HTTP 5xx)
  • All requests with exceptions
  • All requests exceeding P99 latency threshold (>5s)
csharp
// Sampling is configured in Microtec.Web.Core
options.SamplingSettings = new SamplingSettings
{
    IsAdaptiveSamplingEnabled = true,
    MaxTelemetryItemsPerSecond = 20
};

Internal Documentation — Microtec Platform Team