API d'analyse des résultats

Chaque page de résultats d'un test de charge est construite à partir d'un seul document JSON : tous les échantillons de l'exécution, agrégés en percentiles, types d'erreur et synthèses par requête, par région et par palier d'utilisateurs. Ce même document est disponible pour vos propres outils via l'API d'analyse, pour qu'un tableau de bord, un générateur de rapports ou une étape de CI lise exactement les chiffres affichés sur la page de résultats.

Point d'accès

GET /api/v1/{loadtests|k6tests|jmetertests}/analysis?testrunname=<name>&testrunid=<id>

Envoyez votre clé d'API dans l'en-tête loadfocus-auth. Utilisez loadtests pour les tests cloud, k6tests pour les scripts k6 et jmetertests pour les plans JMeter. Les deux paramètres sont obligatoires ; testrunid est le numéro d'exécution visible dans l'URL des résultats (voir Qu'est-ce qu'un identifiant d'exécution de test ?). Les requêtes sont limitées à 100 par 15 minutes et par clé d'API.

curl -H "loadfocus-auth: $LOADFOCUS_API_KEY" \
"https://loadfocus.com/api/v1/loadtests/analysis?testrunname=checkout-flow&testrunid=12"

Une exécution terminée est calculée une fois puis mise en cache, les appels répétés sont donc peu coûteux. Une exécution en cours renvoie ses chiffres à date.

Réponses

StatutCorpsSignification
200le document d'analyseL'exécution existe et contient des échantillons.
404{ "error": "no-data" }Exécution inconnue, appartenant à une autre équipe, ou sans échantillon pour l'instant.
503{ "error": "analysis-unavailable" }Le calcul a échoué ou expiré. Réessayez ; ne le traitez pas comme « pas de données » dans une porte de CI.
400{ "error": "testrunname-and-testrunid-required" }Un paramètre manque.
400{ "error": "invalid-api-key" }La clé d'API ne correspond à aucune équipe.
429{ "error": "Too many requests, please try again later." }Plus de 100 requêtes en 15 minutes pour cette clé d'API.

Le document

{
"samples": 50312,
"overall": {
"mean": 212.4, "p50": 180, "p90": 410, "p95": 612, "p99": 1480,
"min": 41, "max": 5120, "sd": 233.1, "latency": 198.7, "connect": 9.2,
"errors": 137, "errorPct": 0.3, "rps": 83.9,
"first": 1756540800000, "last": 1756541400000
},
"labels": [ { "label": "GET /api/products", "samples": 25100, "mean": 190.2, "p50": 160, "p90": 380, "p95": 540, "p99": 1200, "errors": 12, "errorPct": 0.1, "rps": 41.8, "min": 41, "max": 3100, "sd": 201.0, "latency": 180.1, "connect": 8.9 } ],
"byThreads": [ { "vus": 50, "samples": 4210, "mean": 150.3, "max": 900, "errors": 0, "rps": 44.1, "errorPct": 0 } ],
"byRegion": [ { "region": "us-east-1", "samples": 25156, "mean": 170.5, "p95": 480, "p99": 1100, "errors": 40, "errorPct": 0.2, "rps": 41.9 } ],
"errorTypes": [ { "label": "POST /api/checkout", "type": "502", "count": 90, "message": "Bad Gateway", "messages": 90, "topMessages": [ { "message": "Bad Gateway", "count": 90 } ] } ],
"perSecond": [ { "t": 1756540800000, "samples": 62, "errors": 0, "errorPct": 0 } ],
"histogram": { "step": 50, "buckets": [ { "from": 0, "to": 50, "count": 812 } ], "over": 31 },
"apdex": { "t": 500, "satisfied": 44100, "tolerating": 5200, "frustrated": 1012, "score": 0.93 },
"settled": true
}
  • samples est le nombre de requêtes enregistrées sur l'ensemble des moteurs et des régions. Tous les autres chiffres sont calculés à partir de ces échantillons, pas de moyennes par moteur.
  • overall est l'exécution entière. Les temps sont en millisecondes ; latency est le temps jusqu'au premier octet, connect le temps de connexion. rps correspond aux échantillons divisés par les secondes actives de l'exécution. first et last sont des millisecondes epoch.
  • labels contient une ligne par requête (URL ou nom de sampler) avec les mêmes champs plus ses propres percentiles.
  • byThreads regroupe les échantillons selon le nombre d'utilisateurs virtuels actifs à ce moment-là. Lisez-le comme le temps de réponse en fonction de la charge : le palier où mean ou max décroche est votre capacité.
  • byRegion contient une ligne par région cloud, pour les exécutions multi-régions.
  • errorTypes contient une ligne par requête et type d'échec (type est le code de statut HTTP ou le nom de l'exception JMeter), au plus les 100 plus fréquents, avec le message d'erreur le plus fréquent et jusqu'à cinq topMessages.
  • perSecond est le taux d'erreur dans le temps ; les longues exécutions sont ramenées à 3 600 points au maximum.
  • histogram est la distribution des temps de réponse tracée sur la page de résultats, avec le nombre d'échantillons au-delà du dernier intervalle dans over.
  • apdex utilise une cible de 500 ms : un échantillon est satisfied jusqu'à 500 ms, tolerating jusqu'à 2 000 ms et frustrated au-delà. score vaut (satisfied + tolerating / 2) / total.
  • settled vaut true une fois l'exécution terminée et ses chiffres définitifs. Une exécution en cours renvoie false ; attendez true avant de vous fonder sur les chiffres.

Les percentiles proviennent de 1 000 intervalles logarithmiques ; p99 est donc exact à une fraction de pour cent près et ne correspondra pas à la milliseconde à un tableur calculé sur le JTL brut.

Conditionner un pipeline

Pour une décision réussite/échec, utilisez plutôt l'API de verdict : elle applique les seuils enregistrés sur le test et renvoie un verdict, celui que lit la GitHub Action. Utilisez l'API d'analyse quand vous avez besoin des chiffres eux-mêmes, par exemple pour publier le p95 par point d'accès dans un commentaire de pull request ou tenir votre propre historique de tendances.

Connexe