Infrastructure

Azure Application Insights : diagnostiquer l'echantillonnage avant de changer les alertes

Un runbook de production pour qualifier une perte apparente de telemetrie Application Insights avec sampling, ingestion, SDK, KQL, alertes, validation et rollback avant de modifier les seuils.

19 juil. 2026 azureapplication-insightsazure-monitorobservabilitytelemetrysamplingkqlalertsrunbookrollbackproduction

Quand une alerte Azure Monitor devient silencieuse apres un deploiement, le reflexe consiste souvent a baisser un seuil, changer une requete KQL ou declarer que l’application va mieux. C’est fragile. Avec Application Insights, une baisse de requests, dependencies, traces ou exceptions peut venir du trafic reel, mais aussi de l’echantillonnage, d’une configuration SDK, d’un role name modifie, d’une perte d’ingestion ou d’une requete qui ne lit plus le bon signal.

Le cas d’usage est une API billing-api instrumentee avec Application Insights. Apres une livraison, l’alerte sur le taux d’erreur ne se declenche plus alors que le support signale encore des echecs intermittents. L’objectif du runbook est de decider si l’alerte doit etre modifiee, si l’instrumentation doit etre rollbackee, si l’echantillonnage est acceptable ou si l’incident doit rester ouvert faute de preuves.

Figer le contrat de telemetrie

Commence par expliciter ce que la telemetrie doit prouver. Application Insights n’est pas seulement un endroit ou chercher des logs. C’est le contrat qui relie symptome utilisateur, requete, dependance, exception, trace applicative, version et operation de deploiement.

yaml telemetry-contract.yml
service:
name: billing-api
environment: production
app_insights: ai-platform-prod
expected_cloud_role: billing-api-prod

signals_required:
- requests with resultCode and success
- dependencies for sql and http backends
- exceptions linked to operation_Id
- traces carrying deployment_version
- availability or synthetic probe result

change_context:
deployment: dep-20260719-0840
suspected_change: sdk configuration and sampling policy
decision_needed: alert_change_or_instrumentation_rollback
rollback_owner: platform-operations

Si ce contrat n’est pas clair, la discussion va melanger trois sujets : l’application va-t-elle mieux, les logs arrivent-ils encore, et l’alerte lit-elle le bon signal.

Separer trafic reel, sampling et ingestion

Une baisse de volume n’a pas une seule explication. Avant de toucher l’alerte, classe le symptome.

text telemetry-drop-classes.txt
Trafic reel en baisse
Les requests, dependencies, traces et probes baissent ensemble
Decision typique : verifier le routage, le frontend ou le calendrier metier avant de modifier l'alerte

Sampling plus agressif
Les volumes baissent mais les ratios, operation_Id et itemCount indiquent une extrapolation
Decision typique : lire les taux avec itemCount et valider que les signaux critiques ne sont pas perdus

Ingestion degradee
Certains types disparaissent ou arrivent en retard
Decision typique : qualifier pipeline, Diagnostic Settings, workspace, quotas et latence avant de changer KQL

Instrumentation cassee
Le role name, connection string, SDK ou enrichissement a change
Decision typique : rollback instrumentation ou corriger configuration avant de recalibrer les alertes

Requete d'alerte obsolete
Les donnees existent mais plus sous le meme champ, role ou table
Decision typique : corriger la requete avec preuves avant de changer le seuil

Cette separation evite une fausse correction : rendre l’alerte plus sensible alors que la telemetrie est incomplete, ou rollbacker l’application alors que seul un nom de role a change.

Lire le volume avec itemCount

Dans Application Insights, le sampling peut reduire le nombre de lignes sans reduire le nombre d’evenements representes. Les tables comme requests, dependencies, traces et exceptions peuvent porter itemCount. Une requete qui compte seulement les lignes peut donc mentir.

kusto 01-application-insights-volume-with-itemcount.kql
let StartTime = datetime(2026-07-19T07:30:00Z);
let EndTime = datetime(2026-07-19T10:00:00Z);
union
(requests
 | where timestamp between (StartTime .. EndTime)
 | extend signal = "requests", weight = toint(coalesce(itemCount, 1))),
