Metadata-Version: 2.4
Name: circuit-logging
Version: 0.2.1
Summary: WLKNS LABS structured logging module with 4 separated worlds, privacy redaction, and tamper-evident audit chains.
License: MIT
Keywords: audit,gdpr,json,logging,privacy,security,wlkns
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Logging
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Provides-Extra: otel
Requires-Dist: opentelemetry-api; extra == 'otel'
Requires-Dist: opentelemetry-sdk; extra == 'otel'
Description-Content-Type: text/markdown

# WLKNS LABS circuit-logging

Ein wiederverwendbares Python-Logging-Modul mit vier getrennten Welten, strukturiertem JSON-Output und automatischer Redaktion sensibler Daten.

[![PyPI version](https://img.shields.io/pypi/v/circuit-logging.svg)](https://pypi.org/project/circuit-logging/)

## Features

- **4 separate Logger-Welten**: `app`, `audit`, `security`, `analytics`
- **Strukturierte JSON-Logs** — kein parsen von Textwürsten nötig
- **Automatische Privacy-Redaktion** — `password`, `token`, `api_key`, etc. werden automatisch auf `[REDACTED]` gesetzt
- **Append-Only Integritätskette** — manipulationsgeschützte Audit-/Security-Logs mit verketteten SHA-256-Hashes
- **IP-Anonymisierung** — täglich wechselnder Salt für GDPR-konforme Hashes (Cross-Day-Tracking unmöglich)
- **Datei-Rotation** für Application- und Analytics-Logs (täglich, mit Aufbewahrung)
- **OpenTelemetry-Integration** — optional Logs an OTLP-Backends exportieren
- **Service-Metadaten** — `service_name`, `service_version`, `environment` in jedem Event
- **Stdlib-kompatibel** — nutzt `logging` mit `extra={...}` für zusätzliche Felder

## Schnellstart

```python
from circuit_logging import LogConfig, WLKNSLogger

cfg = LogConfig(
    service_name="billing-api",
    service_version="2.1.0",
    environment="production",
)

log = WLKNSLogger(cfg)

# 1. Application Logs — für Entwickler und Betrieb
log.app.info("Payment processed", extra={"request_id": "abc-123"})

# 2. Audit Logs — der Tresorbereich
log.audit.info("User role changed", extra={"user_id_pseudonymized": "u-42"})

# 3. Security Logs — verdächtige Muster
log.security.warning("Suspicious login pattern", extra={"ip_hash": "10.0.0.x"})

# 4. Analytics — Produktnutzung
log.analytics.info("Feature X used", extra={"event_type": "feature_usage"})
```

Ein ausführliches Beispiel mit allen Features findest du unter:
`examples/demo.py`.

## JSON Output

Jede Log-Zeile ist ein JSON-Objekt:

```json
{
  "timestamp": "2025-05-31 12:34:56,789",
  "service_name": "billing-api",
  "service_version": "2.1.0",
  "environment": "production",
  "severity": "INFO",
  "logger": "wlkns.app",
  "message": "Payment processed",
  "request_id": "abc-123"
}
```

## Privacy / Datenschutz

Sensible Felder werden **automatisch** rekursiv ausgefiltert:

```python
log.app.info("Login attempt", extra={
    "username": "alice",
    "password": "secret123",      # → [REDACTED]
    "token": "abc",                # → [REDACTED]
    "nested": {"api_key": "xyz"},  # → [REDACTED]
})
```

Betroffene Keys (partial match, case-insensitive):
`password`, `token`, `api_key`, `apikey`, `api-key`, `secret`, `authorization`, `auth`, `credit_card`, `ssn`, `private_key`, `access_token`, `refresh_token`, `passwd`, `pwd`.

### IP-Anonymisierung (täglich wechselnder Salt)

Besser als Pseudonymisierung: Derselbe IP liefert an unterschiedlichen Tagen **unterschiedliche Hashes**. Cross-Day-Tracking wird unmöglich, Same-Day-Analyse (z. B. Brute-Force-Erkennung) bleibt möglich.

```python
from circuit_logging import DailySalt, anonymize_ip
from datetime import date

ds = DailySalt(master_secret=b"ein-geheimer-schlüssel")
salt = ds.salt_for(date.today())

anonymized = anonymize_ip("192.168.1.1", salt)
# z. B. "a3f7c2e9d8b1a4f6"
```

## Die 4 Welten

| Welt | Zweck | Beispiele |
|------|-------|-----------|
| `log.app` | Betrieb, Debugging, API-Calls | Fehler, Warnungen, Performance |
| `log.audit` | Manipulationsgeschützte Audit-Trail | Login, Rollenänderung, Löschung |
| `log.security` | Sicherheitsereignisse | Brute-force, unautorisierter Zugriff |
| `log.analytics` | Produkt-Telemetry | Feature-Nutzung, Conversion, Churn |

Jede Welt ist ein eigener `logging.Logger` mit eigenem Namen (`wlkns.app`, `wlkns.audit`, ...). So lassen sie sich getrennt filtern, rotieren oder an verschiedene Backends schicken.

### Append-Only Integritätskette

Audit- und Security-Logs können in **manipulationsgeschützte** Dateien geschrieben werden. Jede Zeile enthält einen Hash, der sich auf die vorherige Zeile stützt:

```python
log = WLKNSLogger(
    cfg,
    audit_file="/var/log/wlkns/audit.jsonl",
    security_file="/var/log/wlkns/security.jsonl",
)
```

Beispiel-Ausgabe (zweite Zeile verweist auf Hash der ersten):

```json
{"message": "Login success", "_integrity_prev": "", "_integrity_hash": "abc123..."}
{"message": "Role changed", "_integrity_prev": "abc123...", "_integrity_hash": "def456..."}
```

**Verifikation:** Ein einfaches Skript liest die Datei Zeile für Zeile und prüft, ob jeder `_integrity_prev` mit dem `_integrity_hash` der Vorgängerzeile übereinstimmt. Abweichung = Manipulation.

### Integrität prüfen (CLI)

```bash
python3 scripts/verify_audit.py /var/log/wlkns/audit.jsonl
# VERDICT: 42 line(s) — chain is INTACT
```

Oder programmatisch:

```python
from circuit_logging import check_integrity

issues, total = check_integrity("/var/log/wlkns/audit.jsonl")
if issues:
    print(f"Chain broken at lines: {[i.line_number for i in issues]}")
else:
    print(f"All {total} lines intact.")
```

### Log-Rotation (App & Analytics)

Audit und Security dürfen **nicht** rotiert werden — die Integritätskette würde brechen. Für `app` und `analytics` steht ein täglicher Rotations-Handler bereit:

```python
from circuit_logging import RotatingJSONHandler, LogConfig

cfg = LogConfig("billing-api", "2.1.0", "production")
handler = RotatingJSONHandler(
    "/var/log/wlkns/app.jsonl",
    config=cfg,
    when="midnight",
    backup_count=30,
)
log.app.addHandler(handler)
```

## OpenTelemetry (optional)

Für SaaS-Umgebungen kannst du Logs zusätzlich an ein OTLP-Backend schicken (Grafana, Datadog, etc.):

```bash
python3 -m pip install "circuit-logging[otel]"
```

```python
from circuit_logging import LogConfig, WLKNSLogger
from circuit_logging.otel import OpenTelemetryHandler
from opentelemetry.sdk._logs import LoggerProvider

provider = LoggerProvider()
handler = OpenTelemetryHandler(provider, config=cfg)
log.app.addHandler(handler)
```

## Installation

```bash
# Von PyPI (empfohlen)
python3 -m pip install circuit-logging

# Mit OpenTelemetry-Unterstützung
python3 -m pip install "circuit-logging[otel]"

# Editable install (für Entwicklung)
python3 -m pip install -e ".[dev]"
```

## Entwicklung

```bash
# Tests
python3 -m pytest tests/

# Lint
ruff check src/ tests/

# Format
ruff format src/ tests/
```

## Architektur

```
src/circuit_logging/
├── __init__.py   → LogConfig, WLKNSLogger, AuditFileHandler, DailySalt, check_integrity
├── config.py     → LogConfig (service_name, version, environment)
├── logger.py     → WLKNSLogger mit 4 Welten
├── formatter.py  → JSONFormatter (redact + JSON output)
├── privacy.py    → redact() — rekursive Key-Filterung
├── integrity.py  → AuditFileHandler — verkettete SHA-256-Hashes
├── anonymize.py  → DailySalt + anonymize_ip() — GDPR-konforme IPs
├── rotation.py   → RotatingJSONHandler — tägliche Rotation für app/analytics
├── verify.py     → check_integrity() — programmatische Kettenprüfung
└── otel.py       → OpenTelemetryHandler — OTLP-Export (optional)

scripts/
└── verify_audit.py → CLI für Integritätsprüfung
```

## Lizenz

MIT
