'/var/log/monitoring/events.jsonl', 'MONITORING_LOCK_DIR' => '/var/lock/monitoring', 'LOG_LEVEL' => 'INFO' ]; if (file_exists($MONITORING_CONF_DIR . '/monitoring.conf.php')) { $global_conf = include $MONITORING_CONF_DIR . '/monitoring.conf.php'; if (is_array($global_conf)) { $CONFIG = array_merge($CONFIG, $global_conf); } } // Variables d'exécution $SCRIPT_NAME = basename($_SERVER['SCRIPT_FILENAME'] ?? $argv[0]); $SCRIPT_PATH = realpath($_SERVER['SCRIPT_FILENAME'] ?? $argv[0]); // --- Fonctions de Log --- /** * Log un événement au format JSONL */ function log_event(string $level, string $event, string $message, array $extra_kv = []) { global $CONFIG, $SCRIPT_NAME; $ts = date('c'); // ISO-8601 // Détection Hostname $host = getenv('HOSTNAME_FQDN') ?: (gethostname() ?: 'unknown'); $log_data = [ "ts" => $ts, "host" => $host, "app" => $SCRIPT_NAME, "level" => $level, "event" => $event, "message" => $message ]; // Fusion des paires clé=valeur supplémentaires foreach ($extra_kv as $kv) { if (strpos($kv, '=') !== false) { list($k, $v) = explode('=', $kv, 2); $log_data[$k] = $v; } } $json_line = json_encode($log_data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); $log_file = $CONFIG['LOG_FILE']; ensure_parent_dir($log_file); file_put_contents($log_file, $json_line . "\n", FILE_APPEND | LOCK_EX); } function set_status(int $new_status) { global $CURRENT_STATUS; if ($new_status > $CURRENT_STATUS) { $CURRENT_STATUS = $new_status; } } // Helpers de logs function log_debug($e, $m, $x = []) { log_event("DEBUG", $e, $m, $x); } function log_info($e, $m, $x = []) { log_event("INFO", $e, $m, $x); } function log_notice($e, $m, $x = []) { log_event("NOTICE", $e, $m, $x); } function log_warning($e, $m, $x = []) { log_event("WARNING", $e, $m, $x); set_status(1); } function log_error($e, $m, $x = []) { log_event("ERROR", $e, $m, $x); set_status(2); } function log_critical($e, $m, $x = []) { log_event("CRITICAL", $e, $m, $x); set_status(2); } function fail_internal(string $msg) { log_event("ERROR", "internal_error", $msg); exit(3); // STATUS_INTERNAL } function exit_with_status() { global $CURRENT_STATUS; exit($CURRENT_STATUS); } // --- Utilitaires Système --- /** * Vérifie la présence de commandes système */ function require_cmd(...$cmds) { foreach ($cmds as $cmd) { $output = []; $res = 0; exec("command -v " . escapeshellarg($cmd), $output, $res); if ($res !== 0) { fail_internal("Commande requise absente: $cmd"); } } } /** * Gestion du verrouillage (Lock) */ function lock_or_exit(?string $lock_name = null) { global $CONFIG, $SCRIPT_NAME; $name = $lock_name ?: $SCRIPT_NAME; $lock_file = ($CONFIG['MONITORING_LOCK_DIR'] ?? '/var/lock/monitoring') . "/{$name}.lock"; ensure_parent_dir($lock_file); $fp = fopen($lock_file, "w+"); if (!$fp || !flock($fp, LOCK_EX | LOCK_NB)) { log_notice("already_running", "Une autre instance est déjà en cours", ["lock=$lock_file"]); exit(0); } // On garde le descripteur ouvert pour maintenir le lock return $fp; } /** * Évalue un niveau selon des seuils */ function threshold_level($value, $warning, $critical) { if ($value >= $critical) return 'CRITICAL'; if ($value >= $warning) return 'WARNING'; return 'INFO'; } function ensure_parent_dir(string $file) { $dir = dirname($file); if (!is_dir($dir)) { if (!mkdir($dir, 0755, true)) { // Ici on ne peut pas appeler log_event si c'est le répertoire de log qui échoue error_log("Impossible de créer le répertoire : $dir"); exit(3); } } } function safe_mv(string $src, string $dst) { if (!rename($src, $dst)) { fail_internal("Échec du déplacement de $src vers $dst"); } }