Appearance
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
| Environment | Resource Name | Resource Group |
|---|---|---|
| dev | mic-erp-be-dev-ai | mic-erp-be-dev-monitoring-rg |
| stage | mic-erp-be-stage-ai | mic-erp-be-stage-monitoring-rg |
| preprod | mic-erp-be-preprod-ai | mic-erp-be-preprod-monitoring-rg |
| uat | mic-erp-be-uat-ai | mic-erp-be-uat-monitoring-rg |
| production | mic-erp-be-prod-ai | mic-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__ConnectionStringConnection 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
| Type | Backend | Frontend |
|---|---|---|
| Requests | All HTTP requests with duration, status | Page views, route changes |
| Dependencies | SQL queries, Redis calls, HTTP calls to other services | XHR/fetch calls to API |
| Exceptions | Unhandled exceptions with stack traces | JS errors and unhandled promise rejections |
| Custom metrics | Business metrics (tenants active, invoices processed/hour) | User action metrics |
| Traces | Structured log forwarding from Serilog | Console.error forwarding |
| Availability | Health 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:
| Tile | Metric |
|---|---|
| Request rate | Requests/min across all services |
| Failure rate | 5xx responses as % of total |
| P95 latency | 95th percentile response time per service |
| Active exceptions | Exceptions in last hour by service |
| Dependency health | SQL / 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 Name | URL | Alert threshold |
|---|---|---|
| Gateway Health | https://gateway.{domain}/health | 2 consecutive failures |
| Keycloak Ready | https://auth.{domain}/health/ready | 2 consecutive failures |
| Frontend | https://erp.{domain}/index.html | 3 consecutive failures |
Failures trigger alerts via the alerting action groups.
Sampling
To control costs, Application Insights uses adaptive sampling in all environments:
| Environment | Sampling rate |
|---|---|
| dev | 100% (no sampling) |
| stage | 100% (no sampling) |
| preprod | 50% |
| uat | 100% (for UAT accuracy) |
| production | Adaptive (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
};