Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Instrument applications with Azure Application Insights for telemetry, tracing, and performance monitoring
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/container-apps.md
1## Container Apps Observability23Observability guide for apps running in Azure Container Apps.45## Environment-Level Log Analytics67By default, Container Apps environments use a Log Analytics workspace. Configure it at environment creation (`--logs-workspace-id` expects the workspace **Customer ID** (GUID), not the ARM resource ID):89```bash10WORKSPACE_ID=$(az monitor log-analytics workspace show \11--resource-group <rg> --workspace-name <workspace-name> \12--query customerId -o tsv)1314WORKSPACE_KEY=$(az monitor log-analytics workspace get-shared-keys \15--resource-group <rg> --workspace-name <workspace-name> \16--query primarySharedKey -o tsv)1718az containerapp env create \19--name <env-name> \20--resource-group <rg> \21--logs-workspace-id $WORKSPACE_ID \22--logs-workspace-key $WORKSPACE_KEY \23--logs-destination log-analytics24```2526> π‘ **Tip:** All apps in the same environment share the workspace. Use `--logs-destination none` only for BYOB (bring-your-own-backend) scenarios.2728## System Logs vs Application Logs2930| Log Table | Content | Retention |31|-----------|---------|-----------|32| `ContainerAppConsoleLogs_CL` | stdout/stderr from containers | Workspace default |33| `ContainerAppSystemLogs_CL` | Platform events (scaling, restarts, image pulls) | Workspace default |3435> β οΈ **Note:** The `_CL` suffix and `_s` column suffixes apply to the **Log Analytics** destination. Environments using the newer **Azure Monitor** destination use `ContainerAppConsoleLogs` / `ContainerAppSystemLogs` (no `_CL`, no `_s` suffixes). Check your environment's log destination to use the correct table name.3637System logs capture events outside your codeβreplica scheduling, health probe results, and revision activation. Console logs capture everything your app writes to stdout/stderr.3839## Built-in Metrics4041Container Apps exposes these metrics without any SDK:4243| Metric | Description | Dimensions |44|--------|-------------|-----------|45| `Replicas` | Current replica count | `revision` |46| `Requests` | HTTP request count | `statusCode`, `statusCodeCategory`, `revision`, `replica` |47| `UsageNanoCores` | CPU usage per replica | `revision`, `replica` |48| `WorkingSetBytes` | Memory usage per replica | `revision`, `replica` |49| `RestartCount` | Container restart count | `revision`, `replica` |50| `RxBytes` / `TxBytes` | Network I/O | `revision`, `replica` |5152> β οΈ **Warning:** Built-in metrics cover infrastructure only. For request-level tracing, response times, and dependency tracking, add Application Insights SDK.5354## Application Insights SDK Setup5556Set `APPLICATIONINSIGHTS_CONNECTION_STRING` as an environment variable on the container app, then add the SDK per language:5758| Language | Package | Init Pattern |59|----------|---------|-------------|60| Node.js | `@azure/monitor-opentelemetry` | Call `useAzureMonitor()` before app startup |61| Python | `azure-monitor-opentelemetry` | Call `configure_azure_monitor()` at entry |62| .NET | `Azure.Monitor.OpenTelemetry.AspNetCore` | `builder.Services.AddOpenTelemetry().UseAzureMonitor()` |63| Java | Agent JAR (manual) | Set `JAVA_TOOL_OPTIONS=-javaagent:/agent/applicationinsights-agent.jar` |6465```bash66# Store as a secret (recommended β keeps value out of az show output and portal config)67az containerapp secret set -n <app-name> -g <rg> \68--secrets "appinsights-conn=<conn-string>"6970az containerapp update \71--name <app-name> \72--resource-group <rg> \73--set-env-vars "APPLICATIONINSIGHTS_CONNECTION_STRING=secretref:appinsights-conn"74```7576## Distributed Tracing Across Microservices7778Container Apps with multiple services need correlation. The OpenTelemetry SDK propagates `traceparent` headers automatically through HTTP calls. Ensure:79801. Every microservice has the SDK initialized with the **same** Application Insights resource812. HTTP clients use instrumented libraries (e.g., `requests` in Python, `fetch`/`axios` in Node.js)823. Verify end-to-end traces in the **Application Map** blade8384> π‘ **Tip:** Use `operation_Id` in KQL queries to trace a single request across all services.8586## Dapr Observability8788For apps using Dapr sidecars, Dapr generates tracing spans for service invocation, pub/sub, and state operations when tracing is configured. Note that `samplingRate: "1"` means 100% sampling β consider lowering for production workloads.8990Configure Dapr tracing in the Container Apps environment. The YAML below represents the config spec β in ACA, apply it via `az containerapp env dapr-component set` or ARM/Bicep (not as a raw YAML file):9192```yaml93# Dapr tracing config spec (apply via CLI or Bicep, not raw kubectl)94apiVersion: dapr.io/v1alpha195kind: Configuration96metadata:97name: appconfig98spec:99tracing:100samplingRate: "1"101otel:102endpointAddress: "<otlp-collector-endpoint>"103isSecure: true104protocol: grpc105```106107> β οΈ **Note:** `endpointAddress` should point to an OpenTelemetry Collector (not Application Insights directly). Configure the collector with the Azure Monitor exporter to forward traces to App Insights.108109Dapr generates spans for:110- **Service invocation** β caller β Dapr sidecar β target sidecar β target app111- **Pub/sub** β publisher β broker β subscriber112- **Bindings** β input/output binding operations113114## ARG Queries β Monitoring Status115116Discover Container Apps and their monitoring configuration:117118```kql119// Container Apps without App Insights configured (checks all containers)120resources121| where type == "microsoft.app/containerapps"122| mv-expand container = properties.template.containers123| mv-expand envVar = container.env124| where isnotempty(envVar)125| summarize hasAppInsights = countif(envVar.name == "APPLICATIONINSIGHTS_CONNECTION_STRING") by name, resourceGroup126| where hasAppInsights == 0127```128129> **Note:** This query only covers apps with existing environment variables. Apps with no env vars are excluded by the `mv-expand` and should be identified separately (e.g., filter for containers where `env` is null or empty).130131## KQL Query Library132133### Console log errors134135```kql136ContainerAppConsoleLogs_CL137| where Log_s contains "error" or Log_s contains "exception"138| project TimeGenerated, ContainerAppName_s, RevisionName_s, Log_s139| order by TimeGenerated desc140| take 50141```142143### Replica restart events144145```kql146ContainerAppSystemLogs_CL147| where EventSource_s == "ContainerAppController" and Reason_s == "Restarting"148| summarize restarts = count() by ContainerAppName_s, RevisionName_s, bin(TimeGenerated, 1h)149| order by TimeGenerated desc150```151152### Scaling events153154```kql155ContainerAppSystemLogs_CL156| where Reason_s in ("ScalingUp", "ScalingDown")157| project TimeGenerated, ContainerAppName_s, Reason_s, Log_s158| order by TimeGenerated desc159```160161### Console log volume by revision162163```kql164ContainerAppConsoleLogs_CL165| where isnotempty(Log_s)166| summarize logCount = count() by RevisionName_s, bin(TimeGenerated, 5m)167| render timechart168```169170### Request latency by instance (requires Application Insights SDK)171172```kql173requests174| where cloud_RoleName has "<app-name>"175| summarize avgDuration = avg(duration), p95 = percentile(duration, 95) by cloud_RoleInstance, bin(timestamp, 5m)176| render timechart177```178179> π‘ **Tip:** Console logs don't contain latency data. For request-level latency and dependency analysis, query the `requests` and `dependencies` tables from Application Insights.180