# Architektur: 01_Modulerweiterungen — Erweiterungen zu 00_Globale_Richtlinien

Dieses Dokument beschreibt das Design und die Schnittstellen für die Module, die als
Erweiterung zu den bestehenden globalen Richtlinien in
[`00_Globale_Richtlinien/README.md`](00_Globale_Richtlinien/README.md:1) implementiert werden.

Ziel
- Die Planung bleibt strikt von Code getrennt.
- Bereitstellung zweier Logging-Module:
  - Internal Logging (SQLite)
  - External Logging (MySQL/PostgreSQL)

1. Designprinzipien
- Module folgen der Standardstruktur aus
  [`00_Globale_Richtlinien/Planung/Komponenten_Standardstruktur.md`](00_Globale_Richtlinien/Planung/Komponenten_Standardstruktur.md:1)
- Konfiguration erfolgt zentral über
  [`00_Globale_Richtlinien/Entworfener_Code/app/config/config.yaml`](00_Globale_Richtlinien/Entworfener_Code/app/config/config.yaml:1)
- Code nutzt definierte APIs; Logging-Module fungieren als optionale Handler

2. Dateisystem / vorgeschlagene Struktur
```
01_Modulerweiterungen/
├── Planung/
│   ├── Architektur.md
│   └── Security.md
└── Entworfener_Code/
    ├── app/
    │   ├── config/
    │   │   └── config.yaml  # Ergänzungen für logging_internal und logging_external
    │   └── src/
    │       ├── logging_internal.py
    │       ├── logging_external.py
    │       └── logger_integration.py
    └── tests/
        ├── test_logging_internal.py
        └── test_logging_external.py
```

3. Konfigurationsschema (Ergänzung)
Ergänze folgenden Abschnitt in
[`00_Globale_Richtlinien/Entworfener_Code/app/config/config.yaml`](00_Globale_Richtlinien/Entworfener_Code/app/config/config.yaml:1)

```yaml
logging_internal:
  enabled: true
  db_path: "data/internal_logs.sqlite"
  clean_database: false
  retention_days: 30
  max_entries: 100000
  vacuum_on_start: true
  batch_write: 100  # Anzahl pro Schreibbatch

logging_external:
  enabled: false
  type: "postgresql"  # mysql | postgresql
  host: "db.example.local"
  port: 5432
  user: "logger"
  password: null  # siehe Security.md für Secret-Handling
  database: "logs"
  sslmode: "prefer"
  pool_size: 5
  connect_timeout: 10
  write_buffer_size: 100
  fallback_to_internal_on_error: true
```

Empfohlene zusätzliche Einstellungen sind dokumentiert in Security.md

4. Internal Logging Modul (SQLite)
Ziel
- Leichtgewichtige, in-process persistente Log-Datenbank zur Aufnahme von internen Daten
  wie Hashwerte, Zustände, kleinere Events.

Schema (minimal)
- Tabelle logs:
  - id INTEGER PRIMARY KEY AUTOINCREMENT
  - ts TIMESTAMP NOT NULL
  - level TEXT
  - logger TEXT
  - message TEXT
  - meta JSON NULL

API / Funktionen (in [`01_Modulerweiterungen/Entworfener_Code/app/src/logging_internal.py`](01_Modulerweiterungen/Entworfener_Code/app/src/logging_internal.py:1))
- init(db_path: str, vacuum_on_start: bool, clean_database: bool) -> None
  - erzeugt DB, Tabellenschema; löscht DB wenn clean_database true
- write(entry: dict) -> None
  - akzeptiert dict mit keys ts, level, logger, message, meta
- query(where: dict, limit: int, offset: int) -> List[dict]
- cleanup(retention_days: int, max_entries: int) -> None
  - löscht alte Einträge nach Datum und begrenzt Gesamtanzahl
- get_engineered_handler() -> logging.Handler
  - liefert einen Python logging.Handler, der LogRecords in die SQLite DB schreibt

Verhalten des Flags clean_database
- Wenn `clean_database: true` in der Konfiguration gesetzt ist, löscht `init` die bestehende DB-Datei
  bevor Schema neu aufgebaut wird. Danach sollte die Konfig-Flag temporär im Runtime-Config
  zurückgesetzt werden, damit beim Neustart nicht erneut gelöscht wird.

