Comment mesurer simultanément les temps de demande et de réponse à l'aide de cURL?

659

J'ai un service Web qui reçoit des données au format JSON, traite les données, puis renvoie le résultat au demandeur.

Je souhaite mesurer la demande, la réponse et le temps total à l'aide cURL.

Mon exemple de demande ressemble à ceci:

curl -X POST -d @file server:port

et je mesure actuellement cela en utilisant la timecommande sous Linux:

time curl -X POST -d @file server:port

Cependant, la commande time ne mesure que le temps total - ce qui n'est pas tout à fait ce que je recherche.

Existe-t-il un moyen de mesurer les temps de demande et de réponse en utilisant cURL?

sdasdadas
la source

Réponses:

1677

De ce brillant article de blog ... https://blog.josephscott.org/2011/10/14/timing-details-with-curl/

cURL prend en charge la sortie formatée pour les détails de la demande (voir la page de manuel cURL pour plus de détails , sous -w, –write-out <format>). Pour nos besoins, nous nous concentrerons uniquement sur les détails de calendrier qui sont fournis. Les temps ci-dessous sont en secondes .

  1. Créez un nouveau fichier, curl-format.txt, et collez-le:

        time_namelookup:  %{time_namelookup}s\n
           time_connect:  %{time_connect}s\n
        time_appconnect:  %{time_appconnect}s\n
       time_pretransfer:  %{time_pretransfer}s\n
          time_redirect:  %{time_redirect}s\n
     time_starttransfer:  %{time_starttransfer}s\n
                        ----------\n
             time_total:  %{time_total}s\n
    
  2. Faire une demande:

    curl -w "@curl-format.txt" -o /dev/null -s "http://wordpress.com/"
    

    Ou sous Windows, c'est ...

    curl -w "@curl-format.txt" -o NUL -s "http://wordpress.com/"
    


Ce que cela fait:

-w "@curl-format.txt"indique à cURL d'utiliser notre fichier de format
-o /dev/nullredirige la sortie de la demande vers / dev / null
-s indique à cURL de ne pas montrer qu'un indicateur de progression
"http://wordpress.com/"est l'URL que nous demandons. Utilisez des guillemets en particulier si votre URL a des paramètres de chaîne de requête "&"


Et voici ce que vous récupérez:

   time_namelookup:  0.001s
      time_connect:  0.037s
   time_appconnect:  0.000s
  time_pretransfer:  0.037s
     time_redirect:  0.000s
time_starttransfer:  0.092s
                   ----------
        time_total:  0.164s


Créer un raccourci Linux / Mac (alias)

alias curltime="curl -w \"@$HOME/.curl-format.txt\" -o NUL -s "

Ensuite, vous pouvez simplement appeler ...

curltime wordpress.org

Merci au commentateur Pete Doyle!


Créer un script autonome Linux / Mac

Ce script ne nécessite pas de fichier .txt distinct pour contenir la mise en forme.

Créez un nouveau fichier, curltime, quelque part dans votre chemin exécutable, et collez-le:

#!/bin/bash

curl -w @- -o /dev/null -s "$@" <<'EOF'
    time_namelookup:  %{time_namelookup}\n
       time_connect:  %{time_connect}\n
    time_appconnect:  %{time_appconnect}\n
   time_pretransfer:  %{time_pretransfer}\n
      time_redirect:  %{time_redirect}\n
 time_starttransfer:  %{time_starttransfer}\n
                    ----------\n
         time_total:  %{time_total}\n
EOF

Appelez de la même manière que l'alias:

curltime wordpress.org


Créer un raccourci Windows (aka fichier BAT)

Placez cette commande dans CURLTIME.BAT (dans le même dossier que curl.exe)

curl -w "@%~dp0curl-format.txt" -o NUL -s %*

Ensuite, vous pouvez simplement appeler ...

