# Logging & Telemetrie

> Wie die DataBridge Logs erzeugt, welche Telemetrie sie sendet und wie Sampling die Kosten steuert.

---

Site [llms.txt](/llms.txt)

---

Die DataBridge steuert ihr Telemetrie-Volumen über **zwei voneinander unabhängige
Mechanismen**:

- **Gepuffertes Logging** — Log-Einträge werden pro Funktionsausführung gesammelt und
  erst am Ende des Laufs, abhängig vom Ergebnis, selektiv gesendet.
- **Sampling von Abhängigkeiten** — ausgehende Aufrufe an Quell- und Zielsysteme werden
  nur anteilig gesendet, sofern sie erfolgreich und schnell waren.

Der zweite Mechanismus ist der eigentliche Kostenhebel: In einer Volumenanalyse über
90 Tage entfielen rund **78 %** des gesamten Datenvolumens auf Abhängigkeiten und nur ein
Bruchteil auf Log-Einträge.

| Seite | Inhalt |
|---|---|
| [Metriken](metriken/) | Custom Metrics — die einzige nicht gesampelte Mengenangabe |
| [Performance & Laufzeiten](performance/) | KQL-Abfragen für Laufzeiten, Fehler, Abhängigkeiten und Datenvolumen |

---

## Gepuffertes Logging — drei Lauf-Ergebnisse

| Ergebnis | Kriterium | Gesendete Log-Level |
|---|---|---|
| **Normaler Lauf** | Keine Fehler, keine Warnungen | Nur Warning + Error + ~20 % der Information-Einträge (konfigurierbar) |
| **Lauf mit Warnungen** | Mindestens eine Warning, kein Fehler | Alle Information + Warning + Error |
| **Fehlerlauf** | Mindestens ein unbehandelter Fehler | Alle Debug + Information + Warning + Error |

Der Anteil der Information-Einträge im Normalbetrieb wird über
`TELEMETRY_INFO_SAMPLE_RATE` gesteuert (Standard: `20` = 20 %). Die Stichprobe wird
**pro Eintrag** gezogen — es entstehen also vereinzelte Traces aus allen Läufen,
keine vollständigen Ketten. Lückenlose Ketten gibt es nur bei Warning- und Fehler-Läufen.

### Trace-Level erreicht Application Insights nie

> **`LogTrace` ist ausschließlich live sichtbar**
>
> Log-Einträge auf Level `Trace` werden **niemals** an Application Insights gesendet —
> auch nicht bei Fehler-Läufen. Der Telemetriepfad ist auf `Debug` und höher begrenzt.
> 
> Sichtbar sind sie nur live: lokal in der Konsole bzw. im Container-Log, in Azure im
> **Log Stream** der Function App (oder per `az webapp log tail`).



---

## Sampling von Abhängigkeiten

Ausgehende Aufrufe an Quell- und Zielsysteme (D365 OData, SQL, Table Storage, Service Bus)
werden von Application Insights automatisch als *Dependencies* erfasst. Ohne Filterung
verursachen sie bei kurzem Polling-Intervall ein Vielfaches aller Log-Einträge zusammen.

| Aufruf | Wird gesendet |
|---|---|
| Fehlgeschlagen | **Immer** vollständig |
| Langsam (≥ `TELEMETRY_DEPENDENCY_SLOW_MS`) | **Immer** vollständig |
| Erfolgreich und schnell | Nur zum Anteil `TELEMETRY_DEPENDENCY_SAMPLE_RATE` (Standard 10 %) |

> **Die Entscheidung fällt pro Aufruf**
>
> Anders als beim Logging wird hier **pro Aufruf** entschieden, und zwar in dem Moment,
> in dem der Aufruf endet — also bevor bekannt ist, ob die Funktionsausführung insgesamt
> erfolgreich war.
> 
> Praktische Folge: Ein fehlgeschlagener Lauf enthält garantiert den fehlgeschlagenen
> Aufruf, aber **nicht zwangsläufig die erfolgreichen Aufrufe davor**. Wird der vollständige
> Verlauf für eine Analyse gebraucht, ist vorübergehend `TELEMETRY_CONTROL=TRACE_ALL`
> zu setzen.



---

## Steuerung über `TELEMETRY_CONTROL`

Die Einstellung wirkt auf **beide** Mechanismen — Traces *und* Abhängigkeiten:

| Wert | Wirkung |
|---|---|
| `TRACE_SAMPLE` (Standard) | Selektives Sampling wie oben beschrieben |
| `TRACE_ALL` | Sendet alles, deaktiviert jedes Sampling (für aktive Fehlersuche) |
| `TRACE_NONE` | Unterdrückt Traces und Abhängigkeiten vollständig |

Eine leere Variable entspricht `TRACE_SAMPLE`. Details zu allen Telemetrie-Einstellungen
stehen unter [Umgebungsvariablen](../../einrichtung/umgebungsvariablen/).

