Monitorer son serveur avec Netdata

Credit : Logo officiel

Monitorer son serveur avec Netdata

Dylan D. — Agent Support Technique Serveur DevOps 2559 mots 13 min de lecture

Monitorer son serveur avec Netdata

Il y a deux mois, un client m'appelle un dimanche soir : son site WordPress repond en timeout depuis l'apres-midi. Je me connecte au VPS, htop, free, df, iostat... le swap est plein, le disque sature en IO, et le php-fpm consomme 95% du CPU. Probleme : je n'ai aucun historique. Impossible de savoir si c'est arrive d'un coup ou progressivement, si c'est lie a un cron, a une requete bot, ou a une fuite memoire d'un plugin. C'est la que Netdata aurait sauve la mise. En une heure on l'a installe et configure, et les fois suivantes ou ce genre de probleme s'est presente, j'avais le graphique sous les yeux et le coupable identifie en 30 secondes.

Je te montre comment je deploie Netdata sur un VPS Debian 12, comment je le securise, comment je configure les alertes pour qu'elles arrivent sur Slack avant que les utilisateurs s'en rendent compte, et comment l'integrer aux services tournants (Nginx, MySQL, PHP-FPM).

Pourquoi Netdata plutot que Prometheus + Grafana ?

J'ai longtemps tourne avec Prometheus + Grafana + Loki + AlertManager. C'est puissant, c'est l'industrie standard, et c'est clairement overkill pour un VPS isole. Quatre services a maintenir, deux dashboards a configurer, des regles PromQL a ecrire... pour un site qui veut juste savoir quand son disque arrive a 90%, c'est sortir le bazooka pour tuer une mouche.

Netdata, c'est :

Pour 99% des besoins de mes clients (sites WordPress, PrestaShop, applis Node sur VPS unique), c'est l'outil parfait. Au-dessus, quand tu commences a avoir un cluster de 10+ serveurs, Prometheus + Grafana redevient pertinent.

Quand Netdata atteint ses limites

Je veux etre honnete : Netdata n'est pas la reponse a tout. Ses limites :

Ma regle : Netdata jusqu'a 5-10 serveurs, Prometheus + Grafana au-dela. Et meme dans une infra Prometheus, garder un Netdata local sur chaque host pour le debug temps reel reste pertinent.

Installation en cinq minutes

Le script officiel installe la derniere version stable depuis les depots Netdata :

curl https://get.netdata.cloud/kickstart.sh > /tmp/netdata-kickstart.sh
sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry

--disable-telemetry desactive l'envoi anonyme de stats vers Netdata Cloud. A toi de voir, mais perso j'aime bien que mes serveurs ne phone-home pas par defaut.

Verification :

systemctl status netdata
ss -tlnp | grep 19999
curl -sI http://127.0.0.1:19999 | head -1

Le service ecoute sur le port 19999. Le dashboard est accessible immediatement, mais il est ouvert a tous les vents : on va corriger ca tout de suite.

Securiser le dashboard

Par defaut le port 19999 est expose en HTTP brut sans authentification. Donc avant tout, on bloque l'acces direct au port :

ufw deny 19999

Ou si tu utilises iptables direct :

iptables -A INPUT -p tcp --dport 19999 -j DROP

Dans /etc/netdata/netdata.conf, restreins l'ecoute a localhost :

[web]
    bind to = 127.0.0.1

Puis on monte un reverse proxy Nginx avec HTTPS et auth basique. Cree d'abord le mot de passe :

apt install apache2-utils -y
htpasswd -c /etc/nginx/.htpasswd-monitoring admin

Vhost /etc/nginx/sites-available/monitoring.monsite.fr :

server {
    listen 443 ssl http2;
    server_name monitoring.monsite.fr;

    ssl_certificate /etc/letsencrypt/live/monitoring.monsite.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/monitoring.monsite.fr/privkey.pem;

    auth_basic "Monitoring";
    auth_basic_user_file /etc/nginx/.htpasswd-monitoring;

    location / {
        proxy_pass http://127.0.0.1:19999;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Connection "upgrade";
        proxy_set_header Upgrade $http_upgrade;
    }
}

server {
    listen 80;
    server_name monitoring.monsite.fr;
    return 301 https://$host$request_uri;
}
ln -s /etc/nginx/sites-available/monitoring.monsite.fr /etc/nginx/sites-enabled/
certbot --nginx -d monitoring.monsite.fr
nginx -t && systemctl reload nginx
systemctl restart netdata

Pour aller plus loin, tu peux ajouter un filtre IP au niveau Nginx (allow/deny) ou mettre Netdata derriere un VPN WireGuard. Sur les infras de mes clients sensibles, c'est exclusivement WireGuard : aucun port monitoring n'est expose au public, jamais.

Ce que le dashboard te donne sans rien configurer

Une fois en route, Netdata expose en temps reel (granularite 1 seconde) :

