Infrastructure

Azure Monitor DCR : diagnostiquer des logs manquants avant de rollbacker une transformation

Un runbook de production pour qualifier une perte de logs après modification d’une Data Collection Rule, séparer source, stream, transformation KQL et destination, puis valider ou rollbacker avec un canary.

18 août 2026 azureazure-monitordata-collection-rulelog-analyticskqlobservabilityautomationrunbookrollbackproduction

Une équipe réduit le bruit d’une table Log Analytics avec une transformation KQL dans une Data Collection Rule (DCR). Le déploiement réussit, les coûts semblent baisser, puis un incident révèle que certaines lignes utiles n’arrivent plus. Le réflexe est de retirer immédiatement la transformation. Ce rollback peut restaurer le volume, mais il ne prouve ni quelles lignes ont disparu, ni si la transformation est réellement responsable.

Le cas d’usage couvre une source envoyée par Azure Monitor Agent ou l’API Logs Ingestion, une DCR avec un dataFlow, une transformation transformKql et une table de destination. L’objectif est de séparer quatre causes : la source n’émet plus, le mauvais stream est utilisé, la transformation filtre ou rejette les lignes, ou la destination refuse le schéma. Le runbook se termine par une décision observable : conserver, corriger ou rollbacker.

Figer le flux avant de modifier la DCR

Une DCR ne se résume pas à une requête KQL. Le chemin complet relie une source, un stream déclaré, un data flow, une transformation, une destination et une table. Capturez ce contrat pour la fenêtre d’incident.

text dcr-incident-scope.txt
Incident: inc-20260818-04
Fenetre UTC: 2026-08-18 05:30 - 06:30
Ressource DCR: /subscriptions/.../dataCollectionRules/dcr-app-events-prod
Immutable ID: dcr-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Source: api-ingestion-app-events
Stream attendu: Custom-AppEventsRawData
Destination: law-operations-prod
Table: AppEvents_CL
Version de configuration avant/apres
Commit ou deployment ID du changement
Volume attendu et dernier evenement connu

Preuves a conserver
Configuration DCR complete avant et apres
Payload canary redige
Reponse HTTP et client request ID de l'envoi
Metriques DCR de lignes recues, rejetees et erreurs
Erreurs DCRLogErrors
Ligne canary dans la table cible ou preuve de son absence

Pour l’API Logs Ingestion, vérifiez l’immutableId, pas seulement le nom de ressource de la DCR. Figez aussi le stream exact envoyé par le client. Une DCR valide peut ne jamais traiter un payload envoyé vers un autre stream.

Exportez la configuration avant toute correction.

bash 01-export-dcr.sh
az monitor data-collection rule show \
--resource-group rg-monitoring-prod \
--name dcr-app-events-prod \
--output json > dcr-app-events-prod.json

az monitor data-collection rule show \
--resource-group rg-monitoring-prod \
--name dcr-app-events-prod \
--query '{id:id,immutableId:immutableId,dataFlows:dataFlows,destinations:destinations}' \
--output jsonc

Prouver que la source atteint l’ingestion

L’absence de ligne dans la table cible ne prouve pas un problème de transformation. Commencez au bord du système.

Pour un client de l’API Logs Ingestion, conservez le statut HTTP, l’heure UTC, le nombre de lignes et un x-ms-client-request-id unique. Un succès HTTP prouve que la requête a été acceptée, pas que chaque ligne a atteint la table. Pour Azure Monitor Agent, vérifiez l’association DCR, l’état de l’agent et la continuité de la source sur la machine concernée.

Utilisez ensuite les métriques de la DCR : lignes reçues, lignes abandonnées, erreurs de transformation, octets ingérés et durée de transformation. La lecture est comparative : même stream, même fenêtre et baseline connue.

text dcr-metric-reading.txt
Lignes recues a zero
Verifier le producteur, l'association DCR, l'endpoint et le stream

Lignes recues stables, lignes abandonnees en hausse
Verifier le filtre KQL et les erreurs de transformation

Erreurs de transformation en hausse
Comparer le schema reel avec les colonnes et conversions du transformKql

Octets ingeres stables, table cible en baisse
Verifier destination, table, delai d'ingestion et requete de lecture

Duree de transformation en hausse
Rechercher une expression couteuse ou un changement de forme des donnees

Ne comparez pas uniquement le nombre de lignes avant et après. Une transformation peut légitimement filtrer du bruit. Le signal utile est l’écart entre ce que la source envoie, ce que la DCR reçoit, ce qu’elle abandonne et ce que la table conserve.

Lire les erreurs de traitement de la DCR

Les erreurs DCR ne sont exploitables que si les logs de ressource de la règle sont envoyés vers un workspace. Activez la catégorie d’erreurs avant un changement risqué ; l’activer après l’incident ne reconstitue pas les erreurs passées.

Interrogez DCRLogErrors en ciblant la ressource et la fenêtre. Les colonnes détaillées peuvent évoluer selon le scénario ; commencez par le socle commun et gardez le contenu d’erreur brut.

kusto 02-dcr-processing-errors.kql
let StartTime = datetime(2026-08-18T05:30:00Z);
let EndTime = datetime(2026-08-18T06:30:00Z);
let DcrResourceId = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-monitoring-prod/providers/microsoft.insights/dataCollectionRules/dcr-app-events-prod";
DCRLogErrors
| where TimeGenerated between (StartTime .. EndTime)
| where _ResourceId =~ DcrResourceId
| project TimeGenerated, OperationName, ResultType, ResultDescription, _ResourceId
| order by TimeGenerated desc

