InfoSys — Rapport système complet en HTML

Génère un rapport HTML complet du serveur : CPU, RAM, disques, réseau, matériel, services, paquets installés, processus. Ouvrable dans un navigateur.

sysadmindiagnostichardwaremonitoring
$ curl scripts.ysavary.fr/infosys | bash

InfoSys — Rapport système HTML

Génère un fichier HTML autonome avec toutes les informations système du serveur :
CPU, mémoire, stockage, réseau, matériel PCI, services actifs, paquets installés, top processus.

Ce que contient le rapport :

Le fichier est sauvegardé dans /tmp/ avec le nom infosys__.html et le chemin est affiché à la fin.

bash
#!/bin/bash
set -euo pipefail

OUT="/tmp/infosys_$(hostname -s)_$(date +%Y%m%d_%H%M%S).html"
NOW=$(date '+%d/%m/%Y %H:%M:%S')

# ── Collecte des données ──────────────────────────────────────────────────────
HOSTNAME=$(hostname -f 2>/dev/null || hostname)
OS=$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2 || uname -o)
KERNEL=$(uname -r)
ARCH=$(uname -m)
UPTIME=$(uptime -p 2>/dev/null || uptime)
LOAD=$(cat /proc/loadavg | awk '{print $1, $2, $3}')
BOOT=$(who -b 2>/dev/null | awk '{print $3, $4}' || echo "N/A")

CPU_MODEL=$(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2 | xargs)
CPU_CORES=$(nproc)
CPU_THREADS=$(grep -c '^processor' /proc/cpuinfo)
CPU_FREQ=$(grep -m1 'cpu MHz' /proc/cpuinfo | awk '{printf "%.0f MHz", $4}' 2>/dev/null || echo "N/A")
CPU_CACHE=$(grep -m1 'cache size' /proc/cpuinfo | cut -d: -f2 | xargs 2>/dev/null || echo "N/A")

MEM_TOTAL=$(awk '/MemTotal/ {printf "%.1f Go", $2/1024/1024}' /proc/meminfo)
MEM_AVAIL=$(awk '/MemAvailable/ {printf "%.1f Go", $2/1024/1024}' /proc/meminfo)
MEM_USED=$(awk '/MemTotal/{t=$2} /MemAvailable/{a=$2} END{printf "%.1f Go", (t-a)/1024/1024}' /proc/meminfo)
MEM_PCT=$(awk '/MemTotal/{t=$2} /MemAvailable/{a=$2} END{printf "%.0f", (t-a)/t*100}' /proc/meminfo)
SWP_TOTAL=$(awk '/SwapTotal/ {printf "%.1f Go", $2/1024/1024}' /proc/meminfo)
SWP_FREE=$(awk '/SwapFree/ {printf "%.1f Go", $2/1024/1024}' /proc/meminfo)

LSBLK=$(lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT 2>/dev/null || echo "N/A")
DF=$(df -h --output=source,size,used,avail,pcent,target -x tmpfs -x devtmpfs -x overlay 2>/dev/null | column -t)

IP_ADDR=$(ip -o addr show 2>/dev/null | awk '{print $2, $3, $4}' | grep -v '^lo ')
ROUTES=$(ip route 2>/dev/null || echo "N/A")

PCI=$(lspci 2>/dev/null || echo "lspci non disponible")
DMI=""
if command -v dmidecode &>/dev/null; then
    DMI=$(dmidecode -t system 2>/dev/null | grep -E 'Manufacturer|Product|Version|Serial' | sed 's/^\s*//')
fi

SERVICES=$(systemctl list-units --type=service --state=running --no-pager --no-legend 2>/dev/null \
    | awk '{print $1, $4}' | head -50 || echo "N/A")

PKGS=$(dpkg -l 2>/dev/null | awk '/^ii/{print $2, $3}' || echo "N/A")
PKG_COUNT=$(dpkg -l 2>/dev/null | grep -c '^ii' || echo "?")

PROCS=$(ps aux --sort=-%cpu 2>/dev/null | head -21 || echo "N/A")
MEM_PROCS=$(ps aux --sort=-%mem 2>/dev/null | head -11 || echo "N/A")

USERS=$(who 2>/dev/null || echo "Aucun utilisateur connecté")
LAST_LOGINS=$(last -n 10 2>/dev/null || echo "N/A")

# ── Helpers HTML ─────────────────────────────────────────────────────────────
h() { echo "<h2>$1</h2>"; }
pre() { echo "<pre>$(echo "$1" | sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g')</pre>"; }
row() { echo "<tr><th>$1</th><td>$2</td></tr>"; }

