Betrieb Observability & Notfälle¶
Seitenregeln¶
- Single Source of Truth für laufenden Betrieb, Sichtbarkeit und Incident‑Response.
- Enthält konkrete Runbooks/Playbooks; keine Architektur‑ oder Policy‑Texte.
- Messgrößen und Schwellwerte sind verbindlich und referenzieren Dashboards/Alarme.
- Nach größeren Änderungen Smoke‑Tests/DR‑Tests dokumentieren.
- Aktualisieren bei: neuen Dashboards/Alerts, SLO‑Änderungen, Post‑Mortems.
- Verweise auf: „Build, Deployment & Laufzeit“ (Start/Update/Rollback), „Daten, …“ (Restore‑Prozesse).
- Benenne betroffene Dateien inkl. Pfad als Unterpunkte, wenn diese für zukünftige Änderungen relevant.
Zweck und Abgrenzung¶
- Zweck: Sicherer 24/7‑Betrieb der n8n‑Workflows und der PostgreSQL‑Datenhaltung (Kurse, Indikatoren, Marktstatus, Signale).
- Abgrenzung: Keine Zukunfts‑Pläne; nur aktuell implementierte Workflows/Knoten, Tabellen, Checks und manueller Betrieb.
SLIs/SLOs¶
- SLI Workflow‑Erfolg: Anteil erfolgreicher n8n‑Runs je Job (Quelle: core.job_runs.status).
- SLI Datenaktualität Kurse: Zeit seit letztem Preis für ein Wertpapier (Differenz max(date) vs. Heute).
- SLI Datenaktualität Marktstatus: Zeit seit letztem Eintrag in core.market_state.
- SLOs (derzeit manuell überwacht):
- Kurse (XETR): neueste Zeile ≤ T+1 Handelstag.
- Marktstatus (VIX‑Proxy): neuester Eintrag ≤ T+1 Kalendertag.
- Workflow‑Runs: 100% „ok“ für manuell ausgelöste Runs.
Beispiel‑SQL (SLIs):
-- Letztes Kursdatum je ISIN (XETR)
SELECT isin, MAX(date) AS last_price
FROM core.prices_daily
WHERE mic='XETR'
GROUP BY isin;
-- Letzter Marktstatus
SELECT MAX(date) AS last_market_state FROM core.market_state;
-- Job-Erfolgsquote
SELECT job_name,
AVG(CASE WHEN status='ok' THEN 1 ELSE 0 END)::numeric(5,2) AS success_rate
FROM core.job_runs
GROUP BY job_name;
Monitoring/Metriken/Dashboards¶
- Monitoring-Quellen aktuell:
- n8n Executions UI (Erfolg/Fehler pro Knoten/Workflow).
- PostgreSQL Abfragen (SLIs oben).
- Dashboards: noch keine externe Visualisierung im Einsatz; Prüfung erfolgt via n8n UI + SQL‑Abfragen.
Logging (Quellen, Struktur, Retention)¶
- Quellen:
- n8n Execution Logs (internal).
- core.job_runs (Start, Ende, Status, Fehlertext).
- core.alerts_log (für spätere Alerts, derzeit ohne Einträge).
- core.data_quality (erkannte Datenprobleme).
- Retention:
- PostgreSQL: keine TTL aktiv; Logs verbleiben dauerhaft bis manueller Purge.
- n8n Executions: Retention gemäß n8n‑Einstellungen der Instanz.
Alarmierung/On‑Call/Schwellwerte¶
- Aktueller Stand:
- Keine automatischen Alarme konfiguriert.
- Manuelle Checks per SQL/n8n UI.
- Schwellwerte (für manuelle Prüfung):
- Kein neuer Marktstatus > 2 Tage → untersuchen.
- Kein neuer Preis (XETR) > 3 Handelstage → untersuchen.
- job_runs.status in ['fail','partial'] → untersuchen.
Wartungsfenster/Standardaufgaben¶
- Wöchentlich:
- Sichtprüfung n8n Executions (fehlgeschlagene Runs identifizieren).
- SQL‑Quick‑Checks (SLIs oben).
- Monatlich:
- VACUUM/ANALYZE Empfehlung auf mf_app (Datenpflege).
- Bei Schema‑Anpassungen:
- Export der Workflows (n8n JSON).
- pg_dump der Datenbank.
Beispiel:
# In den Postgres-Container
docker exec -it n8n-n8n-postgres-1 psql -U n8n -d mf_app -c "VACUUM ANALYZE;"
Performance‑/Kapazitätsmanagement¶
- Indizes aktiv:
- core.prices_daily (isin,date)
- core.mf_rank (region,run_month,percentile)
- core.listings UNIQUE (isin) WHERE primary_flag
- Beobachtungen:
- Bulk‑Upserts (n8n) werden gebatcht; Performance ausreichend für Backfills (XETR‑Historien).
- Speicherbedarf überwiegend in core.prices_daily; Stooq‑Historien > 15 Jahre möglich.
Runbooks (häufige Tasks)¶
- Manuelles Hinzufügen einer Aktie (XETR):
- Workflow „mf_workflow - Add Security (ISIN → Listing → Prices)“ starten → Formular „Form: Add ISIN“ mit ISIN befüllen → Ausführen.
- Prüfung: core.securities, core.listings, core.prices_daily (neue Zeilen vorhanden), „PG: Update indicators…“, „PG: Compute signal…“ liefen ohne Fehler.
- Preise neu einlesen (Backfill XETR):
- Knoten „Stooq: Daily CSV (full)“ → „Code: Parse Stooq CSV → rows“ → „PG: Upsert prices (Stooq, full)“ nacheinander ausführen.
- Danach „PG: Update indicators (SMA200/52W/3D)“ erneut ausführen.
- Signal neu berechnen (Price‑only):
- Knoten „PG: Compute signal (price-only test)“ ausführen.
- Prüfung: core.signals letzte Zeile (status, rule_breakdown).
- Marktstatus aktualisieren:
- Workflow „Market State Update“ → „VIX Fetch“ → „VIX Parse“ → „Market State Upsert“.
- Prüfung: core.market_state (neuer Eintrag mit source='proxy_vix_stooq').
- Rate‑Limit/Fehler Alpha Vantage:
- Fallback: Stooq‑Pfad nutzen (bereits integriert).
- API‑Key‑Rotation in n8n:
- Credentials (openfigi_api, alpha_vantage, simfin, fmp) in der UI anpassen.
- Testen: HTTP‑Knoten „OpenFIGI: ISIN → XETR mapping“ und „AlphaVantage: Daily (compact, JSON)“.
Incident‑Response (Störung, Eskalation, Post‑Mortem)¶
- Erkennung:
- Fehler in n8n Executions oder „fail/partial“ in core.job_runs.
- Unerwartete Lücken per SLI‑SQL (z. B. fehlendes Kursdatum).
- Erstmaßnahmen:
- n8n‑Fehlerdetails öffnen → fehlerhaften Knoten identifizieren.
- Externe Datenquelle prüfen (OpenFIGI/AV/Stooq Erreichbarkeit).
- Erneute manuelle Ausführung der betroffenen Knoten.
- Datenintegrität:
- Bei defekten Importen betroffene ISIN in core.data_quality dokumentieren (issue_type, severity, note).
- Falls nötig einzelne Tage in core.prices_daily löschen/neu laden (DELETE … WHERE isin=… AND date BETWEEN …).
- Post‑Mortem:
- Kurzbeschreibung von Ursache/Auswirkung/Behebung in Wiki notieren.
- Optional SQL‑Auszug/Logs anhängen.
Hilfs‑SQL:
-- Stale Preise XETR > 3 Tage
SELECT s.isin, s.name, MAX(p.date) AS last_price
FROM core.securities s
LEFT JOIN core.prices_daily p ON p.isin=s.isin AND p.mic='XETR'
GROUP BY s.isin, s.name
HAVING MAX(p.date) < (CURRENT_DATE - INTERVAL '3 day');
-- Fehlgeschlagene Jobs
SELECT * FROM core.job_runs WHERE status IN ('fail','partial') ORDER BY started_at DESC;
DR/Restore‑Smoke‑Tests (Ergebnisse/Termine)¶
- 2026‑02‑01: Initiale Funktionsprüfung erfolgreich
- „Add Security“-Flow mit ISIN DE000BASF111 ausgeführt → core.securities/core.listings befüllt.
- Historienkurse via Stooq geladen → core.prices_daily befüllt.
- Indikatoren berechnet → SMA200/52W/3D/Drawdown vorhanden.
- Price‑only‑Signal berechnet → core.signals (status=no; breakdown dokumentiert).
- Marktstatus (VIX‑Proxy) berechnet und gespeichert → core.market_state Eintrag vorhanden.
- Daten‑Pfade/Dateien:
- Docker‑Container: n8n-n8n-1, n8n-n8n-postgres-1 (Netz: deploy_internal).
- Postgres‑Volume: n8n_n8n_pg_data (Docker‑managed).
- Hinweis: Wiederholbare Smoke‑Tests erfolgen durch manuelles Ausführen der oben genannten Runbooks und Abgleich der Tabellenstände.