Een copy activity mislukt stilzwijgend om 3 uur 's nachts en Power BI wordt desondanks vernieuwd.
Het bronteam heeft customer_id hernoemd naar cust_id in de Salesforce-export. De ADF-copy activity leest uit een opgeslagen procedure die nog steeds naar de oude kolom verwijst. De activiteit retourneert 'Geslaagd' — nul rijen gekopieerd, geen uitzondering gegenereerd, omdat de kolomtoewijzing was ingesteld op 'automatisch' en het schema-driftbeleid het niet-toegewezen veld stilzwijgend heeft verwijderd. De pipeline meldt 'Geslaagd'. De downstream Power BI dataset wordt vernieuwd met de lege stagingtabel. Om 9 uur 's ochtends opent de CFO een dashboard dat de omzet van gisteren op $ 0 laat zien.
Dit is de kloof die de native Azure Monitor-waarschuwingen niet kunnen dichten — en precies het soort foutmodus waarvoor speciale data-observabilityplatformen zijn ontworpen.
ADF toont monitoring op vier plaatsen: het Azure Monitor-metriekvenster, de pipeline runsgeschiedenis in de studio, waarschuwingsregels via actiegroepen en Log Analytics met diagnostische logboeken. De meeste teams configureren er twee — pipeline runsgeschiedenis (standaard ingeschakeld) en een enkele actiegroep die de distributielijst van het team e-mailt wanneer een pipeline mislukt. Dat dekt het geval waarin de pipeline een foutmelding geeft. Het dekt het bovenstaande geval niet.
Wat de standaard ADF-waarschuwingsfunctie je nu eigenlijk biedt.
Het ondersteunde pad voor foutwaarschuwingen op pipelineniveau bestaat uit vijf stappen. Open in je Data Factory de diagnostische instellingen en routeer de categorieën PipelineRuns en ActivityRuns naar een Log Analytics-werkruimte. Wacht tot de logboeken binnenkomen (2-5 minuten na de volgende uitvoering). Maak in Azure Monitor een geplande queryregel voor die werkruimte. Koppel een actiegroep met e-mail, een Teams-webhook of een ITSM-connector. De basis-KQL voor pipeline fouten is:
``kusto
ADFPipelineRun
| where TimeGenerated > ago(15m)
| where Status == "Failed"
| project TimeGenerated, PipelineName, RunId, Status, FailureType, Message=ErrorMessage
``
End-to-end latentie: 3-10 minuten van fout tot e-mail. De regel wordt één keer per evaluatievenster uitgevoerd. De dekking is alleen op pipelineniveau (status) — alles wat als pipeline fout wordt gemeld, wordt opgevangen. Wat het mist: fouten op activiteitsniveau binnen een succesvolle pipeline, schema-afwijkingen die leiden tot onjuiste uitvoer, gevolgen voor Power BI of Databricks, en de vraag of de tien waarschuwingen die je zojuist om 3 uur 's nachts hebt ontvangen, één incident of tien betreffen.
De kloof in activiteitsniveau
De status van een pipeline wordt berekend op basis van het orchestratieresultaat, niet op basis van de data. Een copy activity met enableSkipIncompatibleRow: true slaat rijen over en rapporteert 'Geslaagd'. Een opzoekactiviteit met een onjuist geformuleerde query die een lege resultaatset retourneert, is een succesvolle uitvoering. Een ForEach-lus over een lege array wordt binnen milliseconden voltooid met de status 'Geslaagd'.
Het geval van een schema-mismatch is het meest problematisch. De tabulaire vertaler van ADF met mapComplexValuesToString en automatische mapping tolereert een hernoemde kolom door deze uit de projectie te verwijderen. De copy activity rapporteert rowsCopied: 487293 en de status 'Geslaagd' — het aantal rijen klopt, maar de kolommen zijn onjuist. Monitoring op pipeline niveau zal dit nooit zien. Het enige signaal is het aantal rijen zelf, geparseerd uit de JSON-output van de activiteit, vergeleken met een verwachte basislijn.
KQL voor activiteitsniveaudetectie
Voor het genereren van waarschuwingen op activiteitsniveau is het nodig om ADFActivityRun rechtstreeks op te vragen en de kolom Output te parsen. Hier is een werkende query die zowel expliciete fouten als copy activities met nul rijen detecteert:
```kusto ADFActivityRun | where TimeGenerated > ago(15m) | where ActivityType in ("Copy", "Lookup", "ExecuteDataFlow") | extend Output = parse_json(Output) | extend rowsCopied = toint(Output.rowsCopied),
rowsRead = toint(Output.rowsRead),
errors = toint(Output.errors) | where Status == "Failed"
or (ActivityType == "Copy" and Status == "Succeeded" and (rowsCopied == 0 or errors > 0)) | ```` project TimeGenerated, PipelineName, ActivityName, ActivityType, Status,
rowsRead, rowsCopied, errors, ErrorMessage=tostring(Error.message) ```
Dit werkt. Het vereist echter wel dat je weet welke activiteiten een zinvolle baseline van nul rijen hebben (een delta-load kan op een rustige dag legitiem nul rijen kopiëren), met welk verwacht aantal rijen je wilt vergelijken en welke pipelines deze behandeling nodig hebben. Reserveer 15-30 minuten per pipeline voor het schrijven, testen en afstemmen. Vermenigvuldig dit met je portfolio. De kosten zitten niet in de KQL, maar in het onderhoud wanneer activiteitsnamen veranderen, wanneer nieuwe pipelines worden uitgebracht zonder waarschuwingen en wanneer dezelfde fout vijf regels in een fan-out activeert.
Waar gerichte monitoring zijn nut bewijst
Er doen zich drie problemen voor zodra je portfolio ongeveer vijf pipelines omvat of je stack een mix is van ADF met Databricks, dbt of Power BI.
Correlatie tussen pipelines. De ADF-kopieerfout om 03:14 is hetzelfde incident als de dbt-modelfout 'staging_orders' om 03:22 en het Power BI signaal 'refresh_delayed' voor de dataset 'Sales Executive' om 06:00. De standaardtools behandelen deze als drie waarschuwingen in drie verschillende inboxen. Het betreft echter één incident met een duidelijke oorzaak-gevolgrelatie.
Deduplicatie. Een pipeline die via ForEach naar 12 datasets uitwaaiert, genereert 12 activiteitsfouten met dezelfde hoofdoorzaak. Actiegroepen sturen je 12 e-mails, of één per regel, afhankelijk van hoe je de drempelwaarde hebt ingesteld – geen van beide is de juiste oplossing. De juiste oplossing is groeperen op hoofdoorzaak.
Het blootleggen van de hoofdoorzaak. De ErrorMessage-kolom van ADF geeft de foutmelding Operation on target Copy data1 failed: ErrorCode=2200, ..., gevolgd door 2 KB aan stacktrace. Het relevante detail — kolom 'customer_id' niet gevonden in bron — staat erin, maar je moet het zelf lezen. Speciale tools parseren deze foutmeldingen, tonen de kolomnaam en koppelen deze aan de schemawijziging die de fout heeft veroorzaakt.
Hier komt MetricSign in beeld: het leest ADF-activiteitenlogboeken via dezelfde diagnostische stream die je al hebt geconfigureerd, groepeert fouten in incidenten voor ADF, Databricks, dbt en Power BI, en toont de aanwijzing voor de hoofdoorzaak in plaats van de stacktrace.
Wat moet er daadwerkelijk gebouwd worden?
Voor één tot vier pipelines zonder downstream BI-afhankelijkheden: configureer de diagnostische instellingen, schrijf de bovenstaande waarschuwingsregel op pipeline niveau, koppel een actiegroep en stop. De native methode is voldoende. Besteed de tijd liever aan datakwaliteitstests binnen de pipelines.
Voor portfolio's met gemengde orchestratie (ADF die Databricks triggert, dbt die volgens een schema draait, Power BI die daar bovenop ververst) of voor pipelines met een SLA waarbij stakeholders binnen een uur een probleem zullen opmerken: de KQL-aanpak per pipeline loopt tegen een onderhoudslimiet aan bij ongeveer vijf tot tien pipelines. De rekensom draait om: de engineeringuren die worden besteed aan het implementeren van waarschuwingen overstijgen de kosten van een tool die standaard correlatie, deduplicatie en oorzaakanalyse uitvoert. Beslis op basis van de portfoliogrootte en de diversiteit van de stack, niet op basis van of de native methode 'werkt'. Die werkt wel. Maar is niet schaalbaar voor de fouten die je wakker schudden.