Skip to content

Foundry observability implementation guide

Scope: Azure AI Foundry

This page describes the Azure AI Foundry target, the hosted-cloud target of ADR-0011. Foundry Local and Azure Local Foundry differ from it in models, features, identity, cost, and operations. Compare all three on Deployment targets.

Package layout

PathPurpose
infra/observability/main.bicepSubscription-scope Foundry observability composition
infra/observability/modulesSingle-purpose modules for foundation, alerts, diagnostics, application telemetry, and dashboard definition
infra/observability/params/example.bicepparamComplete public, fictitious parameter contract
infra/observability/dashboardsSource-control rules for native Azure Monitor Grafana dashboard definitions
infra/observability/queriesFoundry Resource Graph inventory and tag-compliance queries

Deployment sequence

  1. Copy params/example.bicepparam to the private Homestead deployment area.
  2. Replace every fictitious identity, naming, recipient, budget, scope, and threshold value.
  3. Select the foundation, Foundry core, or Foundry diagnostics profile by setting the corresponding feature switches and definitions.
  4. Compile Bicep and run a subscription what-if through the private deployment path.
  5. Review all resource changes, tags, metrics, alert conditions, data-producing features, retention, daily quota, and cost implications.
  6. Obtain explicit approval, deploy, test an action-group notification, and record the as-built state. Do not deploy the public example file.

Module mapping

CapabilityModulePrivate definition required
FoundationResource group, Log Analytics, Azure Monitor Workspace, action group, subscription budget, dashboardIdentity tags, recipient, budget, quota, retention
Azure health and control planeactivity-log-alerts.bicepFoundry scopes and explicit Activity Log conditions
Foundry behaviormetric-alerts.bicepMetric namespace, supported metric, dimensions, window, threshold, severity
Response hygienealert-processing-rules.bicepNarrow maintenance or routing rule properties
Foundry diagnosticsfoundry-diagnostic-setting.bicepExisting account location, selected categories, destination type
Foundry billed costfoundry-cost-collection.bicep, resource-group-role-assignment.bicepTarget subscription and resource group, collection interval, retention
Application telemetryapplication-insights.bicep, availability-tests.bicepApplication scenario, data classification, sampling, retention, safe endpoint
Query-based detectionscheduled-query-alerts.bicepReviewed KQL, scopes, frequency, window, and severity

Metric alert rule

Each metric definition contains the full ARM metric-alert properties except the action group. Use a resource scope only for the existing Foundry account or project being monitored. Confirm the target metric appears in Azure Monitor for that resource before enabling the rule. Do not invent a metric or assume every Foundry model exposes the same dimensions.

The initial candidates are model requests, availability rate, response latency, server errors, throttling, input and output tokens, generated images, and safety metrics. They begin as dashboard signals; alerting requires an agreed normal baseline.

Model-use dashboard

infra/observability/dashboards/foundry-model-usage.dashboard.json is the core dashboard definition. A private overlay must load the JSON and replace all seven target placeholders before it supplies the serialized definition to grafanaDashboardDefinitionSerializedData.

bicep
param grafanaDashboardDefinitionSerializedData = replace(
  replace(
    replace(
      replace(
        replace(loadTextContent('../../core/homestead-foundry/infra/observability/dashboards/foundry-model-usage.dashboard.json'), '__SUBSCRIPTION_ID__', '<private-subscription-id>'),
        '__FOUNDRY_RESOURCE_GROUP__', '<private-foundry-resource-group>'),
      '__FOUNDRY_RESOURCE_NAME__', '<private-foundry-account-name>'),
    '__LOCATION__', '<private-azure-region>'),
  '__LOG_ANALYTICS_WORKSPACE_RESOURCE_ID__', '<private-workspace-resource-id>')

The full private overlay must also replace both gateway placeholders. The dashboard uses native Microsoft.CognitiveServices/accounts metrics for operational signals. Its ModelDeploymentName series show which deployment was used and when. ModelRequests and InputTokens, OutputTokens, and TotalTokens show how much it was used. The availability and status-code panels show the operating condition. Actual billed-cost panels query FoundryModelCost_CL, which is populated from Cost Management ActualCost. Do not represent raw Azure Monitor token metrics as billed currency.

Actual-cost collection

Set enableFoundryCostCollection to true and provide foundryCostCollectionConfiguration to enable the billed-cost section. The module creates a system-assigned managed-identity Logic App, a direct data collection rule, and the FoundryModelCost_CL custom table. It grants the workflow Cost Management Reader on the target Foundry resource group and Monitoring Metrics Publisher on the data collection rule. It does not store account keys or credentials.

