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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.