Files
scripts-bash/servers/linux/monitoring/lib/monitoring-lib.php
2026-03-16 22:14:35 +01:00

161 lines
4.5 KiB
PHP

<?php
/**
* Monitoring Library - PHP Version
* Copyright (C) 2026 Cédric Abonnel
* License: GNU Affero General Public License v3
*/
// --- Chemins et Constantes ---
$MONITORING_LIB_DIR = __DIR__;
$MONITORING_BASE_DIR = dirname($MONITORING_LIB_DIR);
$MONITORING_CONF_DIR = $MONITORING_BASE_DIR . '/conf';
// États globaux
$STATUS_OK = 0;
$STATUS_WARNING = 1;
$STATUS_ERROR = 2;
$STATUS_INTERNAL = 3;
$CURRENT_STATUS = $STATUS_OK;
// --- Chargement de la Config ---
$CONFIG = [
'LOG_FILE' => '/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");
}
}