Cet article explique comment accéder aux paramètres des capteurs matériels (sondes, ventilateurs) et les contrôler sur un serveur physique sous Linux Ubuntu, et effectuer un test de charge pour vérifier que le refroidissement est correct sur un serveur nouvellement installé.
On ne considère ici que le matériel grand public (PC assemblé). En cas d'utilisation de matériel de récupération (Dell iDRAC, HP iLO, Supermicro, etc.) voir également ipmitool.
Installer de quoi surveiller le matériel:
# apt install lm-sensors nvme-cli linux-firmware amd64-microcode hwinfo jq
Vérifier:
# sensors-detect
=> valider toutes les réponses par défaut et ignorer le "no sensors were detected" (beaucoup de cartes mères récentes exposent les capteurs directement via le noyau et sensors-detect ne trouve rien, ce qui est normal).
Commandes utiles:
# hwinfo
# sensors
# nvme list
# nvme smart-log /dev/nvmeX
Exemple de sortie de la commande sensors:
$ sensors
amdgpu-pci-1c00
Adapter: PCI adapter
vddgfx: 1.10 V
vddnb: 914.00 mV
edge: +44.0°C
PPT: 8.00 mW
nvme-pci-0400
Adapter: PCI adapter
Composite: +49.9°C (low = -273.1°C, high = +80.8°C)
(crit = +84.8°C)
Sensor 1: +62.9°C (low = -273.1°C, high = +65261.8°C)
Sensor 2: +49.9°C (low = -273.1°C, high = +65261.8°C)
r8169_0_f00:00-mdio-0
Adapter: MDIO adapter
temp1: +60.0°C (high = +120.0°C)
k10temp-pci-00c3
Adapter: PCI adapter
Tctl: +48.4°C
Tccd1: +31.9°C
Tccd2: +33.1°C
nvme-pci-0700
Adapter: PCI adapter
Composite: +49.9°C (low = -273.1°C, high = +80.8°C)
(crit = +84.8°C)
Sensor 1: +61.9°C (low = -273.1°C, high = +65261.8°C)
Sensor 2: +49.9°C (low = -273.1°C, high = +65261.8°C)
1. La température Composite est généralement celle utilisée pour le throttling et constitue donc l'indicateur le plus pertinent.
2. Si le GPU est passé en passthrough à une VM, la commande sensors ne récupèrera pas la température, il faut passer la commande dans la VM.
Le script suivant permet de vérifier le comportement du CPU sous forte charge en surveillant la température, afin de valider le compromis silence/refroidissement réglé dans le BIOS:
#!/bin/bash
trap 'killall yes 2>/dev/null' EXIT
CORES=$(nproc)
for i in $(seq 1 $CORES); do
yes > /dev/null &
done
sleep 20
killall yes
#end#
Ce script charge tous les cores pendant 20 secondes.
Afficher les températures en parallèle avec la commande sensors:
La température doit monter immédiatement puis se stabiliser (autour de max. ~85 à 90 degrés dans mon cas pour un AMD 9950X ; dépend de la spécification du Tjmax du CPU) puis redescendre en quelques secondes après la fin du test.
C'est un test minimal pour faire monter le CPU en température sans installer de paquet supplémentaire. Il ne sollicite pratiquement que les unités entières. Pour un test plus représentatif, utiliser stress-ng (voir plus bas).
Voici des exemples de commandes complémenatires pour contrôler les ventilateurs depuis l'OS (sur carte mère compatible) et de faire des stress-tests plus poussés:
# apt install lm-sensors fancontrol stress-ng
# pwmconfig
# systemctl enable --now fancontrol
# systemctl status fancontrol
# stress-ng --cpu 0 --timeout 30s
# stress-ng --cpu 4 --vm 2 --io 2 --timeout 60s
# stress-ng --matrix 0 --timeout 30s --metrics-brief # test de charge hardware
fancontrol est un outil destiné à des cas particuliers ; tous les BIOS modernes savent très bien gérer les ventilateurs.
Pour enregistrer périodiquement les températures dans les logs, voici un exemple simple de script à intégrer:
J'ai mis en place ce logging suite à un crash "sec" d'un serveur, sans aucune info exploitable dans les logs, nada. Pour écarter un éventuel problème de surchauffe j'ai décidé de mettre ça en place, ce qui en cas de récidive permettra de confirmer ou infirmier l'hypothèse. Ce serveur fonctionne maintenant depuis longtemps sans avoir crashé.
vi /usr/local/bin/hwmon-sampler.sh
#!/usr/bin/env bash
set -euo pipefail
LOGFILE="/var/log/hwmon-samples.log"
LOCKFILE="/tmp/hwmon-sampler.lock"
exec 9>"$LOCKFILE"
if ! flock -n 9; then
exit 0
fi
sample_once() {
local ts cpu gpu nic load1 load5 load15 mem_used mem_total mem_free mem_avail uptime_s
ts="$(date -Is)"
# Load averages
read -r load1 load5 load15 _ < /proc/loadavg
# Memory (kB)
read -r _ mem_total _ < <(grep -m1 '^MemTotal:' /proc/meminfo)
read -r _ mem_free _ < <(grep -m1 '^MemFree:' /proc/meminfo)
read -r _ mem_avail _ < <(grep -m1 '^MemAvailable:' /proc/meminfo)
mem_total="${mem_total% kB}"
mem_free="${mem_free% kB}"
mem_avail="${mem_avail% kB}"
mem_used=$(( mem_total - mem_avail ))
# Uptime (seconds)
read -r uptime_s _ < /proc/uptime
# Sensors JSON
local js
if ! js="$(sensors -j 2>/dev/null)"; then
echo "$ts level=error msg=\"sensors failed\"" >> "$LOGFILE"
return
fi
# CPU temp (k10temp: prefer Tctl then Tdie)
cpu="$(jq -r '
to_entries
| map(select(.key|startswith("k10temp")))
| (.[0].value.Tctl.temp1_input // .[0].value.Tdie.temp1_input // empty)
' <<<"$js")"
[[ -z "${cpu:-}" ]] && cpu=""
# GPU temp (amdgpu edge)
gpu="$(jq -r '
to_entries
| map(select(.key|startswith("amdgpu")))
| if length>0 then (.[0].value.edge.temp1_input // empty) else empty end
' <<<"$js")"
[[ -z "${gpu:-}" ]] && gpu=""
# NIC temp (e.g. r8169)
nic="$(jq -r '
to_entries
| map(select(.key|test("(^|-)r8169")))
| if length>0 then (.[0].value.temp1.temp1_input // empty) else empty end
' <<<"$js")"
[[ -z "${nic:-}" ]] && nic=""
# NVMe Composite temps sorted by device id → nvme1..nvme4
IFS=$'\n' read -r -d '' -a nvmes < <(jq -r '
to_entries
| map(select(.key|startswith("nvme-pci-")))
| sort_by(.key)
| map(.value.Composite.temp1_input // empty)
| .[]
' <<<"$js" && printf '\0')
nvme1="${nvmes[0]:-}"; nvme2="${nvmes[1]:-}"; nvme3="${nvmes[2]:-}"; nvme4="${nvmes[3]:-}"
# Optional GPU power if exposed as PPT (amdgpu)
local gpupwr
gpupwr="$(jq -r '
to_entries
| map(select(.key|startswith("amdgpu")))
| if length>0 then (
(.[0].value.PPT.power1_average // .[0].value.PPT.power1_input // empty)
) else empty end
' <<<"$js")"
[[ -z "${gpupwr:-}" ]] && gpupwr=""
# One compact line (space-separated key=val)
echo "$ts cpu_c=${cpu}C gpu_c=${gpu}C nvme1_c=${nvme1}C nvme2_c=${nvme2}C nvme3_c=${nvme3}C nvme4_c=${nvme4}C nic_c=${nic}C gpupwr_w=${gpupwr} load1=${load1} load5=${load5} load15=${load15} mem_used_kb=${mem_used} mem_total_kb=${mem_total} uptime_s=${uptime_s}" >> "$LOGFILE"
}
# 4 samples at 15s interval
for _ in 1 2 3 4; do
sample_once
sleep 15
done
Pour mettre en place la collecte dans les logs: exemple
# chmod +x /usr/local/bin/hwmon-sampler.sh
# crontab -e
* * * * * /usr/local/bin/hwmon-sampler.sh
Pour un GPU Nvidia:
# nvidia-smi
# nvidia-smi --query-gpu=temperature.gpu,fan.speed --format=csv
Pour aller directement à l'essentiel et récupérer rapidement toutes les informations utiles sur l'état du système:
# apt install lm-sensors stress-ng nvme-cli
# sensors
# watch -n1 sensors
# stress-ng --cpu 0 --timeout 60s
# nvidia-smi
--
TG - 06/2026