(dependencies
 | where timestamp between (StartTime .. EndTime)
 | extend signal = "dependencies", weight = toint(coalesce(itemCount, 1))),
(exceptions
 | where timestamp between (StartTime .. EndTime)
 | extend signal = "exceptions", weight = toint(coalesce(itemCount, 1))),
(traces
 | where timestamp between (StartTime .. EndTime)
 | extend signal = "traces", weight = toint(coalesce(itemCount, 1)))
| summarize storedRows=count(), representedEvents=sum(weight) by signal, bin(timestamp, 15m)
| order by timestamp asc, signal asc

Si storedRows chute mais representedEvents reste coherent, l’alerte doit lire le signal pondere ou un ratio adapte. Si les deux chutent sans explication, il faut poursuivre le diagnostic d’ingestion et d’instrumentation.

Verifier role, version et operation

Un deploiement peut casser une alerte sans casser l’application : cloud_RoleName change, la version n’est plus injectee, les traces perdent operation_Id, ou les dependances sortent sous un autre nom.

kusto 02-role-version-operation-drift.kql
let StartTime = datetime(2026-07-19T07:30:00Z);
let EndTime = datetime(2026-07-19T10:00:00Z);
requests
| where timestamp between (StartTime .. EndTime)
| summarize requests=count(),
          representedRequests=sum(toint(coalesce(itemCount, 1))),
          operations=dcount(operation_Id),
          versions=make_set(tostring(customDimensions.deployment_version), 10),
          sampleNames=make_set(name, 10)
by cloud_RoleName, bin(timestamp, 15m)
| order by timestamp asc, cloud_RoleName asc

Un changement de cloud_RoleName apres le deploiement est un signal fort : l’alerte peut regarder l’ancien role pendant que la nouvelle version emet ailleurs. Dans ce cas, changer le seuil masque le probleme. Il faut corriger le filtre, retablir le role attendu ou documenter la migration.

Correlier requete, dependance et exception

Avant de declarer qu’une erreur a disparu, prouve que la chaine complete existe encore. Une API peut garder des requests mais perdre les dependencies, ou garder des exceptions non reliees aux operations.

kusto 03-correlate-request-dependency-exception.kql
let Window = 2h;
let FailedRequests =
requests
| where timestamp > ago(Window)
| where cloud_RoleName == "billing-api-prod"
| where success == false or toint(resultCode) >= 500
| project operation_Id, requestTime=timestamp, name, resultCode, url;
FailedRequests
| join kind=leftouter (
  dependencies
  | where timestamp > ago(Window)
  | project operation_Id, dependencyTime=timestamp, target, dependencyName=name, dependencyResultCode=resultCode, dependencySuccess=success
) on operation_Id
| join kind=leftouter (
  exceptions
  | where timestamp > ago(Window)
  | project operation_Id, exceptionTime=timestamp, exceptionType=type, problemId
) on operation_Id
| summarize failedRequests=dcount(operation_Id),
          dependencyTargets=make_set(target, 10),
          exceptionTypes=make_set(exceptionType, 10),
          missingDependencies=countif(isempty(target)),
          missingExceptions=countif(isempty(exceptionType))
by bin(requestTime, 15m), resultCode
| order by requestTime desc

Cette correlation dit si l’alerte peut encore expliquer un incident. Un signal qui compte des erreurs sans dependances ni exceptions exploitables peut declencher, mais il aide mal l’astreinte.

Controler les changements de configuration

Le deploiement applicatif n’est pas le seul changement possible. Sampling SDK, connection string, ingestion vers workspace, Diagnostic Settings, ressource Application Insights ou variable d’environnement peuvent avoir bouge.

text configuration-checklist.txt
A verifier avant modification d'alerte
La connection string ou instrumentation key pointe vers la ressource attendue
Le SDK Application Insights est charge dans la nouvelle revision
Le cloud role name reste stable ou la migration est documentee
Le sampling n'exclut pas exceptions, failed requests ou dependances critiques
Les customDimensions utilisees par KQL existent encore
Les donnees arrivent dans le workspace attendu
La latence d'ingestion est compatible avec la fenetre d'alerte
Les quotas, filtres et transformations n'ont pas ete modifies

