anchorage_layer_simple/fixKnowledge/api-anchorage-logs-volumineux.md
ncantu 0960e43a45 Optimisation mémoire api-anchorage avec base de données SQLite
**Motivations:**
- Réduction drastique de la consommation mémoire lors des ancrages
- Élimination du chargement de 173k+ UTXOs à chaque requête
- Stabilisation de la mémoire système sous charge élevée (50+ ancrages/minute)

**Root causes:**
- api-anchorage chargeait tous les UTXOs (173k+) via listunspent RPC à chaque ancrage
- Filtrage et tri de 173k+ objets en mémoire pour sélectionner un seul UTXO
- Croissance mémoire de ~16 MB toutes les 12 secondes avec 50 ancrages/minute
- Saturation mémoire système en quelques minutes

**Correctifs:**
- Création du module database.js pour gérer la base de données SQLite partagée
- Remplacement de listunspent RPC par requête SQL directe avec LIMIT 1
- Sélection directe d'un UTXO depuis la DB au lieu de charger/filtrer 173k+ objets
- Marquage des UTXOs comme dépensés dans la DB après utilisation
- Fermeture propre de la base de données lors de l'arrêt

**Evolutions:**
- Utilisation de la base de données SQLite partagée avec signet-dashboard
- Réduction mémoire de 99.999% (173k+ objets → 1 objet par requête)
- Amélioration des performances (requête SQL indexée vs filtrage en mémoire)
- Optimisation mémoire de signet-dashboard (chargement UTXOs seulement si nécessaire)
- Monitoring de lockedUtxos dans api-anchorage pour détecter les fuites
- Nettoyage des intervalles frontend pour éviter les fuites mémoire

**Pages affectées:**
- api-anchorage/src/database.js (nouveau)
- api-anchorage/src/bitcoin-rpc.js
- api-anchorage/src/server.js
- api-anchorage/package.json
- signet-dashboard/src/bitcoin-rpc.js
- signet-dashboard/public/app.js
- features/optimisation-memoire-applications.md (nouveau)
- features/api-anchorage-optimisation-base-donnees.md (nouveau)
2026-01-27 21:12:22 +01:00

287 lines
8.2 KiB
Markdown

