> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dreizack-medien.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Error-Tracking

## Was macht das Error-Tracking?

JTL speichert Core- und DB-Fehler im Systemlog (`tjtllog`) oft nur als **Halb-Log**: die SQL-Query, aber ohne Stacktrace und ohne den Hinweis, welcher Code den Fehler ausgelöst hat. Das DZM-Logsystem schreibt strukturiert nach `tDZMLogEntries` (Level, Kontext, Stacktrace, Request-ID) und zeigt die Einträge unter [Logs](/Resources-and-Health/Logs) an.

<div className="border border-[#DFE1E1] rounded-2xl overflow-hidden dark:border-transparent">
  <Frame>
    <img src="https://mintcdn.com/dzm/aLOXyq6W-9lvDRi0/images/error-tracking-uebersicht.jpg?fit=max&auto=format&n=aLOXyq6W-9lvDRi0&q=85&s=7e204c51404a4cbca5a67ee6a459cf28" alt="Übersicht Error-Tracking" width="2016" height="586" data-path="images/error-tracking-uebersicht.jpg" />
  </Frame>
</div>

<br />

Zwei Bausteine erweitern das gezielt:

* **Core-Log-Mirror** (in `dzm_resources`): spiegelt JTLs eigene Fehler angereichert um einen **rekonstruierten Aufrufer-Stack** ins DZM-Log. Das ist der einzige Weg, an die *gefangenen* DB-Fehler heranzukommen.
* **Plugin-freies Snippet** (ohne `dzm_resources`): fängt Fatals/OOM/weißen Screen und uncaught Exceptions mit vollem Stack in eine Log-Datei – als frühes Netz oder für Shops ganz ohne DZM-Plugins.

<Warning>
  Bound-Params und der strukturierte MySQL-Fehler bleiben weg (JTL wirft sie vor dem Logger weg). Geliefert werden SQL + MySQL-Message + Stack. Das plugin-freie Snippet sieht die gefangenen DB-Fehler gar nicht – dafür den Core-Log-Mirror aktivieren.
</Warning>

<br />

## Core-Log-Mirror aktivieren

Ein Einzeiler in der `config.JTL-Shop.ini.php`. Danach landen JTLs Core-/DB-Fehler zusätzlich als Plugin "jtl\_core" in den Logs – inklusive Stack.

<div className="border border-[#DFE1E1] rounded-2xl overflow-hidden dark:border-transparent">
  <Frame>
    <img src="https://mintcdn.com/dzm/aLOXyq6W-9lvDRi0/images/error-tracking-core-log-mirror-aktivieren.jpg?fit=max&auto=format&n=aLOXyq6W-9lvDRi0&q=85&s=ba35e04c47b563bfaed9deb8a043b38e" alt="Core-Log-Mirror aktivieren" width="2022" height="268" data-path="images/error-tracking-core-log-mirror-aktivieren.jpg" />
  </Frame>
</div>

```php theme={null}
define('DZM_LOGGER_MIRROR_CORE', true);
```

Ans Ende der `includes/config.JTL-Shop.ini.php`. Voraussetzung: JTL loggt den Fehler überhaupt (DB-Fehler-Logging hängt an `ES_DB_LOGGING`). Nur Error-Level wird gespiegelt.

<br />

## Logger-Konfiguration

Aktuelle Werte der `DZM_LOGGER_*`-Konstanten. Gesetzt in `config.JTL-Shop.ini.php`; ohne `defined()` gilt der Default.

<div className="border border-[#DFE1E1] rounded-2xl overflow-hidden dark:border-transparent">
  <Frame>
    <img src="https://mintcdn.com/dzm/aLOXyq6W-9lvDRi0/images/error-tracking-logger-konfiguration.jpg?fit=max&auto=format&n=aLOXyq6W-9lvDRi0&q=85&s=cfd7859372e1f5d332cb65f051bdb727" alt="Logger-Konfiguration" width="2016" height="1385" data-path="images/error-tracking-logger-konfiguration.jpg" />
  </Frame>
</div>

<ParamField path="DZM_LOGGER_ENABLED" type="boolean" default="true">
  Master-Switch. `false` → `log()` kehrt sofort ohne Aktion zurück.
</ParamField>

<ParamField path="DZM_LOGGER_DRIVER" type="select" default="db">
  Speicher-Ziel. `db` = nur DB (mit File-Fallback bei DB-Fehler), `file` = nur Datei, `both` = beides.

  Möglich: `db` | `file` | `both`