Chaque graphique est zoomable, exportable en CSV, et les correlations entre metriques sont automatiques (clique sur un pic de CPU, le panneau te montre quel process l'a cause).

Configurer les alertes : la vraie valeur

Netdata embarque plus de 300 alertes preconfigurees dans /etc/netdata/health.d/. La plupart conviennent telles quelles, mais certaines meritent un ajustement.

/etc/netdata/edit-config health.d/disks.conf

Exemple personnalise pour l'espace disque (j'ai failli perdre des donnees une fois sur un client dont le /var/log a sature, du coup maintenant c'est ma premiere alerte) :

 template: disk_space_usage
       on: disk.space
   lookup: max -1m unaligned of avail
    units: GiB
    every: 1m
     warn: $this < 10
     crit: $this < 5
     info: Espace disque disponible
       to: sysadmin
    delay: down 15m multiplier 1.5 max 1h

Apres modif :

netdatacli reload-health

Quelques alertes que je personnalise systematiquement chez mes clients :

Notifications email et Slack

Le vrai pouvoir des alertes c'est qu'elles arrivent ou tu regardes. Email c'est bien pour les rapports quotidiens, Slack/Discord/Telegram pour le temps reel.

/etc/netdata/edit-config health_alarm_notify.conf

Email via msmtp

SEND_EMAIL="YES"
DEFAULT_RECIPIENT_EMAIL="admin@monsite.fr"
EMAIL_SENDER="netdata@monsite.fr"

Necessite que sendmail ou msmtp soit configure cote systeme. Sinon tu peux le rediriger via Postfix relay vers ton SMTP.

Slack

Cree un Incoming Webhook dans ton Slack puis :

SEND_SLACK="YES"
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T00/B00/XXXX"
DEFAULT_RECIPIENT_SLACK="#monitoring"

Discord

SEND_DISCORD="YES"
DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/.../..."
DEFAULT_RECIPIENT_DISCORD="alerts"

Telegram

Cree un bot via @BotFather, recupere le token, puis le chat_id en envoyant un message au bot et en interrogeant https://api.telegram.org/bot<TOKEN>/getUpdates :

SEND_TELEGRAM="YES"
TELEGRAM_BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
DEFAULT_RECIPIENT_TELEGRAM="-1001234567890"

Teste tout ca avant de te coucher tranquille :

/usr/libexec/netdata/plugins.d/alarm-notify.sh test

Tu dois recevoir des notifs critical, warning et clear sur tous tes canaux configures. Sur mes infras j'envoie warning sur Slack en non-prioritaire et critical en simultane Slack + Telegram + SMS via Twilio (relai custom). De cette maniere j'ai un signal fort qui me reveille la nuit uniquement quand c'est vraiment urgent.

Integrer les services applicatifs

Netdata detecte la plupart des services tout seul, mais certains demandent un peu de config.

MySQL / MariaDB

Cree un utilisateur dedie en lecture seule :

CREATE USER 'netdata'@'localhost' IDENTIFIED BY '';
GRANT USAGE, REPLICATION CLIENT, PROCESS ON *.* TO 'netdata'@'localhost';
FLUSH PRIVILEGES;

/etc/netdata/go.d/mysql.conf :

jobs:
  - name: local
    dsn: netdata@unix(/run/mysqld/mysqld.sock)/

Nginx

Active le stub_status :

server {
    listen 127.0.0.1:80;
    server_name _;
    location = /nginx_status {
        stub_status;
        allow 127.0.0.1;
        deny all;
    }
}

PHP-FPM

Dans /etc/php/8.3/fpm/pool.d/www.conf :

pm.status_path = /status
ping.path = /ping

Et expose /status derriere un location interne dans Nginx (allow 127.0.0.1 only).

systemctl restart netdata php8.3-fpm nginx

Redis

Netdata detecte automatiquement Redis si la socket Unix par defaut est presente. Sinon, edite /etc/netdata/go.d/redis.conf avec ton address et password (si AUTH est active). Tu obtiens en bonus la latence p50/p95/p99 par commande, le hit ratio du cache, et l'evolution de la memoire utilisee.

Logs Nginx en analyse temps reel

Le plugin web_log parse les logs d'access Nginx et te donne des graphes par code HTTP, par URL pattern, par user-agent. Active dans /etc/netdata/go.d/web_log.conf :

jobs:
  - name: nginx
    path: /var/log/nginx/access.log
    log_type: combined

Apres redemarrage, le dashboard affiche automatiquement les nouveaux graphes MySQL, Nginx, PHP-FPM, Redis et l'analyse des logs.

Retention des donnees historiques

Par defaut Netdata garde environ 2 a 4 heures de metriques. Pour conserver plusieurs semaines, edite /etc/netdata/netdata.conf :

[db]
    mode = dbengine
    storage tiers = 3
    dbengine tier 0 retention size = 2GiB
    dbengine tier 1 retention size = 1GiB
    dbengine tier 2 retention size = 512MiB

Les tiers fonctionnent par agregation : tier 0 = donnees brutes 1s, tier 1 = moyennes par minute, tier 2 = moyennes par heure. Avec cette config tu as un mois de detail seconde, plusieurs mois en minute, et plus d'un an en heure. Le tout dans 4 Go max.

Workflow d'incident type avec Netdata

Quand une alerte tombe, voila le workflow que je suis sur les serveurs de mes clients. Disons que je recois sur Slack : [CRIT] disk_space_usage: 4.2 GiB free (threshold 5 GiB). Mes etapes :

  1. Connexion au dashboard via le sous-domaine monitoring securise, focus sur le graphique disk.space sur la fenetre des 24 dernieres heures pour voir la pente.
  2. Identifier la trajectoire : si la chute est brutale (un drop net), c'est un evenement (un dump SQL, une mise a jour, un log qui explose). Si c'est lineaire sur plusieurs jours, c'est une fuite ou une croissance organique.
  3. Croiser avec les applications : quel groupe de processus a vu son IO ecriture monter en meme temps ? apt, mysqld, php-fpm, nginx... Netdata montre le coupable par categorie de process.
  4. Confirmer en SSH avec du -sh /var/* | sort -h, generalement /var/log ou /var/lib/mysql/binlog est en cause.
  5. Documenter le fix dans un runbook interne pour la prochaine fois (rotation des binlogs, purge des logs Nginx, vidage du repertoire de cache, etc.).

Ce workflow demande 5 minutes au lieu de 30 sans monitoring historique. C'est exactement le ROI de Netdata : pas la vitesse de detection (un df -h fait pareil), mais la vitesse de comprehension du "pourquoi".

Tableaux de bord custom

Le dashboard par defaut de Netdata est exhaustif mais parfois trop dense. Pour les clients qui veulent une vue "executive" (5 metriques cles, pas plus), Netdata propose des dashboards custom via la fonctionnalite "Custom Dashboards". Un fichier HTML simple avec quelques <div data-netdata="system.cpu"> :

<!DOCTYPE html>
<html>
<head><script src="http://monitoring.monsite.fr/dashboard.js"></script></head>
<body>
  <h1>Vue production</h1>
  <div data-netdata="system.cpu" data-after="-300" data-chart-library="dygraph"></div>
  <div data-netdata="system.ram" data-after="-300"></div>
  <div data-netdata="web_log_nginx.requests_per_url" data-after="-3600"></div>
  <div data-netdata="mysql_local.queries" data-after="-300"></div>
</body>
</html>

Tu deposes ca dans /var/cache/netdata/dashboards/ et tu y accedes via l'URL monitoring.monsite.fr/v1/dashboards/prod.html. Pratique pour les TV de bureau ou les ecrans de NOC. Et si tu veux pousser plus loin, Netdata expose toutes ses metriques en JSON sur /api/v1/data?chart=...&format=json, donc tu peux brancher ton propre frontal.

Centraliser plusieurs serveurs (parent/child)

Quand tu as 3 a 10 serveurs, le pattern parent/child de Netdata est tres pratique : chaque "child" envoie ses metriques a un "parent" central qui les stocke et expose un dashboard unifie. Sur le parent, edite /etc/netdata/stream.conf :

[API_KEY_GENEREE_AVEC_uuidgen]
    enabled = yes
    default history = 3600
    default memory mode = dbengine
    health enabled by default = auto
    allow from = 10.0.0.0/24

Sur chaque child, meme fichier mais cote sortant :

[stream]
    enabled = yes
    destination = parent.monsite.fr:19999
    api key = API_KEY_GENEREE_AVEC_uuidgen

Le child peut alors fonctionner en memory mode = none, ne stocker aucune metrique localement, et tout pousser vers le parent. Le parent devient ton point d'entree unique avec une vue de tous les hosts. Pour la securite, j'ajoute du TLS via enable ssl = yes et un certificat autosigne ou Let's Encrypt en frontal.

Erreurs courantes et leur fix

Pour aller plus loin

Monitoring c'est une brique d'observabilite. Pour completer :

Ne jamais piloter a l'aveugle

Un serveur sans monitoring, c'est une voiture sans tableau de bord : ca roule jusqu'au moment ou ca s'arrete brutalement. Netdata, en cinq minutes d'install et une heure de configuration, te donne une visibilite totale sur ton infra avec des alertes qui te previennent avant les utilisateurs. Combine ca avec une bonne strategie de backups et un fail2ban bien regle, et tu es prepare pour l'immense majorite des incidents qui peuvent arriver.

EDIT 2026 : depuis la v1.44, le support natif de systemd journal facilite enormement le debug en cherchant dans les logs sans quitter le dashboard. Et l'integration native avec Prometheus en sortie permet de reutiliser Netdata comme exporter si jamais tu finis par monter un Grafana central. La fonctionnalite Netdata Cloud, dans son free tier, devient aussi tres correcte pour federer 5 a 10 nodes sans rien deployer cote parent — a tester si tu n'as pas envie de gerer le stream.conf toi-meme.

# Articles similaires

Sur les memes sujets et plus loin