Every collection run queries the current month at daily granularity, grouped by meter, and writes a single compact raw snapshot. The dashboard selects only the newest snapshot to avoid counting repeated month-to-date queries more than once. A four-hour interval is recommended because Cost Management data itself can lag usage by several hours. Azure Monitor operational panels retain their five-minute refresh cadence.

Migration from the original foundation

The expanded public contract deliberately aligns with Platform naming. A private overlay updating from the original Homestead foundation maps these inputs before its next approved what-if:

OriginalExpanded contract
envenvironment
regionTokenregionCode
monthlyCreditBudgetUsdmonthlyBudgetUsd
Existing subscription budget resource name and periodbudgetName, budgetStartDate, budgetEndDate
defaulted Bicep valuesExplicit private parameter-file values

The environment input accepts prod as well as prd so an established deployment can retain its existing CAF-derived resource names. Do not change the environment token for a live deployment merely to normalize an abbreviation, because that would target a different set of resource names.

No existing Azure resource changes because of this source update. A private parameter overlay is migrated and deployed only through a separately approved change.

Dashboard panels

The foundry-model-usage.dashboard.json dashboard contains operational, billed-cost, and optional gateway sections:

PanelIDRowDescription
Model requests by deployment1y=0Request volume per ModelDeploymentName
Total tokens by deployment2y=0Token consumption per deployment
Input and output tokens by deployment3y=12Split input vs output tokens
Model availability by deployment4y=12ModelAvailabilityRate per deployment
Throttled requests by deployment5y=24HTTP 429 per deployment
Server errors by deployment6y=24HTTP 5xx per deployment
Input and output token volume7y=32Raw per-deployment token counts, not currency
Aggregate token consumption8y=32All-deployment total tokens
Model inventory: request volume9y=40All 22 deployed models, top 30
Content safety / RAI blocks10y=40HTTP 400 per deployment
Caller / consumer breakdown11y=48Requires AzureOpenAIRequestUsage enabled
Cost and consumption row17y=56Starts the ActualCost section
Actual cost today18y=57Current-day billed cost
Actual cost, last 7 days19y=57Trailing seven-day billed cost
Actual cost, month to date20y=57Current-month billed cost
Billed tokens and cost by model21y=62Today, seven-day, and month token and cost columns
Daily actual model cost22y=74Daily cost trend by model
Month-to-date actual cost by model23y=74Ranked model cost totals
Optional model gateway12-16y=82 onwardGateway requests, latency, health, CPU, and memory

Panels 18-23 require the ActualCost collector. They remain empty when the collector is disabled. Cost columns use billed currency returned by Cost Management, while token columns normalize the billed meter quantities into token counts.

Usage diagnostics (caller identity)

The AzureOpenAIRequestUsage diagnostic category writes request-usage logs to Log Analytics. Each log entry includes callerIpAddress and operationName, which identify which pipeline or agent invoked a model deployment. Enable this category in the private overlay's foundryDiagnosticSetting.logs array:

bicep
{
  category: 'AzureOpenAIRequestUsage'
  enabled: true
  retentionPolicy: {
    enabled: false
    days: 0
  }
}

This category produces log data and therefore incurs Log Analytics ingestion and retention cost. The private overlay should set logAnalyticsDailyQuotaGb to a value that accommodates the expected volume. Usage logs are not required for the core platform-metric panels (1-10); only panel 11 depends on them.

Cost model

Data sourceDestinationCostUsed by
Platform metrics (Microsoft.CognitiveServices/accounts)Azure Monitor metrics pipelineFreePanels 1-10
AzureOpenAIRequestUsage diagnostic logsLog AnalyticsPer GB ingestedPanel 11 only
Cost Management ActualCost snapshotFoundryModelCost_CL in Log AnalyticsMinimal ingestion plus Logic App executionsPanels 18-23

The caller/consumer breakdown and compact ActualCost snapshot require paid Log Analytics ingestion. Set logAnalyticsDailyQuotaGb to a tight supported cap to prevent surprise bills. The Azure Monitor Workspace (amw-*) deployed by this package is available for Prometheus metrics but is not required by the Foundry dashboard panels.

No platform metrics are sent to Log Analytics. The foundryDiagnosticSetting.metrics array is empty in the recommended configuration. This avoids double-ingestion cost for data already available on the free metrics pipeline.