Files
ldap-identidy/docs/application-error-logging.md
Bastian Wagner 201c4e03f8 logging
2026-07-17 10:50:10 +02:00

3.8 KiB

Application Error Logging

Das Backend speichert technische Fehler zentral in application_error_logs. Die Tabelle ist fuer Fehleranalyse gedacht, nicht fuer fachliches Audit-Logging; bestehende Audit-Events bleiben unveraendert.

Felder

  • level: technischer Schweregrad, aktuell error oder warning.
  • category: grobe Fehlergruppe, z. B. EMAIL, EXTERNAL_API, DATABASE, BACKGROUND_JOB, FILE, UNHANDLED.
  • code: stabiler maschinenlesbarer Fehlercode, z. B. PASSWORD_RESET_EMAIL_SEND_FAILED.
  • message, stackTrace, errorType: technische Fehlerdaten aus Error, HttpException oder unbekannten Fehlerwerten.
  • backendModule, service, operation: fachliche Herkunft im Backend.
  • httpMethod, apiPath, httpStatusCode: HTTP-Kontext, sofern vorhanden.
  • correlationId: Request-ID aus X-Correlation-ID oder eine pro Request erzeugte UUID.
  • userId, tenantId: Benutzer- und Mandantenkontext, sofern vorhanden.
  • environment, host: Laufzeitumgebung und Instanz.
  • context: bereinigte strukturierte Zusatzdaten.
  • handled: true, wenn der Fehler gezielt behandelt und protokolliert wurde; false fuer unerwartete globale Exceptions.

Erfassung

Der globale NestJS-Exception-Filter protokolliert unerwartete Exceptions und technische HTTP-Fehler ab Status 500. Erwartete fachliche Fehler wie Validierung, fehlende Berechtigungen, bewusstes 404 oder Konflikte werden nicht automatisch als Systemfehler gespeichert.

Explizit protokolliert werden derzeit:

  • Passwort-Reset-Mailfehler mit PASSWORD_RESET_EMAIL_SEND_FAILED.
  • Registrierungs-Bestaetigungs-Mailfehler mit REGISTRATION_VERIFICATION_EMAIL_SEND_FAILED.
  • Benachrichtigung an User-Manager mit REGISTRATION_APPROVAL_NOTIFICATION_FAILED.
  • LLDAP/GraphQL- und LDAP-Integrationsfehler mit EXTERNAL_API_REQUEST_FAILED.

Asynchrone Prozesse ohne HTTP-Request sollen den ApplicationErrorLoggerService direkt verwenden und handled: true setzen.

Datenschutz

Der Logger entfernt sensible Schluessel rekursiv und case-insensitive, darunter password, currentPassword, newPassword, token, accessToken, refreshToken, idToken, authorization, cookie, secret, apiKey, clientSecret, resetToken und sessionId.

Kontextdaten werden in Tiefe, Array-Laenge, Schluesselanzahl und String-Laenge begrenzt. Zirkulaere Objekte werden sicher ersetzt. E-Mail-Adressen in freien Texten werden maskiert, z. B. m***@example.com.

Fehlersuche

  1. Korrelations-ID aus Response-Header X-Correlation-ID oder Backend-Log notieren.
  2. In application_error_logs nach correlationId, code, category, userId oder Zeitraum suchen.
  3. handled pruefen: false weist auf einen unerwarteten globalen Fehler hin, true auf einen gezielt behandelten technischen Fehler.
  4. context fuer Provider-Status, maskierte Empfaenger oder Integrationsdetails verwenden.

Beispiel

try {
  await this.mail.sendPasswordResetMail(user.email, token);
} catch (error) {
  await this.applicationErrorLogger.log({
    error,
    category: ApplicationErrorCategory.EMAIL,
    code: ApplicationErrorCode.PASSWORD_RESET_EMAIL_SEND_FAILED,
    module: 'PasswordModule',
    service: PasswordService.name,
    operation: 'sendPasswordResetEmail',
    requestContext: {
      correlationId,
      userId: user.id,
    },
    context: {
      maskedRecipient: maskEmail(user.email),
      mailProvider,
    },
    handled: true,
  });

  throw error;
}

Aufbewahrung

Es gibt im Projekt derzeit keinen Scheduler oder Queue-Mechanismus. Empfohlen ist ein spaeterer, begrenzter Cleanup-Job, der Fehler aelter als 180 Tage in Batches loescht und kritische Kategorien bei Bedarf laenger aufbewahrt. Die Tabelle besitzt Indizes auf createdAt, code, category, correlationId, userId, tenantId und httpStatusCode.