> **`TRACE_ALL` nicht dauerhaft setzen**
>
> `TRACE_ALL` deaktiviert sämtliches Sampling und kann das Datenvolumen um ein Vielfaches
> erhöhen — bis hin zum Erreichen der Tagesobergrenze (Daily Cap), ab der gar keine
> Telemetrie mehr ankommt. Nur gezielt für die Dauer einer Analyse aktivieren.



---

## Auswirkung auf bestehende Auswertungen

> **Bestehende Alerts und Dashboards prüfen**
>
> Verworfene Abhängigkeiten werden vollständig entfernt und **nicht** über einen
> Hochrechnungsfaktor (`itemCount`) kompensiert.
> 
> Auswertungen über `dependencies` / `AppDependencies`, die auf **absoluten Zählungen**
> oder Durchschnittslaufzeiten beruhen, liefern zu niedrige Werte.
> 
> Besonders kritisch sind **Fehlerquoten** der Form `countif(success == false) / count()`:
> Da fehlgeschlagene Aufrufe vollständig erhalten bleiben, erfolgreiche aber gesampelt
> werden, ist das Ergebnis **deutlich überhöht**. Solche Abfragen und darauf basierende
> Alerts sind zu entfernen oder auf die Tabelle `requests` umzustellen, die keinem
> Sampling unterliegt.



Nicht betroffen sind:

- **Fehleranzahlen und Fehlerursachen** — fehlgeschlagene Aufrufe werden nie verworfen
- **Auswertungen langsamer Aufrufe** — ab dem Schwellwert immer vollständig
- **Requests, Exceptions, Traces und [Custom Metrics](metriken/)** — unverändert

---

## Wichtige Log-Felder in Application Insights

| Feld | Beschreibung |
|---|---|
| `operation_Id` | Korrelations-ID — verknüpft alle Einträge einer einzigen Funktionsausführung |
| `operation_ParentId` | Span-ID des Requests — sorgt für die korrekte Einordnung in der End-to-End-Transaktionsansicht |
| `operation_Name` | Name der ausgeführten Function (z. B. `GetChanges`, `ProcessStandardQueueItems`) |
| `timestamp` | Zeitpunkt des **ursprünglichen** Log-Aufrufs, nicht des Sendens am Ende der Ausführung |
| `message` | Log-Text |
| `severityLevel` | 0 = Verbose, 1 = Information, 2 = Warning, 3 = Error, 4 = Critical |
| `customDimensions.Category` | .NET-Logger-Kategorie |
| `customDimensions.Exception` | Vollständiger Stack Trace (nur bei Exceptions) |

### Automatisch erfasste Telemetrie

Neben den eigenen Log-Einträgen erfasst Application Insights selbstständig:

- **Requests** — je Funktionsausführung, mit Laufzeit und Erfolgskennzeichen
- **Exceptions** — jede aufgetretene Ausnahme mit Stack Trace
- **Dependencies** — jeder ausgehende Aufruf (unterliegt dem Sampling, siehe oben)

---

## Auswertung im Azure Portal

### Schnelle Übersicht — Performance Blade

**Application Insights → Untersuchen → Leistung**

Zeigt alle Funktionsausführungen mit Durchschnittslaufzeit und P50/P95/P99-Perzentilen.
Ein hoher P95-Wert deutet auf gelegentliche Verzögerungen hin (langsames Zielsystem,
Queue-Stau).

### Fehlerdiagnose — Failures Blade

**Application Insights → Untersuchen → Fehler**

Fehlgeschlagene Aufrufe, gruppiert nach Fehlertyp, mit direktem Zugriff auf Stack Traces.

### Einzelne Ausführung verfolgen — Transaction Search

**Application Insights → Untersuchen → Transaktionssuche**

Filter nach `operation_Id`, um alle Einträge einer einzigen Ausführung zu sehen.

---

## Tipps für die Fehlersuche

1. **operation_Id finden:** Im Failures Blade auf einen fehlgeschlagenen Request klicken →
   End-to-End Transaction Details → `operation_Id` ist in der URL bzw. in den Details sichtbar.

2. **Komplette Traces aktivieren:** `TELEMETRY_CONTROL = TRACE_ALL` setzen, den
   problematischen Job über `ExecuteJob` manuell auslösen, anschließend zurücksetzen.

3. **Zwischen Funktionen korrelieren:** Schlägt eine der `Process…QueueItems`-Funktionen
   fehl, ist die `operation_Id` der ursprünglichen `GetChanges`-Ausführung in der Nachricht
   gespeichert — so lässt sich der vollständige Pfad eines Datensatzes nachvollziehen.
   Beachten Sie dabei die Einschränkung beim Dependency-Sampling (siehe oben).

---

Section pages:

- [Metriken](/docs/betrieb/logging/metriken/): Custom Metrics der DataBridge — vorab aggregiert und ohne Sampling.
- [Performance & Laufzeiten](/docs/betrieb/logging/performance/): KQL-Abfragen für Laufzeiten, Fehlerquoten, Abhängigkeiten und Datenvolumen.
