147 lines
4.1 KiB
Bash
147 lines
4.1 KiB
Bash
#!/bin/bash
|
|
# Copyright (C) 2026 Cédric Abonnel
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
|
|
MONITORING_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
MONITORING_BASE_DIR="$(cd "${MONITORING_LIB_DIR}/.." && pwd)"
|
|
MONITORING_CONF_DIR="${MONITORING_BASE_DIR}/conf"
|
|
|
|
# Chargement config globale
|
|
if [ -f "${MONITORING_CONF_DIR}/monitoring.conf" ]; then
|
|
# shellcheck source=/dev/null
|
|
. "${MONITORING_CONF_DIR}/monitoring.conf"
|
|
fi
|
|
|
|
SCRIPT_NAME="${SCRIPT_NAME:-$(basename "$0")}"
|
|
SCRIPT_PATH="${SCRIPT_PATH:-$(readlink -f "$0" 2>/dev/null || realpath "$0" 2>/dev/null || echo "$0")}"
|
|
|
|
STATUS_OK=0
|
|
STATUS_WARNING=1
|
|
STATUS_ERROR=2
|
|
STATUS_INTERNAL=3
|
|
|
|
CURRENT_STATUS=$STATUS_OK
|
|
|
|
LOG_LEVEL=${LOG_LEVEL:-INFO}
|
|
|
|
json_escape() {
|
|
local s="${1:-}"
|
|
s="${s//\\/\\\\}"
|
|
s="${s//\"/\\\"}"
|
|
s="${s//$'\n'/\\n}"
|
|
s="${s//$'\r'/\\r}"
|
|
s="${s//$'\t'/\\t}"
|
|
printf '%s' "$s"
|
|
}
|
|
|
|
log_event() {
|
|
local level="$1"
|
|
local event="$2"
|
|
local message="$3"
|
|
shift 3
|
|
|
|
local ts extra key value kv host
|
|
ts="$(date --iso-8601=seconds)"
|
|
|
|
# Détection dynamique du hostname si HOSTNAME_FQDN n'est pas défini
|
|
# On utilise 'hostname -f' pour le nom complet ou 'hostname' en secours
|
|
host="${HOSTNAME_FQDN:-$(hostname -f 2>/dev/null || hostname)}"
|
|
|
|
extra=""
|
|
|
|
for kv in "$@"; do
|
|
key="${kv%%=*}"
|
|
value="${kv#*=}"
|
|
extra="${extra},\"$(json_escape "$key")\":\"$(json_escape "$value")\""
|
|
done
|
|
|
|
# Utilisation de la variable 'host' détectée ci-dessus
|
|
printf '{"ts":"%s","host":"%s","app":"%s","level":"%s","event":"%s","message":"%s"%s}\n' \
|
|
"$(json_escape "$ts")" \
|
|
"$(json_escape "$host")" \
|
|
"$(json_escape "$SCRIPT_NAME")" \
|
|
"$(json_escape "$level")" \
|
|
"$(json_escape "$event")" \
|
|
"$(json_escape "$message")" \
|
|
"$extra" >> "${LOG_FILE:-/var/log/monitoring/events.jsonl}"
|
|
}
|
|
|
|
set_status() {
|
|
local new_status="$1"
|
|
if [ "$new_status" -gt "$CURRENT_STATUS" ]; then
|
|
CURRENT_STATUS="$new_status"
|
|
fi
|
|
}
|
|
|
|
log_debug() { log_event "DEBUG" "$@"; }
|
|
log_info() { log_event "INFO" "$@"; }
|
|
log_notice() { log_event "NOTICE" "$@"; }
|
|
log_warning() { log_event "WARNING" "$@"; set_status "$STATUS_WARNING"; }
|
|
log_error() { log_event "ERROR" "$@"; set_status "$STATUS_ERROR"; }
|
|
log_critical() { log_event "CRITICAL" "$@"; set_status "$STATUS_ERROR"; }
|
|
|
|
fail_internal() {
|
|
log_event "ERROR" "internal_error" "$1"
|
|
exit "$STATUS_INTERNAL"
|
|
}
|
|
|
|
exit_with_status() {
|
|
exit "$CURRENT_STATUS"
|
|
}
|
|
|
|
require_cmd() {
|
|
local cmd
|
|
for cmd in "$@"; do
|
|
command -v "$cmd" >/dev/null 2>&1 || fail_internal "Commande requise absente: $cmd"
|
|
done
|
|
}
|
|
|
|
load_conf_if_exists() {
|
|
local conf="$1"
|
|
[ -f "$conf" ] && . "$conf"
|
|
}
|
|
|
|
lock_or_exit() {
|
|
local lock_name="${1:-$SCRIPT_NAME}"
|
|
local lock_file="${MONITORING_LOCK_DIR:-/var/lock/monitoring}/${lock_name}.lock"
|
|
|
|
exec 9>"$lock_file" || fail_internal "Impossible d'ouvrir le lock $lock_file"
|
|
flock -n 9 || {
|
|
log_notice "already_running" "Une autre instance est déjà en cours" "lock=$lock_file"
|
|
exit 0
|
|
}
|
|
}
|
|
|
|
threshold_level() {
|
|
local value="$1"
|
|
local warning="$2"
|
|
local critical="$3"
|
|
|
|
if [ "$value" -ge "$critical" ]; then
|
|
printf 'CRITICAL'
|
|
elif [ "$value" -ge "$warning" ]; then
|
|
printf 'WARNING'
|
|
else
|
|
printf 'INFO'
|
|
fi
|
|
}
|
|
|
|
safe_mv() {
|
|
local src="$1"
|
|
local dst="$2"
|
|
mv -f "$src" "$dst" || fail_internal "Échec du déplacement de $src vers $dst"
|
|
}
|
|
|
|
ensure_parent_dir() {
|
|
local file="$1"
|
|
mkdir -p "$(dirname "$file")" || fail_internal "Impossible de créer le répertoire parent de $file"
|
|
} |