# Fix: Logs volumineux api-anchorage
**Date:** 2026-01-27
**Auteur:** Équipe 4NK
## Problème
Les logs de `api-anchorage` sont très volumineux et peuvent saturer l'espace disque du journal systemd.
### Symptômes
- **Volume de logs:** 48 MB en 7 jours pour `anchorage-api` seul
- **Fréquence:** ~94 308 lignes par jour (~3 900 lignes/heure)
- **Taux actuel:** ~2 815 lignes INFO par heure (~47 lignes/minute)
- **Taille totale journald:** 191.1 MB (tous services confondus)
### Impact
- Risque de saturation de l'espace disque dédié aux logs
- Performance dégradée lors de la consultation des logs
- Coût de stockage inutile
- Difficulté à identifier les logs importants dans la masse
## Root cause
### Sources de logs identifiées
1. **Logging de chaque requête HTTP** (ligne 44-47 dans `server.js`)
- Chaque requête GET/POST génère un log INFO
- Inclut les health checks fréquents
- ~447 requêtes HTTP/heure
2. **Logs détaillés des transactions d'ancrage**
- `Anchor request received` - 1 log par transaction
- `Anchor transaction with provisioning` - 1 log avec détails
- `Fetched UTXOs` - 1 log avec liste des UTXOs (peut être volumineux)
- `Available UTXOs` - 1 log avec statistiques
- `Selected UTXO` - 1 log
- `Adding change output` - 1 log
- `OP_RETURN metadata created` - 1 log
- `Anchor transaction sent to mempool` - 1 log avec détails
- **Total:** ~8-10 logs par transaction d'ancrage
3. **Logs de vérification d'ancrage**
- Potentiellement très volumineux si recherche dans plusieurs blocs
### Analyse quantitative
**Sur 1 heure:**
- 2 815 lignes INFO
- 447 requêtes HTTP (GET/POST)
- ~3 WARN
- Ratio: ~6.3 lignes de log par requête HTTP
**Sur 1 jour:**
- ~94 308 lignes
- ~10 728 requêtes HTTP
- ~72 WARN
**Sur 7 jours:**
- ~244 554 lignes
- ~48 MB de données
- ~504 WARN
## Correctifs
### 1. Réduire le logging des requêtes HTTP (priorité haute)
**Problème:** Chaque requête HTTP génère un log, y compris les health checks fréquents.
**Solution:** Ne logger que les requêtes importantes, exclure les health checks et les requêtes GET simples.
**Modification recommandée dans `server.js`:**
```javascript
// Middleware de logging
app.use((req, res, next) => {
// Ne pas logger les health checks et requêtes GET simples
if (req.path === '/health' || req.path === '/' || req.path === '/favicon.ico' || req.path === '/robots.txt') {
return next();
}
// Logger uniquement les requêtes POST (ancrage, vérification)
if (req.method === 'POST') {
logger.info(`${req.method} ${req.path}`, {
ip: req.ip,
userAgent: req.get('user-agent'),
});
}
next();
});
```
**Impact attendu:** Réduction de ~80% des logs HTTP (les health checks représentent une grande partie)
### 2. Réduire le niveau de détail des logs de transaction (priorité moyenne)
**Problème:** Chaque transaction génère 8-10 logs détaillés.
**Solution:** Regrouper les logs ou réduire le niveau de détail pour les opérations normales.
**Modifications recommandées:**
- **Option A:** Logger uniquement le début et la fin de la transaction
- **Option B:** Utiliser le niveau DEBUG pour les détails intermédiaires
- **Option C:** Regrouper plusieurs logs en un seul log structuré
**Exemple (Option A):**
```javascript
// Au début
logger.info('Anchor transaction started', { hash: hash.substring(0, 16) + '...' });
// À la fin (regrouper toutes les infos)
logger.info('Anchor transaction completed', {
txid,
hash: hash.substring(0, 16) + '...',
utxosCount: availableUtxos.length,
fee: actualFee,
// ... autres infos importantes
});
```
**Impact attendu:** Réduction de ~70% des logs par transaction (de 8-10 logs à 2-3 logs)
### 3. Configurer la rotation des logs journald (priorité haute)
**Solution:** Limiter la taille et la durée de rétention des logs dans journald.
**Fichier:** `/etc/systemd/journald.conf`
**Modifications recommandées:**
```ini
[Journal]
# Limiter la taille maximale des journaux
SystemMaxUse=500M
SystemKeepFree=1G
SystemMaxFileSize=100M
# Limiter la durée de rétention
MaxRetentionSec=7day
# Rotation automatique
MaxFiles=10
```
**Impact attendu:** Prévention de la saturation disque, logs automatiquement nettoyés après 7 jours
### 4. Utiliser un niveau de log adaptatif (priorité basse)
**Solution:** Permettre de changer le niveau de log sans redémarrer le service.
**Implémentation:** Utiliser `LOG_LEVEL=warn` en production pour ne logger que les warnings et erreurs.
**Fichier:** `.env`
```env
LOG_LEVEL=warn
```
**Impact attendu:** Réduction de ~95% des logs (seulement warnings et erreurs)
## Modifications
### Fichiers à modifier
1. **`api-anchorage/src/server.js`** - Réduire le logging des requêtes HTTP
2. **`api-anchorage/src/routes/anchor.js`** - Réduire le nombre de logs par transaction
3. **`api-anchorage/src/bitcoin-rpc.js`** - Réduire les logs détaillés (optionnel)
4. **`/etc/systemd/journald.conf`** - Configuration de rotation des logs
### Fichiers de configuration
- `.env` - Changer `LOG_LEVEL=warn` pour production (si souhaité)
## Modalités de déploiement
### 1. Configuration journald (sans redémarrage de l'application)
```bash
# Éditer la configuration
sudo nano /etc/systemd/journald.conf
# Appliquer les modifications
sudo systemctl restart systemd-journald
# Vérifier l'espace utilisé
journalctl --disk-usage
```
### 2. Modification du code (nécessite redémarrage)
```bash
# Modifier les fichiers source
# ... modifications dans server.js et anchor.js ...
# Redémarrer le service
sudo systemctl restart anchorage-api
# Vérifier les nouveaux logs
journalctl -u anchorage-api.service -f
```
### 3. Changement du niveau de log (sans redémarrage si supporté)
```bash
# Modifier .env
# LOG_LEVEL=warn
# Redémarrer le service
sudo systemctl restart anchorage-api
```
## Modalités d'analyse
### Vérification du volume de logs
```bash
# Taille des logs sur 7 jours
journalctl -u anchorage-api.service --since "7 days ago" --no-pager -q | wc -c
# Nombre de lignes par jour
journalctl -u anchorage-api.service --since "1 day ago" --no-pager -q | wc -l
# Nombre de lignes par heure
journalctl -u anchorage-api.service --since "1 hour ago" --no-pager -q | wc -l
# Répartition par niveau
journalctl -u anchorage-api.service --since "1 hour ago" --no-pager -q | grep -oE "\[(INFO|ERROR|WARN|DEBUG)\]" | sort | uniq -c
```
### Vérification de l'espace disque
```bash
# Espace utilisé par journald
journalctl --disk-usage
# Espace disque disponible
df -h /var/log
```
### Analyse des types de logs
```bash
# Nombre de requêtes HTTP loggées
journalctl -u anchorage-api.service --since "1 hour ago" --no-pager -q | grep -E "POST|GET" | wc -l
# Nombre de transactions d'ancrage
journalctl -u anchorage-api.service --since "1 hour ago" --no-pager -q | grep "Anchor request received" | wc -l
# Nombre de health checks
journalctl -u anchorage-api.service --since "1 hour ago" --no-pager -q | grep "GET /health" | wc -l
```
## Impact attendu
### Réduction du volume de logs
- **Avant:** 48 MB / 7 jours (~6.9 MB/jour)
- **Après (avec correctifs 1 + 2):** ~10 MB / 7 jours (~1.4 MB/jour)
- **Réduction:** ~79% de réduction
### Réduction du nombre de lignes
- **Avant:** ~94 308 lignes/jour
- **Après:** ~20 000 lignes/jour
- **Réduction:** ~79% de réduction
### Bénéfices
- Prévention de la saturation disque
- Amélioration des performances de consultation des logs
- Réduction des coûts de stockage
- Meilleure lisibilité des logs importants
## Recommandations prioritaires
1. **Configuration journald** (priorité haute) - Prévention immédiate de la saturation
2. **Réduction du logging HTTP** (priorité haute) - Impact immédiat sur le volume
3. **Réduction des logs de transaction** (priorité moyenne) - Impact significatif
4. **Niveau de log adaptatif** (priorité basse) - Si besoin de réduire encore plus
## Notes
- Les modifications du code nécessitent un redémarrage du service
- La configuration journald peut être appliquée sans redémarrage de l'application
- Il est recommandé de tester les modifications en environnement de test avant production
- Surveiller les logs après déploiement pour s'assurer que les informations importantes sont toujours disponibles