Introductie
Databeveiliging sloot af met threat detection: dezelfde infrastructuur die afwijkend toegangsgedrag signaleert, blijkt in de praktijk vaak ook waar operationele problemen het eerst zichtbaar worden. Dit hoofdstuk maakt dat raakvlak expliciet. Waar Datakwaliteit & Testen beantwoordt of de data correct is, beantwoordt monitoring & observability of het systeem gezond is — en, minstens zo belangrijk, hoe snel je dat weet wanneer het niet zo is.
De Drie Pijlers van Observability
Observability — het vermogen om de interne staat van een systeem af te leiden uit de signalen die het naar buiten stuurt — rust traditioneel op drie pijlers, elk met een ander soort vraag:
- Metrics: numerieke tijdreeksen (aantal verwerkte rijen per run, pipeline-duur, CPU-gebruik van een warehouse). Beantwoordt "hoeveel" en "hoe snel", geaggregeerd over tijd.
- Logs: tijdgestempelde, discrete gebeurtenissen (een taak start, een taak faalt met een specifieke foutmelding). Beantwoordt "wat is er precies gebeurd", op het niveau van één gebeurtenis.
- Traces: het end-to-end pad van een verzoek of run door meerdere systemen heen (een Airflow-DAG die een dbt-run triggert die op zijn beurt een Snowflake-warehouse aanspreekt). Beantwoordt "waar in de keten ging het mis of werd het traag".
Dit raamwerk komt oorspronkelijk uit software engineering, maar vertaalt direct naar datapipelines: metrics vertellen je dát een run drie keer zo lang duurde als normaal, logs vertellen je waarom (een specifieke taak liep vast op een schema-mismatch), en traces vertellen je waar in de DAG dat gebeurde.
Pipeline-gezondheid versus Datakwaliteit: Twee Aparte Vragen
Een pipeline kan foutloos draaien en toch verkeerde data opleveren, en een pipeline kan crashen terwijl de data die al binnen is volledig correct blijft. Dit zijn onafhankelijke faalmodi die aparte bewaking vereisen:
| Vraag | Domein | Voorbeeldsignaal |
|---|---|---|
| Draait de pipeline op tijd? | Monitoring (dit hoofdstuk) | Run-duur, laatste succesvolle run-tijdstip |
| Faalt een taak met een fout? | Monitoring (dit hoofdstuk) | Foutlogs, exit codes, retry-tellers |
| Is de data compleet en juist? | Datakwaliteit & Testen | dbt-tests, anomaliedetectie op datawaarden |
| Klopt de rijentelling met gisteren? | Beide — een grensgeval | Volume-anomalie: kan een pipeline-bug óf een brondata-probleem zijn |
Dat laatste grensgeval is waarom de twee disciplines in de praktijk vaak dezelfde tooling delen: een onverwachte volumedaling kan net zo goed wijzen op een kapotte pipeline als op een probleem bij de bron. Monitoring signaleert dát er iets afwijkt; het onderzoek dat daarop volgt bepaalt in welk domein de oorzaak ligt.
SLA's, SLO's en SLI's Voor Data
Drie termen die vaak door elkaar worden gebruikt maar een strikte hiërarchie vormen:
- SLI (Service Level Indicator): de gemeten waarde zelf — bijvoorbeeld "minuten tussen het laatste brondata-record en het beschikbaar zijn van de bijbehorende gold-tabel".
- SLO (Service Level Objective): het interne doel voor die indicator — bijvoorbeeld "95% van de dagen is de gold-tabel binnen 30 minuten na middernacht ververst".
- SLA (Service Level Agreement): een extern, vaak contractueel toegezegde belofte aan een consument, doorgaans losser dan de interne SLO om ruimte te houden voor incidentele afwijkingen.
# Voorbeeld: SLO-definitie voor een gold-tabel, als config naast de pipeline
slo:
table: gold.omzet_per_klant
freshness_target_minutes: 30
target_percentage: 95
measurement_window_days: 30
completeness_target_percentage: 99.5
Het punt van deze hiërarchie: een SLO die je nooit meet, is geen SLO maar een wens. Concreet meetbare SLI's — freshness, volledigheid, foutpercentage per run — zijn de voorwaarde om een SLO ooit te kunnen bewaken, laat staan een SLA extern te durven beloven.
Alerting: Drempelwaarden versus Anomaliedetectie
Twee fundamenteel verschillende manieren om te bepalen wanneer iets een melding waard is:
Drempelwaarde-alerting vuurt wanneer een metric een vaste grens overschrijdt — "waarschuw als de pipeline-duur langer is dan 45 minuten". Eenvoudig te begrijpen en te debuggen, maar bot: een drempel die goed werkt bij een stabiele workload, is te streng op een drukke maandag en te soepel op een rustige zondag.
Anomaliedetectie vergelijkt een metric met zijn eigen historische patroon — inclusief dag-van-de-week- en seizoenseffecten — en waarschuwt bij statistisch ongebruikelijke afwijkingen, ongeacht de absolute waarde. Dit is exact hetzelfde principe als de anomaliedetectie op datawaarden uit Datakwaliteit & Testen en de gebruikersgedrag-detectie uit Databeveiliging, hier toegepast op operationele metrics.
# Vereenvoudigde anomaliedetectie op pipeline-duur t.o.v. de laatste 30 runs
import statistics
def is_duration_anomalous(current_minutes: float, history: list[float], z_threshold: float = 3.0) -> bool:
"""Vlagt een run-duur die meer dan z_threshold standaarddeviaties afwijkt."""
mean = statistics.mean(history)
stdev = statistics.stdev(history) or 1.0 # voorkom deling door nul bij weinig variatie
z_score = (current_minutes - mean) / stdev
return abs(z_score) > z_threshold
Laat de Snowflake Query Optimizer je queryplan analyseren op kostbare stappen.
Alert Fatigue: het Stille Faalmodel van Alerting
Een alertsysteem dat te vaak of op te lage urgentie meldt, traint mensen — onvermijdelijk — om meldingen te negeren. Dit heet alert fatigue, en het is gevaarlijker dan geen alerting hebben: een team zonder alerting weet dat het blind is, een team met genegeerde alerts denkt bewaakt te zijn terwijl het dat feitelijk niet meer is. Twee tegenmaatregelen die het meeste verschil maken: alerts naar urgentie differentiëren (een gemiste SLO om 3 uur 's nachts wachten tot de ochtend versus een pipeline die productie-rapportages blokkeert direct escaleren), en elke alert koppelen aan een duidelijke, uitvoerbare vervolgstap — een melding zonder aanwijzing wat je ermee moet, traint hetzelfde negeergedrag als een melding die te vaak vals afgaat.
Data Observability-tooling: een Vergelijking
| Categorie | Voorbeelden | Sterk in |
|---|---|---|
| Platform-native | Databricks Lakehouse Monitoring, Snowflake Trust Center/Query History | Geen aparte infrastructuur, direct gekoppeld aan het platform dat je al gebruikt |
| dbt-ecosysteem | Elementary, dbt Cloud-observability | Freshness- en testresultaten direct uit dbt-artefacten, weinig extra instrumentatie nodig |
| Gespecialiseerde data observability | Monte Carlo, Bigeye | Automatische anomaliedetectie over veel tabellen tegelijk, minder handmatige regelconfiguratie |
| Algemene APM/infrastructuur | Datadog, Grafana + Prometheus | Eén dashboard voor zowel infrastructuur als datapipelines, sterk in tracing |
Net als bij de vector-database-afweging voor RAG-systemen geldt hier een vergelijkbare vuistregel: platform-native tooling voorkomt een aparte synchronisatiepijplijn en is meestal de pragmatische eerste keuze; gespecialiseerde tooling wordt de moeite waard zodra je platform-overstijgend of over tientallen tot honderden tabellen tegelijk moet bewaken.
Gestructureerd Loggen van Pipeline-runs
Een pipeline die alleen "Failed" print naar een uitvoerlog is nauwelijks beter dan een pipeline zonder logging. Gestructureerd loggen — elke gebeurtenis als machine-leesbaar record met consistente velden, in plaats van vrije tekst — maakt logs doorzoekbaar, aggregeerbaar en koppelbaar aan metrics en traces.
import logging
import json
import time
logger = logging.getLogger("pipeline.orders_ingestion")
def run_with_structured_logging(pipeline_func, run_id: str, source: str):
start = time.monotonic()
logger.info(json.dumps({
"event": "run_started", "run_id": run_id, "source": source,
}))
try:
row_count = pipeline_func()
logger.info(json.dumps({
"event": "run_succeeded", "run_id": run_id, "source": source,
"row_count": row_count, "duration_seconds": time.monotonic() - start,
}))
except Exception as exc:
logger.error(json.dumps({
"event": "run_failed", "run_id": run_id, "source": source,
"error": str(exc), "duration_seconds": time.monotonic() - start,
}))
raise
Het run_id-veld is hier het belangrijkste onderdeel: dezelfde identifier die door een orchestrator (Airflow, ADF) wordt meegegeven, laat je logs, metrics én de trace van diezelfde run aan elkaar koppelen — de praktische invulling van "de drie pijlers werken samen" uit de inleiding.
Distributed Tracing over Orchestratiegrenzen Heen
Een moderne datapipeline loopt zelden binnen één systeem: een Airflow-DAG triggert een dbt-run, die queries uitvoert op een warehouse, die op zijn beurt resultaten wegschrijft die een BI-tool oppikt. Wanneer een dashboard te laat ververst, ligt de oorzaak ergens in die keten — maar waar?
Distributed tracing (met OpenTelemetry als de facto standaard) lost dit op door een enkele trace-ID door de hele keten mee te geven, zodat elke stap — Airflow-taak, dbt-model, warehouse-query — als span onder diezelfde trace wordt geregistreerd. Het resultaat is een tijdlijn die precies toont welke schakel de vertraging veroorzaakte, in plaats van dat je losse logs uit vier systemen handmatig naast elkaar moet leggen.
Trace: daily_orders_refresh (14:02:03 - 14:19:47, 16m 44s totaal)
├─ Span: airflow.task.extract_orders (2m 10s)
├─ Span: airflow.task.trigger_dbt_run (11m 58s) ← grootste blok
│ ├─ Span: dbt.model.stg_orders (0m 40s)
│ └─ Span: dbt.model.fct_orders (11m 12s) ← werkelijke boosdoener
└─ Span: airflow.task.notify_bi_refresh (2m 36s)
Zonder tracing zou dit onderzoek betekenen: Airflow-logs doorzoeken, dan handmatig naar dbt-run-logs overstappen, dan de warehouse-query-history erbij pakken — drie aparte systemen, drie aparte tijdstempel-formaten. Met een gedeelde trace-ID is de boosdoener in één oogopslag zichtbaar.
Kosten als Observability-signaal
Compute-kosten zijn zelf een metric die de moeite waard is om te monitoren, niet alleen om te budgetteren. Een dbt-model waarvan de compute-kosten geleidelijk stijgen zonder dat het datavolume evenredig groeit, wijst vaak op precies hetzelfde onderliggende probleem als de onbedoelde volledige verversing uit Snowflake Dynamic Tables vs Views: een query die efficiënter zou kunnen, of een incrementele strategie die stilletjes is teruggevallen op een volledige herberekening. Kostenmetrics per model of per tabel — niet alleen op accountniveau — maken dit soort sluipende regressies zichtbaar vóórdat de eindfactuur het doet.
Runbooks: van Alert naar Actie
Een alert zonder runbook verplaatst het probleem alleen: in plaats van niet te weten dát er iets misging, weet je het nu wel maar moet iedereen die op-call staat het onderzoek opnieuw uitvinden. Een runbook is een kort, specifiek document per alert-type dat de eerste onderzoeksstappen vastlegt — niet de volledige oplossing, want die verschilt per incident, maar wel waar te beginnen.
## Runbook: SLO-breach op gold.omzet_per_klant (freshness)
1. Check de laatste dbt-run: `dbt Cloud → Run History → gold.omzet_per_klant`
2. Faalde de run, of draaide hij te laat?
- Faalde: bekijk de trace (zie hierboven) om het falende model te vinden
- Te laat: check of de bron-extractie (Airflow: extract_orders) op tijd startte
3. Bronprobleem? Escaleer naar het bronsysteem-team via #data-incidents
4. Pipeline-probleem? Herstart vanaf het gefaalde model met `dbt run --select +fct_orders`
5. Update de incident-tracker, ongeacht de oorzaak
Runbooks zijn ook waar monitoring en documentatie elkaar raken: net zoals Data Governance pleit voor metadata die niet losraakt van de tabel zelf, moet een runbook direct vindbaar zijn vanuit de alert — een link in het alertbericht, niet een document dat iemand eerst moet opzoeken terwijl de klok doortikt.
Best Practices
- Instrumenteer metrics, logs én traces met een gedeelde run-ID, zodat je bij een incident niet drie systemen los hoeft te doorzoeken.
- Definieer SLI's voordat je een SLO belooft — een ongemeten doel is een wens, geen objectief.
- Differentieer alerts naar urgentie in plaats van alles even zwaar te laten afgaan; dit is de meest effectieve tegenmaatregel tegen alert fatigue.
- Koppel elke alert aan een uitvoerbare vervolgstap, niet alleen aan een geconstateerde afwijking.
- Monitor compute-kosten per model, niet alleen op accountniveau, om sluipende performance-regressies vroeg te signaleren.
Veelgemaakte Fouten
- Alleen metrics bewaken zonder logs of traces, waardoor je weet dát iets misging maar niet snel genoeg kunt achterhalen waar of waarom.
- Vaste drempelwaarden zonder rekening te houden met dag-van-de-week-patronen, wat leidt tot valse alarmen op drukke dagen en gemiste problemen op rustige dagen.
- Elke afwijking met dezelfde urgentie melden, de directe oorzaak van alert fatigue en het negeren van meldingen die er wél toe doen.
- Pipeline-gezondheid en datakwaliteit als hetzelfde probleem behandelen, terwijl het onafhankelijke faalmodi zijn die allebei aparte, gerichte bewaking nodig hebben.
- Compute-kosten pas bij de maandfactuur voor het eerst bekijken, in plaats van als doorlopend monitoringsignaal per model.
Performance Tips
- Aggregeer metrics vóór opslag (per minuut of per run, niet elke individuele gebeurtenis) om de monitoring-infrastructuur zelf niet tot een bottleneck te laten worden.
- Bewaar ruwe logs korter dan geaggregeerde metrics — gedetailleerde logs zijn duur om lang te bewaren en meestal alleen relevant voor recente incidentonderzoeken.
- Sample traces bij zeer hoogfrequente pipelines in plaats van elke run volledig te traceren, om overhead te beperken zonder het diagnostische nut te verliezen.
- Houd anomaliedetectie-vensters representatief (bijvoorbeeld de laatste 30 vergelijkbare dagen, niet de laatste 30 kalenderdagen) zodat weekend- of piekeffecten de baseline niet vertekenen.
Interviewvragen
"Wat zijn de drie pijlers van observability, en waar is elk goed in?" Let op: metrics (hoeveel/hoe snel, geaggregeerd), logs (wat gebeurde er precies, per gebeurtenis), traces (waar in een keten van systemen ging het mis) — samen geven ze een vollediger beeld dan elk apart.
"Wat is het verschil tussen een SLI, SLO en SLA?" Let op: SLI is de gemeten indicator zelf; SLO is het interne doel voor die indicator; SLA is een extern, vaak contractueel toegezegde belofte — meestal losser dan de interne SLO.
"Waarom is anomaliedetectie vaak beter dan een vaste drempelwaarde voor alerting?" Let op: een vaste drempel houdt geen rekening met normale variatie (dag-van-de-week, seizoen), wat leidt tot valse alarmen op drukke momenten en gemiste problemen op rustige momenten; anomaliedetectie vergelijkt met het eigen historische patroon.
"Wat is alert fatigue en hoe voorkom je het?" Let op: het stille faalmodel waarbij te veel of te lage-urgentie-meldingen ertoe leiden dat mensen alerts gaan negeren; tegenmaatregelen zijn urgentie-differentiatie en elke alert koppelen aan een uitvoerbare vervolgstap.
"Hoe helpt distributed tracing bij het debuggen van een trage multi-systeem pipeline?" Let op: een gedeelde trace-ID door Airflow, dbt en het warehouse heen laat je in één tijdlijn zien welke specifieke schakel de vertraging veroorzaakte, in plaats van logs uit meerdere systemen handmatig te correleren.
"Waarom zijn pipeline-monitoring en datakwaliteitstesten aparte disciplines, ook al overlappen ze soms?" Let op: een pipeline kan foutloos draaien met verkeerde data, of crashen terwijl bestaande data correct blijft — onafhankelijke faalmodi; een volume-anomalie is het grensgeval waar beide disciplines hetzelfde signaal delen.
Relevante Documentatie
- OpenTelemetry: Traces — de facto standaard voor distributed tracing.
- Google SRE Book: Service Level Objectives — het canonieke naslagwerk over SLI/SLO/SLA.
- dbt: Elementary Data Observability — observability direct bovenop dbt-artefacten.
- Databricks: Lakehouse Monitoring — platform-native monitoring voor Delta-tabellen.
Samenvatting
Monitoring & observability beantwoordt een andere vraag dan datakwaliteit: niet "is de data correct", maar "is het systeem gezond, en weten we dat snel genoeg". De drie pijlers — metrics, logs, traces — werken pas echt samen met een gedeelde run-ID die ze aan elkaar koppelt. SLI's maken SLO's meetbaar in plaats van wensen, anomaliedetectie voorkomt de valse-alarm-problematiek van vaste drempelwaarden, en gerichte urgentie-differentiatie is de beste bescherming tegen alert fatigue. Met de operationele bewaking van het platform behandeld, verschuift de aandacht in het volgende hoofdstuk naar een andere ontwikkeling die zowel monitoring als de rest van het vak verandert: AI voor Data Engineers.
Hulp nodig bij het bouwen van een modern dataplatform?
DataPartner365 helpt organisaties met Microsoft Fabric, Snowflake, Databricks, dbt, Azure, data-architectuur en CI/CD.
Neem contact op met DataPartner365