Une erreur de conversion, une colonne obligatoire absente ou une sortie incompatible avec la table cible oriente vers la transformation ou le schéma. Une erreur de livraison oriente vers la destination. L’absence d’erreur ne prouve pas que la transformation est saine : une clause where qui filtre toutes les lignes est valide et peut donc ne produire aucune erreur.

Relire la transformation comme un contrat de schéma

Dans une transformation Azure Monitor, source représente chaque ligne entrante. La requête doit produire au plus une ligne par ligne reçue et respecter le schéma attendu par le stream de sortie. Une transformation courte peut tout de même supprimer silencieusement un type d’événement après un changement de casse, de valeur par défaut ou de structure JSON.

kusto current-transform.kql
source
| where tostring(Severity) in ("Warning", "Error", "Critical")
| extend TimeGenerated = todatetime(EventTime),
       Service = tostring(ServiceName),
       CorrelationId = tostring(CorrelationId),
       Payload = tostring(Payload)
| project TimeGenerated, Service, Severity, CorrelationId, Payload

Relisez chaque étape avec des échantillons réels et rédigés :

  • quelles valeurs de Severity existent réellement, y compris la casse et les valeurs nulles ;
  • si EventTime reste convertible en date ;
  • si un producteur a renommé ServiceName ou imbriqué Payload ;
  • si les colonnes projetées correspondent exactement à la table cible ;
  • si le filtre retire une classe d’événements nécessaire aux alertes ou aux investigations.

N’ajoutez pas summarize, join ou une logique multi-lignes pour compenser un problème de source. Les transformations d’ingestion standard travaillent ligne par ligne et n’acceptent qu’un sous-ensemble de KQL.

Envoyer un canary qui traverse chaque branche utile

Un bon canary ne contient pas seulement un événement censé passer. Il contient aussi une ligne censée être filtrée et une ligne volontairement proche d’une limite de schéma. Utilisez un identifiant unique, aucune donnée sensible et aucun effet métier.

json dcr-canary-payload.json
[
{
  "EventTime": "2026-08-18T06:10:00Z",
  "ServiceName": "billing-api",
  "Severity": "Error",
  "CorrelationId": "dcr-canary-20260818-pass",
  "Payload": "controlled validation event"
},
{
  "EventTime": "2026-08-18T06:10:01Z",
  "ServiceName": "billing-api",
  "Severity": "Information",
  "CorrelationId": "dcr-canary-20260818-filter",
  "Payload": "expected to be filtered"
},
{
  "EventTime": "2026-08-18T06:10:02Z",
  "ServiceName": "billing-api",
  "Severity": null,
  "CorrelationId": "dcr-canary-20260818-null",
  "Payload": "schema boundary"
}
]

Attendez le délai d’ingestion observé sur ce flux, puis cherchez les identifiants attendus. Le premier doit arriver, le second doit être absent pour une raison documentée, et le troisième doit suivre la politique explicite choisie pour les valeurs nulles. Répétez avec l’ancienne et la nouvelle transformation hors production si le diagnostic reste ambigu.

Décider entre correction et rollback

La décision doit citer une preuve et un test de sortie.

yaml dcr-change-decision.yml
decision:
action: rollback_transform
reason:
  - lignes recues stables apres le deploiement
  - lignes abandonnees en hausse sur le stream cible
  - canary Error absent avec la nouvelle transformation
  - canary Error present avec la version precedente
scope:
  dcr: dcr-app-events-prod
  data_flow: Custom-AppEventsRawData vers AppEvents_CL
validation:
  - canary passant visible dans la table cible
  - ligne Information toujours filtree comme prevu
  - aucune erreur nouvelle dans DCRLogErrors
  - alertes dependantes rejouees sur une fenetre controlee
stop_conditions:
  - volume d'ingestion depasse la baseline
  - donnees sensibles apparaissent dans Payload
  - erreurs de transformation persistent apres rollback

Corrigez en avant si le défaut est étroit, compris et testé : par exemple une conversion nullable ou une nouvelle valeur de sévérité. Rollbackez si des événements critiques disparaissent, si le schéma réel n’est pas maîtrisé ou si plusieurs producteurs sont touchés. Si la source n’envoie plus rien, ne modifiez pas la transformation : restaurez d’abord le producteur ou l’association DCR.

Après rollback, conservez la configuration fautive, les métriques, les erreurs et les identifiants canary. Vérifiez aussi les alertes et tableaux de bord dépendants. Restaurer les lignes sans rétablir les détections n’est qu’un retour partiel.

Conclusion

Des logs manquants après un changement de DCR ne se diagnostiquent pas depuis la table cible seule. Il faut suivre le flux : émission, endpoint ou association, stream, lignes reçues, transformation, erreurs et destination.

Le changement est validé uniquement si un canary prouve les lignes conservées et filtrées, si les métriques restent dans leur baseline et si les usages aval fonctionnent. Sinon, rollbackez la transformation bornée, gardez le dossier de preuves et corrigez le contrat de schéma avant une nouvelle mise en production.