Zum Inhalt springen

Observability

Kurzantwort: Metriken, Health-Indikatoren und Tracing sind optional: Die Module sprechen gegen eine Abstraktion und aktivieren Micrometer nur, wenn die Anwendung eine MeterRegistry mitbringt. Ohne sie laufen No-Op-Implementierungen ohne Kosten. Sensible Werte – rohe Mandantenkennungen, Pfade, Tokens – tauchen weder in Logs noch in Metrik-Tags auf.


flowchart TB
    A["Anwendung startet"] --> B{"MeterRegistry-Bean vorhanden?<br/>(Micrometer/Actuator eingebunden)"}
    B -->|nein| N["NoOp-Implementierung<br/>keine Metriken, keine Kosten"]
    B -->|ja| M["Micrometer-Implementierung"]
    M --> C{"Actuator im Classpath?"}
    C -->|ja| H["zusätzlich Health-Indikator"]

micrometer-core und spring-boot-actuator sind in den Modulen als optional deklariert – nicht transitiv. Die Anwendung entscheidet.

Präfix cdms.persistence:

MetrikTypTagsBedeutung
cdms.persistence.routingCountertarget=system|tenantRouting-Entscheidungen
cdms.persistence.routing.failuresCounterreason=<CDMS_*-Code>fehlgeschlagene Auflösungen
cdms.persistence.tenant_database.createdCounterprovisionierte Mandantendatenbanken
cdms.persistence.tenant_catalog.cacheCounterresult=hit|missWirksamkeit des Katalog-Caches
cdms.persistence.factory_cache.sizeGaugeCache-Belegung
cdms.persistence.factory_cache.evictionsCountergeräumte Factories
cdms.persistence.entity_manager_factory.creationTimerDauer der Factory-Erzeugung
cdms.persistence.tenant_catalog.loadTimerDauer des Katalogzugriffs

Der Routing-Counter zählt Auflösungen, nicht Requests – ein Request kann mehrere auslösen.

MetrikTypTagsBedeutung
cdms.files.operationCounteroperation, resultStorage-Operationen nach Ausgang
cdms.files.operation.durationTimeroperationDauer
cdms.files.bytesCounterdirectionbewegte Bytes

operation ist save, read, delete, listVersions, readVersion oder rollback.

Weder Mandant noch Modell sind Tags. Der Mandant ist unbegrenzt und identifizierend – ein Metrik-Backend behält jede jemals gesehene Zeitreihe, ein Mandanten-Tag machte aus einer Metrik eine wachsende Kundenliste. Speichervolumen pro Mandant ist eine Reporting-Frage und wird aus den Metadaten beantwortet. Ein Test läuft über alle registrierten Meter und schlägt bei jedem fremden Tag fehl.

Kein modulspezifischer Schalter – der Standardweg von Spring Boot genügt:

# alle Metriken des Persistenzmoduls aus
management.metrics.enable.cdms.persistence=false
# nur den Routing-Counter aus
management.metrics.enable.cdms.persistence.routing=false
Indikatorprüft
PersistenceHealthIndicatorErreichbarkeit der Persistenzziele
FileStorageHealthIndicatorErreichbarkeit und Beschreibbarkeit des basePath
CacheHealthIndicatorCache-Zustand

Beim Start prüft FileStorageStartupCheck das Storage-Wurzelverzeichnis – eine fehlende oder nicht beschreibbare Ablage fällt beim Start auf, nicht beim ersten Upload.

Endpunkte: :8081/actuator/health, …/health/liveness.

WasVerhalten
Routingüber cdms.database.log-routing (Standard false); protokolliert Zieltyp und gehashte Mandantenkennung, nie die rohe
Fehlerimmer auf warn, mit CDMS_*-Code
Provisionierungauf info
Storageparametrisiert (model={} fileId={}), Ausnahme als Ursache angehängt

Nicht geloggt werden: Passwörter, Tokens, vollständige JDBC-URLs, Request-Payloads, rohe Mandantenkennungen, absolute Pfade in der Nachricht, Dateinamen fremder Datensätze, Dateiinhalte.

Ein Detail mit Absicht: Die Meldung einer IOException enthält den absoluten Pfad. Sie landet deshalb im Stacktrace (den ein Operator beim Untersuchen liest) und nicht im Nachrichtenfeld (das indiziert, aggregiert und aufbewahrt wird).

Umgesetzt über die Micrometer Observation API: Die zeitgemessenen Operationen laufen durch eine Observation – ist ein Tracer vorhanden, liefert dieselbe Instrumentierung zusätzlich Spans.

Die generierten APIs sind mit @Observed annotiert (z. B. @Observed(name = "CustomerApi.create.json")), sodass Endpunkte einzeln messbar sind.

  • eine durchgehende Korrelations-/Request-ID über alle Schichten (der RequestContext trägt eine requestId, die Storage-Logs nutzen sie noch nicht)
  • Zähler für den Ausgang der Transaktionsklammer (Commits/Rollbacks)