#!/usr/bin/env php 15 mois : suppression * * À exécuter mensuellement via crontab (1er du mois à 3h) : * 0 3 1 * * /usr/bin/php /var/www/geosector/api/scripts/cron/rotate_event_logs.php >> /var/www/geosector/api/logs/rotation_events.log 2>&1 */ declare(strict_types=1); // Configuration define('RETENTION_MONTHS', 15); // Conserver 15 mois define('LOCK_FILE', '/tmp/rotate_event_logs.lock'); // Empêcher l'exécution multiple simultanée if (file_exists(LOCK_FILE)) { $lockTime = filemtime(LOCK_FILE); // Si le lock a plus de 2 heures, on le supprime (processus probablement bloqué) if (time() - $lockTime > 7200) { unlink(LOCK_FILE); } else { die("Le processus est déjà en cours d'exécution\n"); } } // Créer le fichier de lock file_put_contents(LOCK_FILE, getmypid()); // Enregistrer un handler pour supprimer le lock en cas d'arrêt register_shutdown_function(function() { if (file_exists(LOCK_FILE)) { unlink(LOCK_FILE); } }); // Simuler l'environnement web pour AppConfig en CLI if (php_sapi_name() === 'cli') { // Détecter l'environnement basé sur le hostname $hostname = gethostname(); if (strpos($hostname, 'pra') !== false) { $_SERVER['SERVER_NAME'] = 'app3.geosector.fr'; } elseif (strpos($hostname, 'rca') !== false) { $_SERVER['SERVER_NAME'] = 'rapp.geosector.fr'; } else { $_SERVER['SERVER_NAME'] = 'dapp.geosector.fr'; // DVA par défaut } $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME']; $_SERVER['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'; // Définir getallheaders si elle n'existe pas (CLI) if (!function_exists('getallheaders')) { function getallheaders() { return []; } } } // Chargement de l'environnement require_once __DIR__ . '/../../vendor/autoload.php'; require_once __DIR__ . '/../../src/Config/AppConfig.php'; require_once __DIR__ . '/../../src/Services/LogService.php'; try { // Initialisation de la configuration $appConfig = AppConfig::getInstance(); $environment = $appConfig->getEnvironment(); // Définir le chemin du dossier des logs événements $eventLogDir = __DIR__ . '/../../logs/events'; if (!is_dir($eventLogDir)) { echo "Le dossier de logs événements n'existe pas : {$eventLogDir}\n"; exit(0); } // Date limite de suppression $deletionDate = strtotime('-' . RETENTION_MONTHS . ' months'); // Lister tous les fichiers .jsonl $jsonlFiles = glob($eventLogDir . '/*.jsonl'); if (empty($jsonlFiles)) { echo "Aucun fichier .jsonl trouvé dans {$eventLogDir}\n"; exit(0); } $deletedCount = 0; $deletedSize = 0; $deletedFiles = []; // ======================================== // Suppression des fichiers > 15 mois // ======================================== foreach ($jsonlFiles as $file) { $fileTime = filemtime($file); // Vérifier si le fichier est plus vieux que la date de rétention if ($fileTime < $deletionDate) { $fileSize = filesize($file); $fileName = basename($file); if (unlink($file)) { $deletedCount++; $deletedSize += $fileSize; $deletedFiles[] = $fileName; echo "Supprimé : {$fileName} (> " . RETENTION_MONTHS . " mois, " . number_format($fileSize / 1024, 2) . " KB)\n"; } else { echo "ERREUR : Impossible de supprimer {$fileName}\n"; } } } // ======================================== // RÉSUMÉ ET LOGGING // ======================================== if ($deletedCount > 0) { $message = sprintf( "Rotation des logs événements terminée - %d fichier(s) supprimé(s) - %.2f MB libérés", $deletedCount, $deletedSize / (1024 * 1024) ); LogService::log($message, [ 'level' => 'info', 'script' => 'rotate_event_logs.php', 'environment' => $environment, 'deleted_count' => $deletedCount, 'deleted_size_mb' => round($deletedSize / (1024 * 1024), 2), 'deleted_files' => $deletedFiles ]); echo "\n" . $message . "\n"; } else { echo "Aucune rotation nécessaire - Tous les fichiers .jsonl ont moins de " . RETENTION_MONTHS . " mois\n"; } } catch (Exception $e) { $errorMsg = 'Erreur lors de la rotation des logs événements : ' . $e->getMessage(); LogService::log($errorMsg, [ 'level' => 'error', 'script' => 'rotate_event_logs.php', 'trace' => $e->getTraceAsString() ]); echo $errorMsg . "\n"; // Supprimer le lock en cas d'erreur if (file_exists(LOCK_FILE)) { unlink(LOCK_FILE); } exit(1); } // Supprimer le lock if (file_exists(LOCK_FILE)) { unlink(LOCK_FILE); } exit(0);