Si un de ces points a change pendant la fenetre d’incident, l’action prioritaire est de retrouver une telemetrie fiable. L’alerte vient ensuite.

Qualifier la requete d’alerte

Une bonne alerte Application Insights doit etre lisible comme une decision d’exploitation. Elle doit nommer le role, la fenetre, le ratio, le minimum de volume, et la preuve qui justifie rollback ou maintien.

kusto 04-alert-query-with-sampling-awareness.kql
let RoleName = "billing-api-prod";
let MinimumRepresentedRequests = 50;
requests
| where timestamp > ago(15m)
| where cloud_RoleName == RoleName
| extend weight = toint(coalesce(itemCount, 1))
| summarize representedRequests=sum(weight),
          representedFailures=sumif(weight, success == false or toint(resultCode) >= 500),
          storedRows=count(),
          sampleOperationIds=make_set_if(operation_Id, success == false or toint(resultCode) >= 500, 5)
| extend failureRate = todouble(representedFailures) / todouble(representedRequests)
| where representedRequests >= MinimumRepresentedRequests
| project representedRequests, representedFailures, failureRate, storedRows, sampleOperationIds

Cette requete n’est pas un modele universel. Elle montre surtout les controles attendus : ne pas alerter sur trois lignes samplees, ne pas ignorer itemCount, garder des operations exemples et rendre le seuil defendable.

Decider validation, rollback ou changement d’alerte

La decision doit separer les couches. Une alerte ne doit pas corriger une instrumentation cassee.

text application-insights-decision.txt
Valider sans changement
Le volume represente reste coherent
Le sampling est compris et documente
Les erreurs, dependances et exceptions restent correlees
La requete d'alerte lit encore le bon role et le bon workspace

Modifier l'alerte
La telemetrie est fiable
Le seuil ou la fenetre ne correspond plus au comportement attendu
Le changement garde un minimum de volume et des operations exemples
Le rollback de la requete est pret

Rollback instrumentation
Le role name, le SDK, la connection string ou les customDimensions ont derive
Les signaux critiques disparaissent ou ne sont plus correles
L'alerte deviendrait aveugle ou trompeuse

Garder l'incident ouvert
L'ingestion est en retard ou incomplete
Le sampling ne permet pas de prouver les erreurs critiques
Le support observe encore le symptome sans trace exploitable

Ce cadrage evite de transformer une perte de preuve en changement de monitoring.

Preparer le rollback

Le rollback doit couvrir deux objets : la configuration d’instrumentation et la regle d’alerte. Les deux ne reviennent pas toujours ensemble.

yaml telemetry-alert-rollback-card.yml
rollback:
instrumentation:
  restore_connection_string: previous_secret_version
  restore_cloud_role: billing-api-prod
  restore_sampling_policy: previous_sdk_configuration
  validation: requests_dependencies_exceptions_correlated

alert:
  restore_query: alert-rule-version-before-dep-20260719-0840
  restore_threshold: previous_threshold
  validation: controlled_failure_or_synthetic_signal_visible

evidence_required:
  - before_after_kql_result
  - deployment_id
  - alert_rule_version
  - owner_decision
  - next_review_window

La validation apres rollback doit montrer que la telemetrie revient et que l’alerte peut a nouveau produire une decision. Sans cela, le rollback est seulement une remise en configuration, pas une recuperation exploitable.

Conclusion

Avant de modifier une alerte Application Insights, il faut prouver que le signal existe encore, qu’il est interprete correctement avec le sampling, qu’il reste correle entre requetes, dependances et exceptions, et qu’il arrive dans la bonne fenetre.

La bonne decision peut etre de garder l’alerte, de changer sa requete, de rollbacker l’instrumentation ou de maintenir l’incident ouvert. Ce qui compte est de ne pas confondre silence de l’alerte et disparition du probleme.