Until now the only record of what happened was `user_activity_logs`, which stores non-GET 2xx operations with no bodies. When something failed you could see that a counter went up, never what was sent or what came back. This adds one queryable timeline covering both directions: - inbound: every API call, including GETs and including 4xx/5xx, with the user, client IP, status, duration and — redacted, size-capped — the request and response bodies. - outbound: every HTTP call the backend makes, tagged with who it went to (ACME/Let's Encrypt, Cloudflare, GoDaddy, HAProxy stats, agents, the ACME diagnostics probe). Outbound rows inherit the inbound request's id, so one operator action and the CA/DNS calls it triggered read as a single trace: opening a failed "Request Certificate" shows the exact POST /acme/new-order and the CA's 429 underneath. Implementation notes: - Capture is a pure-ASGI middleware that TEES the request and response streams rather than draining them. `await request.body()` inside a BaseHTTPMiddleware would consume the receive channel and break the raw-body agent heartbeat handler. Registered last so it is outermost: it then sees the final client-visible response and seeds correlation_id_context before the error handler reads it. - Rows are written by a batching background writer with a bounded queue, so the request path never awaits the database and a saturated logger drops rows visibly (surfaced on the page) instead of blocking. Redaction runs on the writer, off the request coroutine. - Secrets never land: headers are an allowlist with Authorization/Cookie kept only as a presence marker; body keys and value shapes are redacted (passwords, tokens, api_token, API keys, private-key PEMs, JWTs); the ACME JWS request body is never stored, because a stored protected+signature pair is a replayable credential — a summary is logged instead; DNS-provider errors record only the exception type; the ACME HTTP-01 challenge endpoint is excluded so key_authorization is never captured. - Retention is operator-configurable in Settings -> Request Log: separate day counts for successful and failed rows (7 / 30) plus a hard row cap (500k), whichever is reached first. Pruned in batches under a Postgres advisory lock, with the day counts bound as parameters, never interpolated. - New permissions requestlog.read / requestlog.manage. super_admin and security_admin get both, operator gets read, viewer gets neither. Schema: one new table (request_logs) plus its settings seed, SCHEMA_VERSION 10 -> 11, auto-migrated. No existing table altered, no agent or rendered-config change. Kill switches: REQUEST_LOG_ENABLED=false (middleware never registered) or the `enabled` toggle in Settings. Tests: 245 new (7 backend files + 1 frontend), full suite 1655 backend + 17 frontend passing.
7.6 KiB
Configuration Guide - HAProxy OpenManager
📋 Yapılandırma Dosyaları
Dosya Yapısı
haproxy-openmanager/
├── .env.template # ✅ Template (GIT'e commit edilir)
├── .env # ❌ Gerçek config (GIT'e commit EDİLMEZ)
├── .gitignore # .env dosyalarını korur
└── CONFIG.md # Bu dosya
🎯 Quick Start
1. Template'den Config Oluşturma
# Template'i kopyala
cp .env.template .env
# Gerçek değerleri düzenle
nano .env
2. Örnek Yapılandırmalar
Development (Local)
# .env dosyası
PUBLIC_URL=http://localhost:8000
MANAGEMENT_BASE_URL=http://localhost:8000
DEBUG=True
LOG_LEVEL=DEBUG
Staging
# .env dosyası veya K8s ConfigMap
PUBLIC_URL=https://haproxy-staging.example.com
MANAGEMENT_BASE_URL=https://haproxy-staging.example.com
DEBUG=False
LOG_LEVEL=INFO
Production (OpenShift)
# K8s ConfigMap: k8s/manifests/07-configmaps.yaml
data:
PUBLIC_URL: 'https://haproxy-manager.example.com'
MANAGEMENT_BASE_URL: 'https://haproxy-manager.example.com'
DEBUG: 'False'
LOG_LEVEL: 'INFO'
🔐 Güvenlik
Hassas Bilgiler
.env dosyası hassas bilgiler içerir:
- ❌ Database şifreleri
- ❌ Secret key'ler
- ❌ API token'ları
Bu yüzden:
- ✅
.env→.gitignore'da (commit edilmez) - ✅
.env.template→ Git'e commit edilir (örnek değerler) - ✅ Production'da: Kubernetes Secrets kullan
.gitignore Kontrolü
# .env dosyalarının ignore edildiğini kontrol et
grep "^\.env" .gitignore
# Çıktı olmalı:
# .env
# .env.local
# .env.development.local
# .env.test.local
# .env.production.local
📚 Environment Variable Detayları
PUBLIC_URL
Ne İşe Yarar: Agent kurulum script'lerinde kullanılır
Örnekler:
# Development
PUBLIC_URL=http://localhost:8000
# Production
PUBLIC_URL=https://haproxy-manager.example.com
# OpenShift
PUBLIC_URL=https://haproxy-manager.example.com
Nasıl Kullanılır:
- Agent Management sayfasından "Generate Install Script"
- Script içinde
{{MANAGEMENT_URL}}bu değerle değiştirilir - Agent bu URL'ye bağlanarak backend'i dinler
REACT_APP_API_URL
Ne İşe Yarar: Frontend'in backend'e bağlanacağı URL
Özel Durum:
# Boş bırakılırsa → Auto-detect (production için önerilen)
REACT_APP_API_URL=
# Development için explicit
REACT_APP_API_URL=http://localhost:8000
Auto-detect Mantığı:
// frontend/src/utils/api.js
if (process.env.REACT_APP_API_URL) {
return process.env.REACT_APP_API_URL;
}
// Production'da same-origin kullan
if (window.location) {
return `${window.location.protocol}//${window.location.hostname}`;
}
REQUEST_LOG_ENABLED (v1.11.0)
Ne İşe Yarar: Request/Response Log özelliğinin sert (hard) kill-switch'i. false yapıldığında
loglama middleware'i ASGI zincirine hiç eklenmez, yazıcı ve retention görevleri başlatılmaz —
yani sıfır ek yük, ayar okuması bile yapılmaz. Değişiklik için restart gerekir.
Örnekler:
# Varsayılan: açık
REQUEST_LOG_ENABLED=true
# Tamamen kapat (ör. çok yüksek trafikli kurulum, veya regülasyon gereği)
REQUEST_LOG_ENABLED=false
Nasıl Kullanılır:
- Restart gerektirmeden kapatmak isterseniz bunun yerine Settings → Request Log → Enable request log anahtarını kullanın; o anında etkili olur.
- Retention süreleri, gövde (body) yakalama, örnekleme oranı ve hariç tutulan path'ler bu env
değişkeniyle değil, veritabanındaki
requestlog.*ayarlarıyla yönetilir — arayüzden düzenlenir. - Disk büyümesi asıl operasyonel konudur: sırasıyla
sample_rate'i düşürün,capture_get'i kapatın,capture_bodies'i kapatın, sonrasuccess_retention_days'i kısaltın.
REQUEST_LOG_QUEUE_MAX / REQUEST_LOG_BATCH_SIZE / REQUEST_LOG_FLUSH_MS (v1.11.0)
Ne İşe Yarar: Log satırlarını yazan arka plan görevinin ayarları. Satırlar sınırlı bir kuyruğa konur ve toplu (batch) INSERT ile yazılır; böylece istek yolu asla veritabanını beklemez.
Örnekler:
# Worker başına kuyruk derinliği. Dolduğunda satırlar DÜŞÜRÜLÜR (sayılır ve
# Request Log sayfasında gösterilir), istek bloklanmaz.
REQUEST_LOG_QUEUE_MAX=2000
# Tek INSERT'te kaç satır yazılacağı (havuzdan istek başına değil, batch başına
# bir bağlantı alınır)
REQUEST_LOG_BATCH_SIZE=100
# Yarım dolu bir batch'in en fazla ne kadar bekletileceği (ms)
REQUEST_LOG_FLUSH_MS=500
Nasıl Kullanılır:
- Request Log sayfasında "rows dropped" uyarısı görüyorsanız önce
REQUEST_LOG_QUEUE_MAX'ı artırın; sorun devam edersesample_rate'i düşürün. - Bu üç değer worker başınadır —
UVICORN_WORKERSarttıkça toplam bellek de o oranda artar.
🚀 Deployment Senaryoları
Docker Compose
# 1. .env dosyası oluştur
cp .env.template .env
# 2. Değerleri düzenle
nano .env
# 3. Başlat
docker-compose up -d
# 4. Kontrol et
docker-compose logs backend | grep "PUBLIC_URL"
Kubernetes/OpenShift
# 1. ConfigMap'i düzenle
vim k8s/manifests/07-configmaps.yaml
# 2. Apply
kubectl apply -f k8s/manifests/
# 3. Kontrol et
kubectl get configmap backend-config -n haproxy-manager -o yaml
Manuel (Development)
# 1. Backend
cd backend
cp ../.env.template .env
export $(cat .env | xargs)
uvicorn main:app --reload
# 2. Frontend (başka terminal)
cd frontend
export REACT_APP_API_URL=http://localhost:8000
npm start
🔧 Troubleshooting
Agent Script'inde Yanlış URL
Sorun: Agent script hala eski URL içeriyor
Çözüm:
# 1. Backend'deki değeri kontrol et
docker exec haproxy-openmanager-backend env | grep PUBLIC_URL
# 2. Container'ı yeniden başlat
docker-compose restart backend
# 3. Yeni script oluştur
# UI'dan tekrar "Generate Install Script"
Frontend Backend'e Bağlanamıyor
Sorun: CORS hatası veya connection refused
Çözüm:
# 1. Frontend config'i kontrol et
docker exec haproxy-openmanager-frontend env | grep REACT_APP_API_URL
# 2. Browser console'da kontrol et
# [API Config] Base URL: http://localhost:8000
# 3. Network sekmesinde request URL'i kontrol et
📖 En İyi Pratikler
✅ YAPILMASI GEREKENLER
-
Her ortam için ayrı değerler
Dev: PUBLIC_URL=http://localhost:8000 Staging: PUBLIC_URL=https://staging.example.com Prod: PUBLIC_URL=https://prod.example.com -
Template'i güncelle
- Yeni variable eklendiğinde
.env.template'e ekle - Dokümantasyon ile birlikte
- Yeni variable eklendiğinde
-
Secrets kullan (Production)
# K8s Secret apiVersion: v1 kind: Secret metadata: name: backend-secret data: SECRET_KEY: <base64-encoded>
❌ YAPILMAMASI GEREKENLER
-
.envdosyasını commit etmeyin# Yanlış! git add .env # Doğru! git add .env.template -
Production secret'larını template'e koymayın
# .env.template içinde YANLIŞLAR: SECRET_KEY=actual-production-secret-12345 ❌ DATABASE_URL=postgresql://admin:realpass@prod-db ❌ # Doğru: SECRET_KEY=your-secret-key-change-this-in-production ✅ DATABASE_URL=postgresql://user:pass@host:5432/db ✅ -
Hardcoded URL kullanmayın
# Yanlış! MANAGEMENT_URL = "https://my-server.com" ❌ # Doğru! MANAGEMENT_URL = os.getenv("PUBLIC_URL") ✅
🆘 Yardım
Sorularınız için:
- 📘 Bu dosya:
CONFIG.md - 📗 Ana dokümantasyon:
README.md - 📙 Template:
.env.template