</ParamField>

<ParamField path="DZM_LOGGER_MIN_LEVEL" type="select" default="warning">
  PSR-3-Mindestlevel. Einträge unterhalb werden verworfen (Performance-Guard, ohne Context-Serialisierung).

  Möglich: `emergency` | `alert` | `critical` | `error` | `warning` | `notice` | `info` | `debug`
</ParamField>

<ParamField path="DZM_LOGGER_RETENTION_DAYS" type="number" default="14">
  Aufbewahrungsdauer in Tagen für DB-Einträge und Log-Files. Cleanup mit Wahrscheinlichkeit 1/500 pro Write.
</ParamField>

<ParamField path="DZM_LOGGER_FILE_MAX_MB" type="number" default="10">
  Rotation-Schwelle pro Log-Datei in MB. Bei Überschreitung wird -1, -2 … angehängt.
</ParamField>

<ParamField path="DZM_LOGGER_PATH" type="string" default="/var/www/niuplus.de/web/latest.niuplus.de/jtllogs/dzm/">
  Zielverzeichnis für Log-Files (Trailing-Slash). Wird beim ersten File-Write angelegt inkl. `.htaccess`.
</ParamField>

<ParamField path="DZM_LOGGER_CATCH_FATAL" type="boolean" default="false">
  CrashHandler aktivieren: uncaught Throwables + Fatal Errors via `set_exception_handler`/`shutdown_function` erfassen.
</ParamField>

<ParamField path="DZM_LOGGER_CATCH_ERRORS" type="boolean" default="false">
  Zusätzlich `set_error_handler` für Warnings/Notices/Deprecated registrieren (respektiert @-Suppression).
</ParamField>

<ParamField path="DZM_LOGGER_MIRROR_CORE" type="boolean" default="false">
  JTL-Core-Systemlog (`tjtllog`, z.B. "Error executing query …") zusätzlich als Plugin "jtl\_core" in `tDZMLogEntries` spiegeln – angereichert um einen rekonstruierten Aufrufer-Stack. Nur Error-Level.
</ParamField>

<br />

## Plugin-freies Error-Tracking (ohne dzm\_resources)

Für Shops ohne DZM-Plugins oder als frühes Netz. Fängt Fatals/OOM + uncaught Exceptions mit Stack, schreibt nach `jtllogs/dzm-selfcheck/`.

<div className="border border-[#DFE1E1] rounded-2xl overflow-hidden dark:border-transparent">
  <Frame>
    <img src="https://mintcdn.com/dzm/aLOXyq6W-9lvDRi0/images/error-tracking-plugin-freies-snippet.jpg?fit=max&auto=format&n=aLOXyq6W-9lvDRi0&q=85&s=c87cb614767dc2241c4cf8184cab6bd3" alt="Plugin-freies Snippet" width="2016" height="1048" data-path="images/error-tracking-plugin-freies-snippet.jpg" />
  </Frame>
</div>

Ans Ende der `includes/config.JTL-Shop.ini.php` einfügen.

<Info>
  Erfasst genau die Fehler, die JTL selbst verschluckt oder nur als Halb-Log speichert:

  1. Fatal Errors / Out-of-Memory / weißer Screen (Shutdown, zuverlässig)
  2. uncaught Exceptions mit vollem Stacktrace (chained)

  Schreibt nach `shop_root/jtllogs/dzm-selfcheck/` (JTLs `jtllogs`-Ordner ist per `.htaccess` vor Web-Zugriff geschützt; zusätzlich legt der Block ein eigenes Deny-`.htaccess` an).
</Info>

<Warning>
  **Grenzen (bewusst):** Gefangene DB-Fehler (JTLs "Error executing query …") tauchen hier NICHT auf – die fängt JTL intern ab, kein globaler Handler sieht sie. Dafür braucht es den [Core-Log-Mirror](#core-log-mirror-aktivieren) (`DZM_LOGGER_MIRROR_CORE`) in `dzm_resources`.
</Warning>

**Deaktivieren:** `define('DZM_ERRORLOG_ENABLED', false);` oder diesen Block löschen.

**Eigener Pfad:** `define('DZM_ERRORLOG_DIR', '/absoluter/pfad/');` (vor diesem Block setzen)

<div style={{height: '1px', backgroundColor: 'silver', margin: '24px 0'}} />
