222 lines
5.1 KiB
Bash
222 lines
5.1 KiB
Bash
#!/usr/bin/env bash
|
|
set -uo pipefail
|
|
|
|
###############################################################################
|
|
# check-statut-recette.sh
|
|
#
|
|
# Ce script vérifie la disponibilité de plusieurs applications web définies
|
|
# dans le fichier .env.
|
|
#
|
|
# Fonctionnement global :
|
|
# 1. charge la configuration depuis le fichier .env ;
|
|
# 2. vérifie le DNS de chaque application ;
|
|
# 3. effectue une requête HTTP avec curl ;
|
|
# 4. écrit le résultat dans un fichier de log local ;
|
|
# 5. construit un message récapitulatif unique ;
|
|
# 6. envoie une seule notification Discord avec tous les statuts.
|
|
###############################################################################
|
|
|
|
#######################################
|
|
# Chargement du .env
|
|
#######################################
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
ENV_FILE="${SCRIPT_DIR}/.env"
|
|
|
|
if [[ ! -f "$ENV_FILE" ]]; then
|
|
echo "ERROR: fichier .env introuvable : $ENV_FILE" >&2
|
|
exit 1
|
|
fi
|
|
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "$ENV_FILE"
|
|
set +a
|
|
|
|
#######################################
|
|
# Vérification des variables requises
|
|
#######################################
|
|
|
|
: "${ENV_NAME:?Variable ENV_NAME manquante}"
|
|
: "${APP_LOG_DIR:?Variable APP_LOG_DIR manquante}"
|
|
: "${CHECK_CONNECT_TIMEOUT:?Variable CHECK_CONNECT_TIMEOUT manquante}"
|
|
: "${CHECK_MAX_TIME:?Variable CHECK_MAX_TIME manquante}"
|
|
: "${APP_URLS:?Variable APP_URLS manquante}"
|
|
|
|
#######################################
|
|
# Sites à vérifier
|
|
#######################################
|
|
|
|
read -r -a SITES <<< "$APP_URLS"
|
|
|
|
SCHEME="http"
|
|
CONNECT_TIMEOUT="${CHECK_CONNECT_TIMEOUT}"
|
|
MAX_TIME="${CHECK_MAX_TIME}"
|
|
|
|
#######################################
|
|
# Logs
|
|
#######################################
|
|
|
|
LOG_DIR="${APP_LOG_DIR}"
|
|
mkdir -p "$LOG_DIR"
|
|
LOG_FILE="${LOG_DIR}/app_health_$(date +'%Y-%m-%d').log"
|
|
|
|
#######################################
|
|
# Discord
|
|
#######################################
|
|
|
|
DISCORD_WEBHOOK_URL="${DISCORD_WEBHOOK_URL:-}"
|
|
DISCORD_PING="${DISCORD_PING:-@here}"
|
|
|
|
#######################################
|
|
# Variables globales de synthèse
|
|
#######################################
|
|
|
|
SUMMARY_LINES=()
|
|
FAILURES=0
|
|
|
|
#######################################
|
|
# Logging
|
|
#######################################
|
|
|
|
log_line() {
|
|
printf "%s | %s | %s | %s\n" \
|
|
"$(date +'%Y-%m-%d %H:%M:%S')" "$1" "$2" "$3" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
#######################################
|
|
# DNS
|
|
#######################################
|
|
|
|
dns_ok() {
|
|
getent hosts "$1" >/dev/null 2>&1
|
|
}
|
|
|
|
#######################################
|
|
# Ajout au résumé Discord
|
|
#######################################
|
|
|
|
add_summary_line() {
|
|
local site="$1"
|
|
local status="$2"
|
|
local detail="$3"
|
|
|
|
local icon
|
|
if [[ "$status" == "OK" ]]; then
|
|
icon="✅"
|
|
else
|
|
icon="❌"
|
|
fi
|
|
|
|
SUMMARY_LINES+=("${icon} ${site} : ${detail}")
|
|
}
|
|
|
|
#######################################
|
|
# Envoi du message Discord récapitulatif
|
|
#######################################
|
|
|
|
send_discord_summary() {
|
|
[[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0
|
|
|
|
local header_icon ping_prefix=""
|
|
if [[ "$FAILURES" -eq 0 ]]; then
|
|
header_icon="🟢"
|
|
else
|
|
header_icon="🔴"
|
|
ping_prefix="${DISCORD_PING} "
|
|
fi
|
|
|
|
local msg="**${ping_prefix}CHECK APP ${ENV_NAME} ${header_icon}**"$'\n'
|
|
|
|
local line
|
|
for line in "${SUMMARY_LINES[@]}"; do
|
|
msg+="${line}"$'\n'
|
|
done
|
|
|
|
local payload
|
|
payload="$(jq -n --arg content "$msg" '{content: $content}')"
|
|
|
|
curl -fsS -H "Content-Type: application/json" \
|
|
-d "$payload" \
|
|
"$DISCORD_WEBHOOK_URL" >/dev/null || true
|
|
}
|
|
|
|
#######################################
|
|
# Check application
|
|
#######################################
|
|
|
|
check_site() {
|
|
local host="$1"
|
|
local url="${SCHEME}://${host}/"
|
|
|
|
if ! dns_ok "$host"; then
|
|
log_line "DOWN" "$host" "Résolution impossible (getent hosts)"
|
|
add_summary_line "$host" "DOWN" "DOWN - DNS"
|
|
return 1
|
|
fi
|
|
|
|
local http_code curl_exit err
|
|
local stderr
|
|
stderr="$(mktemp)"
|
|
|
|
http_code="$(
|
|
curl -sS -o /dev/null \
|
|
-w '%{http_code}' \
|
|
--connect-timeout "$CONNECT_TIMEOUT" \
|
|
--max-time "$MAX_TIME" \
|
|
"$url" 2>"$stderr"
|
|
)"
|
|
curl_exit=$?
|
|
|
|
if [[ "$curl_exit" -ne 0 ]]; then
|
|
err="$(head -n 1 "$stderr" | tr -d '\r')"
|
|
rm -f "$stderr"
|
|
|
|
log_line "DOWN" "$host" "curl exit=$curl_exit : ${err:-"(aucun)"}"
|
|
add_summary_line "$host" "DOWN" "DOWN - curl"
|
|
return 1
|
|
fi
|
|
|
|
rm -f "$stderr"
|
|
|
|
if [[ "$http_code" =~ ^[0-9]{3}$ ]]; then
|
|
if [[ "$http_code" -ge 200 && "$http_code" -le 399 ]]; then
|
|
log_line "OK" "$host" "HTTP $http_code"
|
|
add_summary_line "$host" "OK" "OK"
|
|
return 0
|
|
fi
|
|
|
|
log_line "DOWN" "$host" "HTTP $http_code (erreur appli)"
|
|
add_summary_line "$host" "DOWN" "DOWN - HTTP $http_code"
|
|
return 1
|
|
fi
|
|
|
|
log_line "DOWN" "$host" "Code HTTP inattendu: $http_code"
|
|
add_summary_line "$host" "DOWN" "DOWN - code HTTP invalide"
|
|
return 1
|
|
}
|
|
|
|
#######################################
|
|
# Main
|
|
#######################################
|
|
|
|
main() {
|
|
local failures=0
|
|
|
|
for site in "${SITES[@]}"; do
|
|
if ! check_site "$site"; then
|
|
failures=$((failures + 1))
|
|
fi
|
|
done
|
|
|
|
FAILURES="$failures"
|
|
send_discord_summary
|
|
|
|
if [[ "$failures" -gt 0 ]]; then
|
|
exit 2
|
|
fi
|
|
|
|
exit 0
|
|
}
|
|
|
|
main "$@" |