curltime wordpress.org
Simon East
la source
26
réponse géniale. Merci. une chose que je devais faire était d'ajouter \npour briser la ligne dans le fichier texte
Jason Kim
2
Dans le fichier Windows BAT, il n'envoie que le premier paramètre, changez-le pour passer tous les paramètres et désactiver l'écho de la commande elle-même: @curl -w "@%~dp0curl-format.txt" -o NUL -s %*Excellente réponse
padilo
Merci @udoh, j'ai mis à jour la réponse pour l'inclure.
Simon East
excellente réponse. Comment puis-je également inclure la date et l'heure actuelles du moment où la boucle a lancé la demande?
Saqib Ali
4
Pour Linux, j'ai fait un dotfile et un alias et il semble bien fonctionner: alias curltime="curl -w \"@$HOME/.curl-format.txt\" -o NUL -s ". Fonctionne probablement aussi sur MacOS.
Pete Doyle
161

Voici la réponse:

curl -X POST -d @file server:port -w %{time_connect}:%{time_starttransfer}:%{time_total}

Toutes les variables utilisées avec -wse trouvent dans man curl.

sdasdadas
la source
19
Il est préférable pour l'expérience utilisateur d'ajouter de nouvelles lignes:"\n%{time_connect}:%{time_starttransfer}:%{time_total}\n"
1
Pour moi, cela ne fonctionnait pas sans guillemets. Je suggère d'ajouter des guillemets tout en spécifiant le format / h / a / c / haproxy # ❯❯❯ curl -w "% {time_total} \ n" google.com -o / dev / null -s 0,055
Geek
@Geek Il est généralement judicieux d'afficher des erreurs lors d'un fonctionnement en mode silencieux ( -sS).
x-yuri
139

Option 1. Pour mesurer total time:

curl -o /dev/null -s -w 'Total: %{time_total}s\n'  https://www.google.com

Exemple de sortie:

entrez la description de l'image ici

Option 2. Pour obtenir time to establish connection, TTFB: time to first byteet total time:

curl -o /dev/null -s -w 'Establish Connection: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n'  https://www.google.com

Exemple de sortie:

entrez la description de l'image ici

Ref: Obtenez le temps de réponse avec curl

Tho
la source
53

Un raccourci que vous pouvez ajouter à votre .bashrc, etc., basé sur d'autres réponses ici:

function perf {
  curl -o /dev/null -s -w "%{time_connect} + %{time_starttransfer} = %{time_total}\n" "$1"
}

Usage:

> perf stackoverflow.com
0.521 + 0.686 = 1.290
mahemoff
la source
5
J'utilise une variation qui affiche le nombre d'octets téléchargés pendant le temps mesuré:curl -o /dev/null -s -w "time_total: %{time_total} sec\nsize_download: %{size_download} bytes\n" https://www.google.com
jambroseclarke
39

Ce qui suit est inspiré par la réponse de Simon. Il est autonome (ne nécessite pas de fichier de format séparé), ce qui le rend idéal pour l'inclusion dans .bashrc.

curl_time() {
    curl -so /dev/null -w "\
   namelookup:  %{time_namelookup}s\n\
      connect:  %{time_connect}s\n\
   appconnect:  %{time_appconnect}s\n\
  pretransfer:  %{time_pretransfer}s\n\
     redirect:  %{time_redirect}s\n\
starttransfer:  %{time_starttransfer}s\n\
-------------------------\n\
        total:  %{time_total}s\n" "$@"
}

De plus, il devrait fonctionner avec tous les arguments qui curlprennent normalement, car le "$@"passe juste à travers. Par exemple, vous pouvez faire:

curl_time -X POST -H "Content-Type: application/json" -d '{"key": "val"}' https://postman-echo.com/post

Production:

   namelookup:  0,125000s
      connect:  0,250000s
   appconnect:  0,609000s
  pretransfer:  0,609000s
     redirect:  0,000000s
starttransfer:  0,719000s
-------------------------
        total:  0,719000s
Konstantin
la source
34

Si vous souhaitez analyser ou résumer la latence, vous pouvez essayer apache bench:

