Logs de Debug¶
⬇️ Télécharger cette page en Markdown
Vue d'ensemble¶
Le système de logs de debug permet de capturer l'intégralité du trafic HTTP et SQL à des fins d'investigation. Il est désactivé par défaut et ne génère aucun overhead quand inactif. Seul un utilisateur avec le rôle superadmin peut l'activer.
Usage production
Activez les logs uniquement le temps de l'investigation. Chaque requête génère plusieurs entrées en base — pensez à purger régulièrement.
Architecture¶
Composants¶
| Composant | Fichier | Rôle |
|---|---|---|
DebugLogger |
src/DebugLogger.php |
Classe singleton — capture, masquage, écriture |
Database |
src/Database.php |
Instrumenté — appelle DebugLogger::logSql() |
.user.ini |
public/.user.ini |
auto_prepend_file — chargement automatique |
Table debug_logs |
DB | Stockage des entrées |
| Interface superadmin | public/superadmin_debug_logs.php |
Activation, filtres, visualisation |
Activation / Désactivation¶
Via l'interface superadmin¶
/superadmin_debug_logs.php → bouton ▶ Activer le logging / ⏹ Désactiver
L'activation crée le fichier src/debug.flag. La désactivation le supprime.
Effet immédiat sur toutes les requêtes suivantes.
Via shell (urgence)¶
Données capturées¶
Niveaux de log¶
| Niveau | Contenu | Quand |
|---|---|---|
request |
Méthode, endpoint, IP, user-agent, GET/POST/JSON, headers | Début de chaque requête |
sql |
Requête SQL, paramètres liés, durée (ms), nb lignes | À chaque appel Database::* |
info |
Statut HTTP, durée totale, pic mémoire, aperçu réponse | Fin de requête (shutdown) |
error |
Message + contexte, erreurs fatales PHP | Exception ou E_ERROR |
Paramètres configurables¶
| Option | Défaut | Description |
|---|---|---|
log_params |
✅ | GET/POST/corps JSON |
log_sql |
✅ | Requêtes SQL + durée |
log_headers |
❌ | Headers HTTP complets |
log_responses |
❌ | Aperçu réponse (ob_start) |
retention_days |
7 | Purge automatique |
Champs masqués automatiquement¶
Les valeurs des champs dont la clé contient l'un de ces mots sont remplacées par [MASQUÉ] :
password, passwd, pwd, token, api_key, apikey, secret, authorization, x-api-key, credential
Troncature base64¶
Les données base64 (photos, vidéos) sont détectées (data:…;base64,) et remplacées par [BASE64_OMIS:Noctets] prefix… afin de ne pas saturer la base.
Corrélation des logs¶
Chaque requête HTTP reçoit un request_id UUID généré à l'initialisation. Toutes les entrées produites par cette requête (HTTP, SQL, erreurs, fin) partagent ce même request_id.
-- Reconstituer tout le flux d'une requête
SELECT level, sql_query, sql_params, sql_duration_ms,
http_status, duration_ms, error_message, created_at
FROM debug_logs
WHERE request_id = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
ORDER BY id;
Dans l'interface, cliquer sur les 8 premiers caractères d'un request_id filtre automatiquement sur toute la requête.
Table debug_logs¶
CREATE TABLE debug_logs (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
request_id VARCHAR(36) NOT NULL,
level ENUM('request','sql','error','info') NOT NULL,
-- HTTP
method VARCHAR(10),
endpoint VARCHAR(500),
ip_address VARCHAR(45),
user_agent TEXT,
user_id INT,
user_role VARCHAR(50),
-- Requête
get_params JSON,
post_params JSON,
request_body TEXT,
request_headers JSON,
-- SQL
sql_query TEXT,
sql_params JSON,
sql_duration_ms FLOAT,
sql_rows INT,
-- Réponse
http_status SMALLINT,
response_preview TEXT,
-- Méta
duration_ms FLOAT,
memory_peak_kb INT,
error_message TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
INDEX idx_request_id (request_id),
INDEX idx_endpoint (endpoint(100)),
INDEX idx_level (level),
INDEX idx_created_at (created_at)
);
Instrumentation de Database.php¶
Les quatre méthodes publiques sont instrumentées avec un timer :
public function fetchAll(string $sql, array $params = []): array {
$t = microtime(true);
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll();
if (class_exists('DebugLogger') && DebugLogger::isEnabled()) {
DebugLogger::logSql($sql, $params, (microtime(true) - $t) * 1000, count($rows));
}
return $rows;
}
Le check class_exists('DebugLogger') garantit qu'aucune erreur ne survient si le logger n'est pas chargé (pages CLI, tests unitaires).
Anti-récursion¶
DebugLogger utilise une connexion PDO dédiée distincte du singleton Database, et un flag statique $writing qui empêche tout appel récursif lors de l'écriture en base.
Requête HTTP
└─ Database::fetchAll() → DebugLogger::logSql() (buffer)
└─ shutdown()
└─ DebugLogger::insertRow() → PDO interne (non instrumenté)
Interface superadmin¶
Accessible à /superadmin_debug_logs.php (rôle superadmin requis).
Fonctionnalités¶
- Toggle on/off : activation instantanée sans redémarrage
- Paramètres : granularité des données capturées, rétention
- Filtres : niveau, endpoint (LIKE), IP, date, request_id exact
- Tableau : clic sur une ligne → détail expandable (tous les champs)
- Corrélation : clic sur un request_id → filtre sur toute la requête
- Purge : par ancienneté ou purge totale (TRUNCATE)
Exemple d'investigation¶
1. Activer le logging
2. Reproduire le bug depuis l'app ou le navigateur
3. Désactiver le logging
4. Filtrer par endpoint (ex: /api/submit_incident.php) ou par IP
5. Cliquer sur le request_id pour voir la séquence complète :
request → SQL Auth → SQL mairie → SQL types → SQL INSERT → info
6. Identifier l'étape qui échoue (http_status, error_message, sql_params)
7. Purger les logs après investigation
Sécurité¶
- Accès restreint : page superadmin uniquement —
$auth->requireRole(['superadmin']) - Données sensibles masquées : passwords, tokens, clés API jamais stockés en clair
- Base64 tronqués : photos et vidéos ne saturent pas la base
- Connexion isolée : DebugLogger a sa propre PDO, non loggée récursivement
- Désactivation en prod : le flag file absent = overhead nul, aucune donnée collectée
Ne pas laisser actif en production
Les logs contiennent les paramètres des requêtes (adresses, descriptions d'incidents, etc.). Activez uniquement le temps de l'investigation, puis purgez.