Aller au contenu

Session 18 — JMeter UI : debug complet + IHM avancée + éditeur JMX inline

Durée : ~8 heures (6 conversations : debug × 2 + prometheus + UI suite × 3)
Contexte : Session marathon en 4 suites. Debug complet de l'IHM JMeter (17 bugs), puis ajout de fonctionnalités avancées : graphiques temps réel, gestionnaire de scénarios, éditeur JMX inline, sélecteurs vUsers/durée, persistance runState, revue finale.


🎯 Objectif de la session

Transformer l'IHM JMeter de "fonctionnelle mais instable" à "production-ready pédagogique" :

  • Debug : 17 bugs résolus (auth, volumes, assertions, exit codes, Prometheus)
  • Graphiques : 4 graphiques Chart.js temps réel (latence, débit, threads, samples)
  • Gestionnaire scénarios : modale drag & drop, sous-dossiers, upload, création
  • Éditeur JMX inline : parse + édition + sauvegarde des ThreadGroups et timers
  • Sélecteurs avancés : vUsers et durée en mode Slider ↔ Saisie libre
  • Persistance : runState sur disque — survit aux restarts Node
  • Validation : test Docker Desktop réussi avant push git

📦 Fichiers modifiés

Fichier Lignes Nature
jmeter-ui/src/server.js ~976 Auth, docker exec, scenarios API, JMX parser, runState persisté
jmeter-ui/public/index.html ~1500 IHM complète — tous les composants
jmeter/scenarios/*.jmx 7 fichiers Corrections assertions HTTP (test_type + test_field)
grafana/dashboards/dashboard-jmeter.json ~800 lignes Refonte complète — 25 panels (uid=perfshop-jmeter-live)
docker-compose.build.yml Ajout Services JMeter + variables env
docker-compose.desktop.yml Ajout Services JMeter + jmeter-ui-modules volume

🐛 Suite 1 — 17 bugs résolus

Auth Express-session

Cookie SameSite=None nécessite Secure=true → variables SESSION_COOKIE_SECURE / SESSION_COOKIE_SAME_SITE dynamiques selon environnement.

Assertions JMX — 100% erreurs

Assertion.test_type=2 = "Contains" sur le corps → pas sur le code HTTP. Correction : test_field=Assertion.response_code + test_type=8 (Equals) ou 40 (OR).

Exit codes JMeter

  • 0 = succès total → finished
  • 1 = assertions échouées → 🟡 Terminé (erreurs sample) (normal en chaos)
  • 143 = SIGTERM → 🟣 Terminé
  • Autres → 🔴 Erreur

Race condition bouton Stop

clearInterval(currentPollInterval) AVANT pkill — sinon le poll détectait la fin avant le changement de statut et créait un état incohérent.

Bug 401 chargement page

Flag localStorage('jmeter_session') — check uniquement si session précédente connue.


🔧 Suite 2 — Pipeline Prometheus

Plugin johrstrom 0.6.0

Syntaxe JMX PrometheusListener précise — prometheus.ip=0.0.0.0 obligatoire (écoute toutes interfaces, pas seulement localhost).

Job Prometheus

- job_name: perfshop-jmeter
  static_configs:
    - targets: ['perfshop-jmeter:9270']
  scrape_interval: 5s

Requêtes PromQL correctes

Métriques johrstrom : jmeter_response_time{quantile="0.5",label!="null"}, jmeter_threads{state="active"}, sum(rate(jmeter_transactions_total[1m])).


🔧 Suite 3 — IHM avancée

4 graphiques Chart.js temps réel

# Titre Métriques
Temps de réponse P50 / P95 / P99 ms
Débit + Erreurs Trans/s + Erreurs %
Utilisateurs virtuels Actifs / Démarrés / Terminés
Temps moyen + Échantillons Moy ms + total cumulés

MAX_POINTS = 60 (3 minutes à 3s/point). Graphiques détruits à l'idle, recréés au prochain tir.

Sélecteur URL cible

Interne / Externe / Frontend / Personnalisée + preview dynamique. Option "Utiliser le JMX tel quel" (noOverride) — aucune surcharge target_host/port.

Dashboard Grafana — refonte complète

25 panels en 4 sections : Vue d'ensemble, Temps de réponse, Débit & Erreurs, Corrélation backend. URL corrigée : .../d/perfshop-jmeter-live/ (slash final obligatoire Grafana).

Badge container JMeter health

GET /api/jmeter-container/status → widget header 🟢/🔴/⚪. Polling 60s.

Sous-dossiers scénarios (analogie LoadRunner)

jmeter/scenarios/
  ├── baseline-nominal.jmx          →  📋 Général
  ├── Fonctionnel/                   →  ⚙️ Fonctionnel
  ├── Master/                        →  🔥 Master
  └── E2E/                           →  🔄 E2E

🔧 Suite 4 — Éditeur JMX + finitions

Gestionnaire de scénarios (modale)

  • Vue arborescente par groupe
  • Drag & drop entre groupes (highlight bleu cible)
  • Upload .jmx vers dossier choisi (multer diskStorage)
  • Création / suppression dossiers
  • Toast notifications succès/erreur

Sélecteurs vUsers et Durée — radio Slider / Saisie libre

  • Slider : 1–500 vUsers, 1–1440 min (repères : 1min/1h/6h/12h/24h)
  • Saisie libre : illimitée, champ numérique + select unité (min/h/jours/semaines)
  • Slider grisé en mode saisie (opacity .35, pointer-events none)
  • Badge orange › 24h si dépassement
  • Pré-remplissage intelligent lors du changement de mode

Éditeur JMX inline (modale)

Parse XML → modèle éditable → réécriture chirurgicale (pas de re-génération).

Éditable : threads, ramp-up, durée, boucles, onError, think times (delay + déviation)
Lecture seule : requêtes HTTP, assertions, setUp/tearDown grisés

Bandeau variables IHM (en haut de chaque éditeur) :

${__P(users,10)}     → Nombre de vUsers pilotés par l'IHM
${__P(duration,300)} → Durée pilotée par l'IHM
Clic → copie presse-papier. Bouton ↩ reset sur chaque champ modifié. Badge orange si valeur diverge de l'original.

Persistance runState

runState écrit sur disque (.runstate.json) à chaque changement d'état. Au restart Node : vérification via pgrep -f jmeter si tir en cours → poll de récupération.

Paramètres du tir lancé dans le bandeau statut

Badge 👥 110 vUsers · ⏱ 07:00 = paramètres réellement envoyés à JMeter. Métrique activeThreads (Prometheus) renommée "vUsers actifs" pour clarté pédagogique.


🗂️ Bilan qualité

Erreurs Claude : - SyntaxError: Unexpected token '}' — ancienne renderJmxModel laissée en doublon lors du remplacement → supprimée - Graphiques vides affichés après restart → condition metricsEverNonZero ajoutée

Syndrome "Fix Théorique Sans Validation Empirique" : 0 occurrence cette session.
Validation finale : test Docker Desktop réussi — http://localhost:3005 fonctionnel du premier coup.


🎓 Valeur pédagogique

L'IHM JMeter PerfShop couvre désormais le cycle complet d'un ingénieur performance :

Étape Fonctionnalité
Préparer Gestionnaire scénarios, éditeur JMX inline
Configurer vUsers, durée, URL cible, mode noOverride
Lancer Bouton ▶, container permanent (0 latence JVM)
Observer 4 graphiques live, métriques Prometheus, badge health
Analyser Rapports HTML JMeter, dashboard Grafana 25 panels
Rejouer Persistance runState, restauration après restart