ab -n [number of samples] [url]

Par exemple:

ab -n 100 http://www.google.com/

Il montrera:

This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.google.com (be patient).....done


Server Software:        gws
Server Hostname:        www.google.com
Server Port:            80

Document Path:          /
Document Length:        12419 bytes

Concurrency Level:      1
Time taken for tests:   10.700 seconds
Complete requests:      100
Failed requests:        97
   (Connect: 0, Receive: 0, Length: 97, Exceptions: 0)
Total transferred:      1331107 bytes
HTML transferred:       1268293 bytes
Requests per second:    9.35 [#/sec] (mean)
Time per request:       107.004 [ms] (mean)
Time per request:       107.004 [ms] (mean, across all concurrent requests)
Transfer rate:          121.48 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       20   22   0.8     22      26
Processing:    59   85 108.7     68     911
Waiting:       59   85 108.7     67     910
Total:         80  107 108.8     90     932

Percentage of the requests served within a certain time (ms)
  50%     90
  66%     91
  75%     93
  80%     95
  90%    105
  95%    111
  98%    773
  99%    932
 100%    932 (longest request)
Andong Zhan
la source
1
beaucoup plus simple que les autres réponses. Totalement oublié cette commande!
FacePalm
Ceci est une réponse fantastique. Et abaccepte facilement un grand nombre des mêmes indicateurs que curlpar exemple -Hpour les en-têtes. J'ai utilisé cette commande pour comparer les temps de réponse d'une API tierce (en fournissant le jeton au porteur dans un en-tête d'autorisation). Fonctionne avec brio.
tsamb
21

Une autre façon est de configurer ~/.curlrccomme ceci

-w "\n\n==== cURL measurements stats ====\ntotal: %{time_total} seconds \nsize: %{size_download} bytes \ndnslookup: %{time_namelookup} seconds \nconnect: %{time_connect} seconds \nappconnect: %{time_appconnect} seconds \nredirect: %{time_redirect} seconds \npretransfer: %{time_pretransfer} seconds \nstarttransfer: %{time_starttransfer} seconds \ndownloadspeed: %{speed_download} byte/sec \nuploadspeed: %{speed_upload} byte/sec \n\n"

Ainsi, la sortie de curlest

❯❯ curl -I https://google.com
HTTP/2 301
location: https://www.google.com/
content-type: text/html; charset=UTF-8
date: Mon, 04 Mar 2019 08:02:43 GMT
expires: Wed, 03 Apr 2019 08:02:43 GMT
cache-control: public, max-age=2592000
server: gws
content-length: 220
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
alt-svc: quic=":443"; ma=2592000; v="44,43,39"



==== cURL measurements stats ====
total: 0.211117 seconds
size: 0 bytes
dnslookup: 0.067179 seconds
connect: 0.098817 seconds
appconnect: 0.176232 seconds
redirect: 0.000000 seconds
pretransfer: 0.176438 seconds
starttransfer: 0.209634 seconds
downloadspeed: 0.000 byte/sec
uploadspeed: 0.000 byte/sec
Hieu Huynh
la source
Pourriez-vous me montrer la référence à des documents plus détaillés à ce sujet?
Trần Đức Tâm
@ TrầnĐứcTâm détails dans le livre officiel de curl ec.haxx.se/usingcurl-writeout.html
Hieu Huynh
10

Hey c'est mieux qu'Apache Bench, a moins de problèmes avec SSL

./hey https://google.com -more
Summary:
  Total:    3.0960 secs
  Slowest:  1.6052 secs
  Fastest:  0.4063 secs
  Average:  0.6773 secs
  Requests/sec: 64.5992

Response time histogram:
  0.406 [1] |
  0.526 [142]   |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
  0.646 [1] |
  0.766 [6] |∎∎
  0.886 [0] |
  1.006 [0] |
  1.126 [0] |
  1.246 [12]    |∎∎∎
  1.365 [32]    |∎∎∎∎∎∎∎∎∎
  1.485 [5] |∎
  1.605 [1] |

Latency distribution:
  10% in 0.4265 secs
  25% in 0.4505 secs
  50% in 0.4838 secs
  75% in 1.2181 secs
  90% in 1.2869 secs
  95% in 1.3384 secs
  99% in 1.4085 secs

Details (average, fastest, slowest):
  DNS+dialup:    0.1150 secs, 0.0000 secs, 0.4849 secs
  DNS-lookup:    0.0032 secs, 0.0000 secs, 0.0319 secs
  req write:     0.0001 secs, 0.0000 secs, 0.0007 secs
  resp wait:     0.2068 secs, 0.1690 secs, 0.4906 secs
  resp read:     0.0117 secs, 0.0011 secs, 0.2375 secs

Status code distribution:
  [200] 200 responses

Références

Jonathan
la source
9

Une autre option qui est peut-être la plus simple en termes de ligne de commande est d'ajouter l' --trace-timeoption intégrée :

curl -X POST -d @file server:port --trace-time

Même s'il ne produit pas techniquement les timings des différentes étapes comme demandé par l'OP, il affiche les horodatages pour toutes les étapes de la demande comme indiqué ci-dessous. En utilisant cela, vous pouvez (assez facilement) calculer combien de temps chaque étape a pris.

$ curl https://www.google.com --trace-time -v -o /dev/null
13:29:11.148734 * Rebuilt URL to: https://www.google.com/
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     013:29:11.149958 *   Trying 172.217.20.36...
13:29:11.149993 * TCP_NODELAY set
13:29:11.163177 * Connected to www.google.com (172.217.20.36) port 443 (#0)
13:29:11.164768 * ALPN, offering h2
13:29:11.164804 * ALPN, offering http/1.1
13:29:11.164833 * successfully set certificate verify locations:
13:29:11.164863 *   CAfile: none
  CApath: /etc/ssl/certs
13:29:11.165046 } [5 bytes data]
13:29:11.165099 * (304) (OUT), TLS handshake, Client hello (1):
13:29:11.165128 } [512 bytes data]
13:29:11.189518 * (304) (IN), TLS handshake, Server hello (2):
13:29:11.189537 { [100 bytes data]
13:29:11.189628 * TLSv1.2 (IN), TLS handshake, Certificate (11):
13:29:11.189658 { [2104 bytes data]
13:29:11.190243 * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
13:29:11.190277 { [115 bytes data]
13:29:11.190507 * TLSv1.2 (IN), TLS handshake, Server finished (14):
13:29:11.190539 { [4 bytes data]
13:29:11.190770 * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
13:29:11.190797 } [37 bytes data]
13:29:11.190890 * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
13:29:11.190915 } [1 bytes data]
13:29:11.191023 * TLSv1.2 (OUT), TLS handshake, Finished (20):
13:29:11.191053 } [16 bytes data]
13:29:11.204324 * TLSv1.2 (IN), TLS handshake, Finished (20):
13:29:11.204358 { [16 bytes data]
13:29:11.204417 * SSL connection using TLSv1.2 / ECDHE-ECDSA-CHACHA20-POLY1305
13:29:11.204451 * ALPN, server accepted to use h2
13:29:11.204483 * Server certificate:
13:29:11.204520 *  subject: C=US; ST=California; L=Mountain View; O=Google LLC; CN=www.google.com
13:29:11.204555 *  start date: Oct  2 07:29:00 2018 GMT
13:29:11.204585 *  expire date: Dec 25 07:29:00 2018 GMT
13:29:11.204623 *  subjectAltName: host "www.google.com" matched cert's "www.google.com"
13:29:11.204663 *  issuer: C=US; O=Google Trust Services; CN=Google Internet Authority G3
13:29:11.204701 *  SSL certificate verify ok.
13:29:11.204754 * Using HTTP2, server supports multi-use
13:29:11.204795 * Connection state changed (HTTP/2 confirmed)
13:29:11.204840 * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
13:29:11.204881 } [5 bytes data]
13:29:11.204983 * Using Stream ID: 1 (easy handle 0x55846ef24520)
13:29:11.205034 } [5 bytes data]
13:29:11.205104 > GET / HTTP/2
13:29:11.205104 > Host: www.google.com
13:29:11.205104 > User-Agent: curl/7.61.0
13:29:11.205104 > Accept: */*
13:29:11.205104 > 
13:29:11.218116 { [5 bytes data]
13:29:11.218173 * Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
13:29:11.218211 } [5 bytes data]
13:29:11.251936 < HTTP/2 200 
13:29:11.251962 < date: Fri, 19 Oct 2018 10:29:11 GMT
13:29:11.251998 < expires: -1
13:29:11.252046 < cache-control: private, max-age=0
13:29:11.252085 < content-type: text/html; charset=ISO-8859-1
13:29:11.252119 < p3p: CP="This is not a P3P policy! See g.co/p3phelp for more info."
13:29:11.252160 < server: gws
13:29:11.252198 < x-xss-protection: 1; mode=block
13:29:11.252228 < x-frame-options: SAMEORIGIN
13:29:11.252262 < set-cookie: 1P_JAR=2018-10-19-10; expires=Sun, 18-Nov-2018 10:29:11 GMT; path=/; domain=.google.com
13:29:11.252297 < set-cookie: NID=141=pzXxp1jrJmLwFVl9bLMPFdGCtG8ySQKxB2rlDWgerrKJeXxfdmB1HhJ1UXzX-OaFQcnR1A9LKYxi__PWMigjMBQHmI3xkU53LI_TsYRbkMNJNdxs-caQQ7fEcDGE694S; expires=Sat, 20-Apr-2019 10:29:11 GMT; path=/; domain=.google.com; HttpOnly
13:29:11.252336 < alt-svc: quic=":443"; ma=2592000; v="44,43,39,35"
13:29:11.252368 < accept-ranges: none
13:29:11.252408 < vary: Accept-Encoding
13:29:11.252438 < 
13:29:11.252473 { [5 bytes data]
100 12215    0 12215    0     0   112k      0 --:--:-- --:--:-- --:--:--  112k
13:29:11.255674 * Connection #0 to host www.google.com left intact
Per Lundberg
la source
C'est en fait une excellente réponse qui va probablement s'adapter à la plupart des cas d'utilisation que les gens recherchent ici. Les autres réponses sont idéales pour des solutions approfondies et approfondies, mais cela est bon pour vérifier rapidement les temps d'aller-retour.
Chris Vandevelde
Merci @ChrisVandevelde. Oui, je savais qu'il y avait "quelque chose" comme ça (j'avais déjà utilisé ce paramètre auparavant), puis j'ai fait une recherche sur ce poste SO et j'ai trouvé la forme la plus sophistiquée, mais ... j'avais le sentiment qu'il y avait une autre façon aussi . :) Comme vous le dites, c'est plutôt simple dans sa simplicité et c'est parfois assez bien pour des cas d'utilisation plus simples.
Par Lundberg
8

curl -v --trace-time Cela doit être fait en mode verbeux

PAUL SSEMAKULA
la source
4

voici la chaîne que vous pouvez utiliser -w, contient toutes les options prises en curl -wcharge.

{"contentType":"%{content_type}","filenameEffective":"%{filename_effective}","ftpEntryPath":"%{ftp_entry_path}","httpCode":"%{http_code}","httpConnect":"%{http_connect}","httpVersion":"%{http_version}","localIp":"%{local_ip}","localPort":"%{local_port}","numConnects":"%{num_connects}","numRedirects":"%{num_redirects}","proxySslVerifyResult":"%{proxy_ssl_verify_result}","redirectUrl":"%{redirect_url}","remoteIp":"%{remote_ip}","remotePort":"%{remote_port}","scheme":"%{scheme}","size":{"download":"%{size_download}","header":"%{size_header}","request":"%{size_request}","upload":"%{size_upload}"},"speed":{"download":"%{speed_download}","upload":"%{speed_upload}"},"sslVerifyResult":"%{ssl_verify_result}","time":{"appconnect":"%{time_appconnect}","connect":"%{time_connect}","namelookup":"%{time_namelookup}","pretransfer":"%{time_pretransfer}","redirect":"%{time_redirect}","starttransfer":"%{time_starttransfer}","total":"%{time_total}"},"urlEffective":"%{url_effective}"}

sorties JSON.

ATilara
la source
La prépension \naide à séparer le moment où le corps ne se termine pas avec la nouvelle ligne:curl -w '\n{"contentType":"..."}...
Beni Cherniavsky-Paskin
2

Voici un one-liner Bash pour frapper le même serveur à plusieurs reprises:

for i in {1..1000}; do curl -s -o /dev/null -w "%{time_total}\n" http://server/get_things; done
Lucas
la source
0

Il s'agit d'une version modifiée de la réponse Simons qui fait de la sortie multiligne une seule ligne. Il présente également l'horodatage actuel afin qu'il soit plus facile de suivre chaque ligne de sortie.

Exemple de format de fichier
$ cat time-format.txt
time_namelookup:%{time_namelookup} time_connect:%{time_connect} time_appconnect:%{time_appconnect} time_pretransfer:%{time_pretransfer} time_redirect:%{time_redirect} time_starttransfer:%{time_starttransfer} time_total:%{time_total}\n
exemple cmd
$ while [ 1 ];do echo -n "$(date) - " ; curl -w @curl-format.txt -o /dev/null -s https://myapp.mydom.com/v1/endpt-http; sleep 1; done | grep -v time_total:0
résultats
Mon Dec 16 17:51:47 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:0.172 time_pretransfer:0.172 time_redirect:0.000 time_starttransfer:1.666 time_total:1.666
Mon Dec 16 17:51:50 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:0.175 time_pretransfer:0.175 time_redirect:0.000 time_starttransfer:3.794 time_total:3.795
Mon Dec 16 17:51:55 UTC 2019 - time_namelookup:0.004 time_connect:0.017 time_appconnect:0.175 time_pretransfer:0.175 time_redirect:0.000 time_starttransfer:1.971 time_total:1.971
Mon Dec 16 17:51:58 UTC 2019 - time_namelookup:0.004 time_connect:0.014 time_appconnect:0.173 time_pretransfer:0.173 time_redirect:0.000 time_starttransfer:1.161 time_total:1.161
Mon Dec 16 17:52:00 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:0.166 time_pretransfer:0.167 time_redirect:0.000 time_starttransfer:1.434 time_total:1.434
Mon Dec 16 17:52:02 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:0.177 time_pretransfer:0.177 time_redirect:0.000 time_starttransfer:5.119 time_total:5.119
Mon Dec 16 17:52:08 UTC 2019 - time_namelookup:0.004 time_connect:0.014 time_appconnect:0.172 time_pretransfer:0.172 time_redirect:0.000 time_starttransfer:30.185 time_total:30.185
Mon Dec 16 17:52:39 UTC 2019 - time_namelookup:0.004 time_connect:0.014 time_appconnect:0.164 time_pretransfer:0.164 time_redirect:0.000 time_starttransfer:30.175 time_total:30.176
Mon Dec 16 17:54:28 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:3.191 time_pretransfer:3.191 time_redirect:0.000 time_starttransfer:3.212 time_total:3.212
Mon Dec 16 17:56:08 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:1.184 time_pretransfer:1.184 time_redirect:0.000 time_starttransfer:1.215 time_total:1.215
Mon Dec 16 18:00:24 UTC 2019 - time_namelookup:0.004 time_connect:0.015 time_appconnect:0.181 time_pretransfer:0.181 time_redirect:0.000 time_starttransfer:1.267 time_total:1.267

J'ai utilisé ce qui précède pour capturer des réponses lentes sur le point final ci-dessus.

slm
la source