Cleanup-Strategie
- Tägliche Prüfung beim Start (oder definierter Cron)
- Kombination aus retention_days und max_entries
- Optionaler VACUUM nach größeren Löschungen wenn vacuum_on_start true

5. External Logging Modul (MySQL / PostgreSQL)
Ziele
- Möglichkeit zur Speicherung großer Log-Volumina in externen relationalen DBs
- Transaktionssichere Inserts, Connection-Pooling, Retry-Mechanismen

Design-Entscheidungen
- Verwendung von SQLAlchemy als Abstraktions-Schicht
- Alembic optional für Migrationen
- Tabelle logs analog zum SQLite Schema plus index auf ts

Konfig-Optionen (siehe oben)

API / Funktionen (in [`01_Modulerweiterungen/Entworfener_Code/app/src/logging_external.py`](01_Modulerweiterungen/Entworfener_Code/app/src/logging_external.py:1))
- init(connection_url: str, pool_size: int, sslmode: str) -> None
- write_batch(entries: List[dict]) -> None
- ensure_schema() -> None
- health_check() -> bool
- get_handler() -> logging.Handler

Fallback-Verhalten
- Bei Verbindungsfehlern kann `logging_external` optional in den internen SQLite-Puffer schreiben
  wenn `fallback_to_internal_on_error` gesetzt ist.

6. Integration in bestehendes Logging
- Der zentrale Initializer
  [`00_Globale_Richtlinien/Entworfener_Code/app/src/logging_setup.py`](00_Globale_Richtlinien/Entworfener_Code/app/src/logging_setup.py:1)
  soll erweitert werden:
  - Bei aktivem `logging_internal.enabled` init des SQLite-Moduls und Anhang eines Handlers
  - Bei aktivem `logging_external.enabled` init des External-Moduls und Anhang eines Handlers
  - Handler priorisiert: external -> internal -> console/file

Schnittstellenbeispiel (Pseudo)
```python
from src.logging_internal import init as init_internal, get_handler as get_internal_handler
from src.logging_external import init as init_external, get_handler as get_external_handler

if CONFIG["logging_internal"]["enabled"]["wert"]:
    init_internal(db_path=..., clean_database=..., ...)
    root.addHandler(get_internal_handler())

if CONFIG["logging_external"]["enabled"]["wert"]:
    init_external(connection_url=..., pool_size=...)
    root.addHandler(get_external_handler())
```

7. Security und Secret-Handling
- DB-Credentials werden nicht in Klartext in Committer Configs liegen.
- Unterstützte Quelle: Environment-Variablen overrides, optional HashiCorp Vault oder lokale Keystore.
- Dokumentation in [`01_Modulerweiterungen/Planung/Security.md`](01_Modulerweiterungen/Planung/Security.md:1)

8. Tests
- Unit-Tests für Init, Write, Query, Cleanup
- Integrationstest mit temporärer SQLite-Datei
- Externer-Test nutzt Test-Container für Postgres/MySQL
- Tests liegen in
  [`01_Modulerweiterungen/Entworfener_Code/tests/`](01_Modulerweiterungen/Entworfener_Code/tests/:1)

9. Betriebs- und Admin-Endpoints
- Optional: Admin-API z. B. `/admin/logging/clean`  für on-demand clean_database
- Endpoint führt nur das aus, was in Config erlaubt ist

10. Migrationshinweis
- Schema-Änderungen werden via Alembic empfohlen, einfache Schemainitials per ensure_schema()

11. Weiteres / Empfehlungen
- Bei hohem Schreibvolumen evtl. asynchrone Batch-Writes verwenden
- Indizes auf ts und loggername
- Bei sensiblen Inhalten Meta verschlüsseln oder Hashwerte speichern anstelle von Raw-Text

12. Nächste Schritte (kurzer Aktionsplan)
1. Anlegen der Verzeichnisse und Datei `Architektur.md` (dieses Dokument)
2. Implementierung `logging_internal.py` mit Tests
3. Erweiterung von `logging_setup.py` zur optionalen Initialisierung
4. Implementierung `logging_external.py` mit Fallback-Mechanismus
5. Dokumentation Security.md und Beispiele in config.yaml

Ende