bar() {
    local pct=$1
    local color="#3fb950"
    [[ $pct -gt 70 ]] && color="#f0883e"
    [[ $pct -gt 90 ]] && color="#f85149"
    echo "<div class='bar-wrap'><div class='bar' style='width:${pct}%;background:${color}'></div><span>${pct}%</span></div>"
}

# ── Génération HTML ───────────────────────────────────────────────────────────
cat > "$OUT" <<HTMLEOF
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>InfoSys — $HOSTNAME</title>
<style>
  :root { --bg:#0d1117; --surface:#161b22; --border:#30363d; --accent:#58a6ff; --green:#3fb950; --text:#c9d1d9; --muted:#8b949e; }
  * { box-sizing:border-box; margin:0; padding:0; }
  body { background:var(--bg); color:var(--text); font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:14px; }
  header { background:var(--surface); border-bottom:1px solid var(--border); padding:1.5rem 2rem; display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:.5rem; }
  header h1 { font-size:1.3rem; color:var(--accent); font-family:monospace; }
  header .meta { color:var(--muted); font-size:.85rem; text-align:right; }
  .container { max-width:1200px; margin:0 auto; padding:1.5rem; }
  .grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:1rem; margin-bottom:1rem; }
  .card { background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:1.2rem; }
  .card h2 { font-size:.75rem; text-transform:uppercase; letter-spacing:.8px; color:var(--muted); margin-bottom:.8rem; }
  .card .val { font-size:1.6rem; font-weight:700; color:var(--text); }
  .card .sub { font-size:.8rem; color:var(--muted); margin-top:.2rem; }
  section { background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:1.3rem 1.5rem; margin-bottom:1rem; }
  section h2 { font-size:.95rem; font-weight:600; color:var(--accent); margin-bottom:1rem; padding-bottom:.4rem; border-bottom:1px solid var(--border); }
  table { width:100%; border-collapse:collapse; font-size:.85rem; }
  th { text-align:left; color:var(--muted); font-weight:500; padding:.4rem .8rem .4rem 0; width:200px; white-space:nowrap; }
  td { padding:.4rem 0; color:var(--text); }
  tr + tr th, tr + tr td { border-top:1px solid #21262d; }
  pre { background:#010409; border:1px solid var(--border); border-radius:6px; padding:1rem; overflow-x:auto; font-size:.78rem; line-height:1.5; color:#a5d6ff; white-space:pre; font-family:'Courier New',monospace; }
  .bar-wrap { display:flex; align-items:center; gap:.6rem; margin-top:.4rem; }
  .bar-wrap .bar { height:8px; border-radius:4px; transition:width .3s; }
  .bar-wrap span { font-size:.8rem; color:var(--muted); min-width:35px; }
  .pkg-table { width:100%; border-collapse:collapse; font-size:.78rem; }
  .pkg-table th { color:var(--muted); text-align:left; padding:.3rem .5rem; border-bottom:1px solid var(--border); position:sticky; top:0; background:var(--surface); }
  .pkg-table td { padding:.25rem .5rem; border-bottom:1px solid #21262d; font-family:monospace; }
  .pkg-table tr:hover td { background:#1c2128; }
  .pkg-scroll { max-height:400px; overflow-y:auto; border:1px solid var(--border); border-radius:6px; }
  .badge { display:inline-block; background:#1f3a56; color:var(--accent); border-radius:20px; padding:.1rem .5rem; font-size:.7rem; margin-left:.4rem; }
  .two-col { display:grid; grid-template-columns:1fr 1fr; gap:1rem; }
  @media(max-width:700px){ .two-col { grid-template-columns:1fr; } }
</style>
</head>
<body>
<header>
  <div>
    <h1>&#127760; InfoSys — $HOSTNAME</h1>
    <div style="color:var(--muted);font-size:.85rem;margin-top:.2rem">$OS</div>
  </div>
  <div class="meta">
    Généré le $NOW<br>
    Kernel : $KERNEL ($ARCH)<br>
    Démarré : $BOOT
  </div>
</header>
<div class="container">

<!-- Cartes résumé -->
<div class="grid">
  <div class="card">
    <h2>Uptime</h2>
    <div class="val" style="font-size:1rem">$UPTIME</div>
    <div class="sub">Load : $LOAD</div>
  </div>
  <div class="card">
    <h2>Mémoire RAM</h2>
    <div class="val">$MEM_USED <span style="font-size:1rem;color:var(--muted)">/ $MEM_TOTAL</span></div>
    $(bar $MEM_PCT)
    <div class="sub">Disponible : $MEM_AVAIL</div>
  </div>
  <div class="card">
    <h2>CPU</h2>
    <div class="val" style="font-size:.95rem">$CPU_MODEL</div>
    <div class="sub">$CPU_CORES cœurs physiques · $CPU_THREADS threads · $CPU_FREQ</div>
  </div>
  <div class="card">
    <h2>Paquets installés</h2>
    <div class="val">$PKG_COUNT</div>
    <div class="sub">dpkg -l | grep ^ii</div>
  </div>
</div>

<!-- Système -->
<section>
  <h2>Informations système</h2>
  <table>
    $(row "Hostname" "$HOSTNAME")
    $(row "OS" "$OS")
    $(row "Kernel" "$KERNEL")
    $(row "Architecture" "$ARCH")
    $(row "Uptime" "$UPTIME")
    $(row "Démarrage" "$BOOT")
    $(row "Load average" "$LOAD")
  </table>
</section>

<!-- CPU -->
<section>
  <h2>Processeur</h2>
  <table>
    $(row "Modèle" "$CPU_MODEL")
    $(row "Cœurs physiques" "$CPU_CORES")
    $(row "Threads" "$CPU_THREADS")
    $(row "Fréquence" "$CPU_FREQ")
    $(row "Cache" "$CPU_CACHE")
  </table>
</section>

<!-- Mémoire -->
<section>
  <h2>Mémoire</h2>
  <table>
    $(row "RAM totale" "$MEM_TOTAL")
    $(row "RAM utilisée" "$MEM_USED ($MEM_PCT%)")
    $(row "RAM disponible" "$MEM_AVAIL")
    $(row "Swap total" "$SWP_TOTAL")
    $(row "Swap libre" "$SWP_FREE")
  </table>
</section>

<!-- Stockage -->
<section>
  <h2>Stockage</h2>
  <h2 style="font-size:.78rem;color:var(--muted);margin-top:.5rem">Arborescence des disques</h2>
  $(pre "$LSBLK")
  <h2 style="font-size:.78rem;color:var(--muted);margin-top:1rem">Utilisation des partitions</h2>
  $(pre "$DF")
</section>

<!-- Réseau -->
<section>
  <h2>Réseau</h2>
  <div class="two-col">
    <div>
      <h2 style="font-size:.78rem;color:var(--muted);margin-bottom:.5rem">Interfaces</h2>
      $(pre "$IP_ADDR")
    </div>
    <div>
      <h2 style="font-size:.78rem;color:var(--muted);margin-bottom:.5rem">Table de routage</h2>
      $(pre "$ROUTES")
    </div>
  </div>
</section>

<!-- Matériel PCI -->
<section>
  <h2>Matériel PCI</h2>
  $(pre "$PCI")
  $(if [[ -n "$DMI" ]]; then echo "<h2 style='font-size:.78rem;color:var(--muted);margin-top:1rem'>DMI / SMBIOS</h2>"; pre "$DMI"; fi)
</section>

<!-- Services -->
<section>
  <h2>Services actifs <span class="badge">running</span></h2>
  $(pre "$SERVICES")
</section>

<!-- Processus -->
<section>
  <h2>Top processus</h2>
  <div class="two-col">
    <div>
      <h2 style="font-size:.78rem;color:var(--muted);margin-bottom:.5rem">Par CPU</h2>
      $(pre "$PROCS")
    </div>
    <div>
      <h2 style="font-size:.78rem;color:var(--muted);margin-bottom:.5rem">Par mémoire</h2>
      $(pre "$MEM_PROCS")
    </div>
  </div>
</section>

<!-- Utilisateurs -->
<section>
  <h2>Utilisateurs connectés</h2>
  $(pre "$USERS")
  <h2 style="font-size:.78rem;color:var(--muted);margin-top:1rem">Dernières connexions</h2>
  $(pre "$LAST_LOGINS")
</section>

<!-- Paquets -->
<section>
  <h2>Paquets installés <span class="badge">$PKG_COUNT</span></h2>
  <div class="pkg-scroll">
    <table class="pkg-table">
      <thead><tr><th>Paquet</th><th>Version</th></tr></thead>
      <tbody>
$(dpkg -l 2>/dev/null | awk '/^ii/{print "<tr><td>" $2 "</td><td>" $3 "</td></tr>"}' || echo "<tr><td colspan=2>N/A</td></tr>")
      </tbody>
    </table>
  </div>
</section>

</div>
</body>
</html>
HTMLEOF

echo ""
echo -e "\033[0;32m[INFO]\033[0m  Rapport généré avec succès :"
echo ""
echo "  Fichier : $OUT"
echo "  Taille  : $(du -sh "$OUT" | cut -f1)"
echo ""
echo "  Transférer sur ta machine :"
echo "  scp root@$(hostname -I | awk '{print $1}'):$OUT ./infosys.html"
echo ""