-
Dynamic flags: fortio.org/dflag -
Logger: fortio.org/log - now using structured JSON logs for servers (vs text for CLIs) since fortio 1.55 / log 1.4. In color since fortio 1.57 / log 1.6. -
Version helper: fortio.org/version -
CLI helpers integrating the above to reduce toil making new tools fortio.org/cli and servers fortio.org/scli for arguments, flags, usage, dynamic config, etc...
docker run -p 8080:8080 -p 8079:8079 fortio/fortio server & # For the server docker run fortio/fortio load -logger-force-color http://www.google.com/ # For a test run, forcing color instead of JSON log output
-
Install go (golang 1.18 or later) go install fortio.org/ fortio@latest -
you can now run fortio (from your gopath bin/ directory, usually ~/go/bin )
curl -L https://github.com/fortio/fortio/releases/download/v1.63.10/fortio-linux_amd64-1.63.10.tgz \ | sudo tar -C / -xvzpf - # or the debian package wget https://github.com/fortio/fortio/releases/download/v1.63.10/fortio_1.63.10_amd64.deb dpkg -i fortio_1.63.10_amd64.deb # or the rpm rpm -i https://github.com/fortio/fortio/releases/download/v1.63.10/fortio-1.63.10-1.x86_64.rpm # and more, see assets in release page
brew install fortio
fortio.exe server
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Φορτίο 1.63.10 usage: fortio command [flags] target where command is one of: load (load testing), server (starts ui, rest api, http-echo, redirect, proxies, tcp-echo, udp-echo and grpc ping servers), tcp-echo (only the tcp-echo server), udp-echo (only udp-echo server), report (report only UI server), redirect (only the redirect server), proxies (only the -M and -P configured proxies), grpcping (grpc client), or curl (single URL debug), or nc (single tcp or udp:// connection), or version (prints the full version and build details). where target is a url (http load tests) or host:port (grpc health test), or tcp://host:port (tcp load test), or udp://host:port (udp load test). or 1 of the special arguments fortio {help|envhelp|version|buildinfo} flags: -H key:value Additional http header(s) or grpc metadata. Multiple key:value pairs can be passed using multiple -H. -L Follow redirects (implies -std-client) - do not use for load test -M value Http multi proxy to run, e.g -M "localport1 baseDestURL1 baseDestURL2" -M ... -P value Tcp proxies to run, e.g -P "localport1 dest_host1:dest_port1" -P "[::1]:0 www.google.com:443" ... -X string HTTP method to use instead of GET/POST depending on payload/content-type -a Automatically save JSON result with filename based on labels & timestamp -abort-on code Http code that if encountered aborts the run. e.g. 503 or -1 for socket errors. -access-log-file path file path to log all requests to. Maybe have performance impacts -access-log-format format format for access log. Supported values: [json, influx] (default "json") -allow-initial-errors Allow and don't abort on initial warmup errors -base-url URL base URL used as prefix for data/index.tsv generation. (when empty, the url from the first request is used) -c int Number of connections/goroutine/threads (default 4) -cacert Path Path to a custom CA certificate file to be used for the TLS client connections, if empty, use https:// prefix for standard internet/system CAs -calc-qps Calculate the qps based on number of requests (-n) and duration (-t) -cert Path Path to the certificate file to be used for client or server TLS -compression Enable http compression -config-dir directory Config directory to watch for dynamic flag changes -config-port port Config port to open for dynamic flag UI/api -connection-reuse min:max Range min:max for the max number of connections to reuse for each thread, default to unlimited. e.g. 10:30 means randomly choose a max connection reuse threshold between 10 and 30 requests. -content-type string Sets http content type. Setting this value switches the request method from GET to POST. -curl Just fetch the content once -curl-stdout-headers Restore pre 1.22 behavior where http headers of the fast client are output to stdout in curl mode. now stderr by default. -data-dir Directory Directory where JSON results are stored/read (default ".") -dns-method method When a name resolves to multiple ip, which method to pick: cached-rr for cached round robin, rnd for random, first for first answer (pre 1.30 behavior), rr for round robin. (default cached-rr) -echo-debug-path URI http echo server URI for debug, empty turns off that part (more secure) (default "/debug") -echo-server-default-params value Default parameters/querystring to use if there isn't one provided explicitly. E.g "status=404&delay=3s" -gomaxprocs int Setting for runtime.GOMAXPROCS, <1 doesn't change the default -grpc Use GRPC (health check by default, add -ping for ping) for load testing -grpc-compression Enable grpc compression -grpc-max-streams uint MaxConcurrentStreams for the grpc server. Default (0) is to leave the option unset. -grpc-ping-delay duration grpc ping delay in response -grpc-port port grpc server port. Can be in the form of host:port, ip:port or port or /unix/domain/path or "disabled" to not start the grpc server. (default "8079") -h2 Attempt to use http2.0 / h2 (instead of http 1.1) for both TLS and h2c -halfclose When not keepalive, whether to half close the connection (only for fast http) -health grpc ping client mode: use health instead of ping -healthservice string which service string to pass to health check -http-port port http echo server port. Can be in the form of host:port, ip:port, port or /unix/domain/path or "disabled". (default "8080") -http1.0 Use http1.0 (instead of http 1.1) -httpbufferkb kbytes Size of the buffer (max data size) for the optimized http client in kbytes (default 128) -httpccch Check for Connection: Close Header -https-insecure Long form of the -k flag -jitter set to true to de-synchronize parallel clients' by 10% -json path Json output to provided file path or '-' for stdout (empty = no json output, unless -a is used) -k Do not verify certs in https/tls/grpc connections -keepalive Keep connection alive (only for fast http 1.1) (default true) -key Path Path to the key file matching the -cert -labels string Additional config data/labels to add to the resulting JSON, defaults to target URL and hostname -log-errors Log http non 2xx/418 error codes as they occur (default true) -logger-file-line Filename and line numbers emitted in JSON logs, use -logger-file-line=false to disable (default true) -logger-force-color Force color output even if stderr isn't a terminal -logger-goroutine GoroutineID emitted in JSON/color logs, use -logger-goroutine=false to disable (default true) -logger-json Log in JSON format, use -logger-json=false to disable (default true) -logger-no-color Prevent colorized output even if stderr is a terminal -logger-timestamp Timestamps emitted in JSON logs, use -logger-timestamp=false to disable (default true) -loglevel level log level, one of [Debug Verbose Info Warning Error Critical Fatal] (default Info) -max-echo-delay value Maximum sleep time for delay= echo server parameter. dynamic flag. (default 1.5s) -maxpayloadsizekb Kbytes MaxPayloadSize is the maximum size of payload to be generated by the EchoHandler size= argument. In Kbytes. (default 256) -mtls Require client certificate signed by -cacert for client connections -multi-mirror-origin Mirror the request url to the target for multi proxies (-M) (default true) -multi-serial-mode Multi server (-M) requests one at a time instead of parallel mode -n int Run for exactly this number of calls instead of duration. Default (0) is to use duration (-t). Default is 1 when used as grpc ping count. -nc-dont-stop-on-eof in netcat (nc) mode, don't abort as soon as remote side closes -no-reresolve Keep the initial DNS resolution and don't re-resolve when making new connections (because of error or reuse limit reached) -nocatchup set to exact fixed qps and prevent fortio from trying to catchup when the target fails to keep up temporarily -offset duration Offset of the histogram data -p string List of pXX to calculate (default "50,75,90,99,99.9") -payload string Payload string to send along -payload-file path File path to be use as payload (POST for http), replaces -payload when set. -payload-size int Additional random payload size, replaces -payload when set > 0, must be smaller than -maxpayloadsizekb. Setting this switches http to POST. -ping grpc load test: use ping instead of health -pprof Enable pprof http endpoint in the Web UI handler server -profile file write .cpu and .mem profiles to file -proxy-all-headers Determines if only tracing or all headers (and cookies) are copied from request on the fetch2 ui/server endpoint (default true) -qps float Queries Per Seconds or 0 for no wait/max qps (default 8) -quiet Quiet mode, sets loglevel to Error (quietly) to reduces the output -r float Resolution of the histogram lowest buckets in seconds (default 0.001) -redirect-port port Redirect all incoming traffic to https URL (need ingress to work properly). Can be in the form of host:port, ip:port, port or "disabled" to disable the feature. (default "8081") -resolve IP Resolve host name to this IP -resolve-ip-type type Resolve type: ip4 for ipv4, ip6 for ipv6 only, use ip for both (default ip4) -runid int Optional RunID to add to json result and auto save filename, to match server mode -s int Number of streams per grpc connection (default 1) -sequential-warmup http(s) runner warmup done sequentially instead of parallel. When set, restores pre 1.21 behavior -server-idle-timeout value Default IdleTimeout for servers (default 30s) -static-dir path Deprecated/unused path. -stdclient Use the slower net/http standard client (slower but supports h2/h2c) -stream Stream payload from stdin (only for fortio curl mode) -sync URL index.tsv or s3/gcs bucket xml URL to fetch at startup for server modes. -sync-interval duration Refresh the url every given interval (default, no refresh) -t duration How long to run the test or 0 to run until ^C (default 5s) -tcp-port port tcp echo server port. Can be in the form of host:port, ip:port, port or /unix/domain/path or "disabled". (default "8078") -timeout duration Connection and read timeout value (for http) (default 3s) -udp-async if true, udp echo server will use separate go routine to reply -udp-port port udp echo server port. Can be in the form of host:port, ip:port, port or "disabled". (default "8078") -udp-timeout duration Udp timeout (default 750ms) -ui-path URI http server URI for UI, empty turns off that part (more secure) (default "/fortio/") -uniform set to true to de-synchronize parallel clients' requests uniformly -unix-socket path Unix domain socket path to use for physical connection -user user:password User credentials for basic authentication (for http). Input data format should be user:password
-
A simple echo server which will echo back posted data (for any path not mentioned below). For instance curl -d abcdef http://localhost:8080/ returns abcdef back. It supports the following optional query argument parameters:
|
|
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
-
/debug will echo back the request in plain text for human debugging. -
/fortio/ A UI to -
Run/Trigger tests and graph the results. -
A UI to browse saved results and single graph or multi graph them (comparative graph of min, avg, median, p75, p99, p99.9 and max). -
Proxy/fetch other URLs. /fortio/data/index.tsv an tab separated value file conforming to Google cloud storage URL list data transfer format so you can export/backup local results to the cloud. -
Download/sync peer to peer JSON results files from other Fortio servers (using their index.tsv URLs). -
Download/sync from an Amazon S3 or Google Cloud compatible bucket listings XML URLs .
-
-
API to trigger and cancel runs from the running server (like the form ui but more directly and with async=on option) /fortio/rest/run starts a run; the arguments are either from the command line or from POSTed JSON; jsonPath can be provided to look for in a subset of the json object, for instance jsonPath=metadata allows to use the flagger webhook meta data for fortio run parameters (see Remote Triggered load test section below ). /fortio/rest/stop stops all current run or by run id (passing runid= query argument). /fortio/rest/status lists the current runs (or the options of a single one if runid is passed).
-
DNS api for troubleshooting latency based records / view of the DNS where fortio server is running. /fortio/rest/dns? name=x resolves all the IPs for x .
$ fortio server & Fortio X.Y.Z tcp-echo server listening on tcp [::]:8078 Fortio X.Y.Z udp-echo server listening on udp [::]:8078 Fortio X.Y.Z grpc ' ping ' server listening on tcp [::]:8079 Fortio X.Y.Z https redirector server listening on tcp [::]:8081 Fortio X.Y.Z http-echo server listening on tcp [::]:8080 Data directory is /Users/ldemailly/dev/fortio REST API on /fortio/rest/run, /fortio/rest/status, /fortio/rest/stop, /fortio/rest/dns Debug endpoint on /debug, Additional Echo on /debug/echo/, Flags on /fortio/flags, and Metrics on /debug/metrics UI started - visit: http://localhost:8080/fortio/ (or any host/ip reachable on this server) I fortio_main.go: 285> Note: not using dynamic flag watching (use -config to set watch directory) I fortio_main.go: 293> All fortio X.Y.Z goM.m.p arm64 darwin servers started !
$ fortio server -http-port 10.10.10.10:8088 UI starting - visit: http://10.10.10.10:8088/fortio/ Https redirector running on :8081 Fortio X.Y.Z grpc ping server listening on port :8079 Fortio X.Y.Z echo server listening on port 10.10.10.10:8088
$ fortio server --http-port /tmp/fortio-uds-http & Fortio X.Y.Z grpc ' ping ' server listening on [::]:8079 Fortio X.Y.Z https redirector server listening on [::]:8081 Fortio X.Y.Z echo server listening on /tmp/fortio-uds-http UI started - visit: fortio curl -unix-socket=/tmp/fortio-uds-http http://localhost/fortio/ 14:58:45 I fortio_main.go: 217> All fortio X.Y.Z unknown goM.m.p servers started ! $ fortio curl -unix-socket=/tmp/fortio-uds-http http://foo.bar/debug 15:00:48 I http_client.go: 428> Using unix domain socket /tmp/fortio-uds-http instead of foo.bar http HTTP/1.1 200 OK Content-Type: text/plain ; charset=UTF-8 Date: Wed, 08 Aug 2018 22:00:48 GMT Content-Length: 231 Φορτίο version X.Y.Z unknown goM.m.p echo debug server up for 2m3.4s on ldemailly-macbookpro - request from GET /debug HTTP/1.1 headers: Host: foo.bar User-Agent: fortio.org/fortio-X.Y.Z body:
$ fortio tcp-echo & Fortio X.Y.Z tcp-echo TCP server listening on [::]:8078 19:45:30 I fortio_main.go: 238> All fortio X.Y.Z release goM.m.p servers started ! $ fortio load -qps -1 -n 100000 tcp://localhost:8078 Fortio X.Y.Z running at -1 queries per second, 16- > 16 procs, for 100000 calls: tcp://localhost:8078 20:01:31 I tcprunner.go: 218> Starting tcp test for tcp://localhost:8078 with 4 threads at -1.0 qps Starting at max qps with 4 thread(s) [gomax 16] for exactly 100000 calls (25000 per thread + 0) 20:01:32 I periodic.go: 558> T003 ended after 1.240585427s : 25000 calls. qps=20151.77629520873 20:01:32 I periodic.go: 558> T002 ended after 1.241141084s : 25000 calls. qps=20142.75437521493 20:01:32 I periodic.go: 558> T001 ended after 1.242066385s : 25000 calls. qps=20127.7486468648 20:01:32 I periodic.go: 558> T000 ended after 1.24227731s : 25000 calls. qps=20124.331176909283 Ended after 1.242312567s : 100000 calls. qps=80495 Aggregated Function Time : count 100000 avg 4.9404876e-05 +/- 1.145e-05 min 2.7697e-05 max 0.000887051 sum 4.94048763 # range, mid point, percentile, count
> = 2.7697e-05 < = 0.000887051 , 0.000457374 , 100.00, 100000 # target 50% 0.00045737
# target 75% 0.00067221
# target 90% 0.000801115
# target 99% 0.000878457
# target 99.9% 0.000886192 Sockets used: 4 (for perfect no error run, would be 4) Total Bytes sent: 2400000, received: 2400000 tcp OK : 100000 (100.0 %) All done 100000 calls (plus 0 warmup) 0.049 ms avg, 80495.0 qps
$ fortio udp-echo & Fortio X.Y.Z udp-echo UDP server listening on [::]:8078 21:54:52 I fortio_main.go:273> Note: not using dynamic flag watching (use -config to set watch directory) 21:54:52 I fortio_main.go:281> All fortio X.Y.Z release goM.m.p servers started! $ fortio load -qps -1 -n 100000 udp://localhost:8078/ Fortio X.Y.Z running at -1 queries per second, 16->16 procs, for 100000 calls: udp://localhost:8078/ 21:56:48 I udprunner.go:222> Starting udp test for udp://localhost:8078/ with 4 threads at -1.0 qps Starting at max qps with 4 thread(s) [gomax 16] for exactly 100000 calls (25000 per thread + 0) 21:56:49 I periodic.go:558> T003 ended after 969.635695ms : 25000 calls. qps=25782.879208051432 21:56:49 I periodic.go:558> T000 ended after 969.906228ms : 25000 calls. qps=25775.687667818544 21:56:49 I periodic.go:558> T002 ended after 970.543935ms : 25000 calls. qps=25758.751457243405 21:56:49 I periodic.go:558> T001 ended after 970.737665ms : 25000 calls. qps=25753.610786287973 Ended after 970.755702ms : 100000 calls. qps=1.0301e+05 Aggregated Function Time : count 100000 avg 3.8532238e-05 +/- 1.7e-05 min 2.0053e-05 max 0.000881827 sum 3.85322376 # range, mid point, percentile, count >= 2.0053e-05 <= 0.000881827 , 0.00045094 , 100.00, 100000 # target 50% 0.000450936 # target 75% 0.000666381 # target 90% 0.000795649 # target 99% 0.000873209 # target 99.9% 0.000880965 Sockets used: 4 (for perfect no error run, would be 4) Total Bytes sent: 2400000, received: 2400000 udp OK : 100000 (100.0 %) All done 100000 calls (plus 0 warmup) 0.039 ms avg, 103012.5 qps
$ fortio grpcping -n 5 localhost 22:36:55 I pingsrv.go: 150> Ping RTT 212000 (avg of 259000, 217000, 160000 ns) clock skew -10500 22:36:55 I pingsrv.go: 150> Ping RTT 134333 (avg of 170000, 124000, 109000 ns) clock skew 5000 22:36:55 I pingsrv.go: 150> Ping RTT 112000 (avg of 111000, 122000, 103000 ns) clock skew 5000 22:36:55 I pingsrv.go: 150> Ping RTT 157000 (avg of 136000, 158000, 177000 ns) clock skew 6000 22:36:55 I pingsrv.go: 150> Ping RTT 108333 (avg of 118000, 106000, 101000 ns) clock skew 1000 Clock skew histogram usec : count 5 avg 1.3 +/- 6.145 min -10.5 max 6 sum 6.5 # range, mid point, percentile, count
> = -10.5 < = -10 , -10.25 , 20.00, 1 > zero < = 2 , 1 , 40.00, 1 > four < = 6 , 5 , 100.00, 3 # target 50% 4.33333 RTT histogram usec : count 15 avg 144.73333 +/- 44.48 min 101 max 259 sum 2171 # range, mid point, percentile, count
> = 101 < = 110 , 105.5 , 26.67, 4 > one hundred and ten < = 120 , 115 , 40.00, 2 > one hundred and twenty < = 140 , 130 , 60.00, 3 > one hundred and forty < = 160 , 150 , 73.33, 2 > one hundred and sixty < = 180 , 170 , 86.67, 2 > two hundred < = 250 , 225 , 93.33, 1 > two hundred and fifty < = 259 , 254.5 , 100.00, 1 # target 50% 130
$ fortio grpcping 10.10.10.100:8078 # Connects to gRPC server 10.10.10.100 listening on port 8078 02:29:27 I pingsrv.go: 116> Ping RTT 305334 (avg of 342970, 293515, 279517 ns) clock skew -2137 Clock skew histogram usec : count 1 avg -2.137 +/- 0 min -2.137 max -2.137 sum -2.137 # range, mid point, percentile, count
> = -4 < -2 , -3 , 100.00, 1 # target 50% -2.137 RTT histogram usec : count 3 avg 305.334 +/- 27.22 min 279.517 max 342.97 sum 916.002 # range, mid point, percentile, count
> = 250 < 300 , 275 , 66.67, 2 > = 300 < 350 , 325 , 100.00, 1 # target 50% 294.879
-
First, start Fortio server with the -cert and -key flags:
$ fortio server -cert /path/to/fortio/server.crt -key /path/to/fortio/server.key UI starting - visit: http://localhost:8080/fortio/ Https redirector running on :8081 Fortio X.Y.Z grpc ping server listening on port :8079 Fortio X.Y.Z echo server listening on port localhost:8080 Using server certificate /path/to/fortio/server.crt to construct TLS credentials Using server key /path/to/fortio/server.key to construct TLS credentials
-
Next, use grpcping with the -cacert flag:
$ fortio grpcping -cacert /path/to/fortio/ca.crt localhost Using server certificate /path/to/fortio/ca.crt to construct TLS credentials 16:00:10 I pingsrv.go: 129> Ping RTT 501452 (avg of 595441, 537088, 371828 ns) clock skew 31094 Clock skew histogram usec : count 1 avg 31.094 +/- 0 min 31.094 max 31.094 sum 31.094 # range, mid point, percentile, count
> = 31.094 < = 31.094 , 31.094 , 100.00, 1 # target 50% 31.094 RTT histogram usec : count 3 avg 501.45233 +/- 94.7 min 371.828 max 595.441 sum 1504.357 # range, mid point, percentile, count
> = 371.828 < = 400 , 385.914 , 33.33, 1 > five hundred < = 595.441 , 547.721 , 100.00, 2 # target 50% 523.86
$ fortio grpcping https://grpc.fortio.org 13:48:20 I grpcrunner.go: 276> stripping https scheme. grpc destination: grpc.fortio.org. grpc port: 443 13:48:26 I pingsrv.go: 152> Ping RTT 63101562 (avg of 63577000, 63192688, 62535000 ns) clock skew 32021375 Clock skew histogram usec : count 1 avg 32021.375 +/- 0 min 32021.375 max 32021.375 sum 32021.375 # range, mid point, percentile, count
> = 32021.4 < = 32021.4 , 32021.4 , 100.00, 1 # target 50% 32021.4 RTT histogram usec : count 3 avg 63101.563 +/- 430.2 min 62535 max 63577 sum 189304.688 # range, mid point, percentile, count
> = 62535 < = 63577 , 63056 , 100.00, 3 # target 50% 62795.5
$ fortio load http://www.google.com Fortio X.Y.Z running at 8 queries per second, 8- > 8 procs, for 5s: http://www.google.com 19:10:33 I httprunner.go: 84> Starting http test for http://www.google.com with 4 threads at 8.0 qps Starting at 8 qps with 4 thread(s) [gomax 8] for 5s : 10 calls each (total 40) 19:10:39 I periodic.go: 314> T002 ended after 5.056753279s : 10 calls. qps=1.9775534712220633 19:10:39 I periodic.go: 314> T001 ended after 5.058085991s : 10 calls. qps=1.9770324224999916 19:10:39 I periodic.go: 314> T000 ended after 5.058796046s : 10 calls. qps=1.9767549252963101 19:10:39 I periodic.go: 314> T003 ended after 5.059557593s : 10 calls. qps=1.9764573910247019 Ended after 5.059691387s : 40 calls. qps=7.9056 Sleep times : count 36 avg 0.49175757 +/- 0.007217 min 0.463508712 max 0.502087879 sum 17.7032725 Aggregated Function Time : count 40 avg 0.060587641 +/- 0.006564 min 0.052549016 max 0.089893269 sum 2.42350566 # range, mid point, percentile, count
> = 0.052549 < 0.06 , 0.0562745 , 47.50, 19 > = 0.06 < 0.07 , 0.065 , 92.50, 18 > = 0.07 < 0.08 , 0.075 , 97.50, 2 > = 0.08 < = 0.0898933 , 0.0849466 , 100.00, 1 # target 50% 0.0605556
# target 75% 0.0661111
# target 99% 0.085936
# target 99.9% 0.0894975 Code 200 : forty Response Header Sizes : count 40 avg 690.475 +/- 15.77 min 592 max 693 sum 27619 Response Body/Total Sizes : count 40 avg 12565.2 +/- 301.9 min 12319 max 13665 sum 502608 All done 40 calls (plus 4 warmup) 60.588 ms avg, 7.9 qps
-
plus async query arg or json value "on" will make the run asynchronous (returns just the runid of the run instead of waiting for the result); -
plus read all the run configuration from either query args or jsonPath POSTed info; -
compatible with flagger and other webhooks; -
New in 1.22: use headers json array to send headers (or multiple &H= query args).
$ curl -v -d ' {"metadata": {"url":"localhost:8080", "c":"1", "n":"1", "async":"on", "save":"on"}} ' \ " localhost:8080/fortio/rest/run?jsonPath=.metadata " { " started " : 3}
curl -s -d ' {"url":"localhost:8080"} ' " localhost:8080/fortio/rest/run " | jq
{ "metadata" : { "url" : " localhost:8080 " , "payload" : " foo " , "qps" : " forty " , "c" : " two " , "t" : " 0.1s " , "headers" : [ " Foo:Bar " , " X-Blah: Something else " ], "save" : " on " } }
$ fortio curl -stdclient -payload-file sample.json " http://localhost:8080/fortio/rest/run?jsonPath=.metadata " > result.json
POST / HTTP/1.1 Host: localhost:8080 Content-Length: 3 Content-Type: application/octet-stream Foo: Bar X-Blah: Something else X-On-Behalf-Of: [::1]:62629 foo
{ "RunType" : " HTTP " , "Labels" : " " , "StartTime" : " 2022-03-19T15:34:23.279389-07:00 " , "RequestedQPS" : " forty " , "RequestedDuration" : " 100ms " , "ActualQPS" : thirty-eight point four four eight three six three six one two one seven two six three , "ActualDuration" : one hundred and four million thirty-five thousand six hundred and thirty-seven , "NumThreads" : two , "Version" : " X.Y.Z " , "DurationHistogram" : { "Count" : four , "Min" : zero point zero zero zero two seven two nine two , "Max" : zero point zero zero zero nine three zero four zero seven , "Sum" : zero point zero zero two three three two zero four seven , "Avg" : zero point zero zero zero five eight three zero one one seven five , "StdDev" : 0.00028491034912527755 , "Data" : [ { "Start" : zero point zero zero zero two seven two nine two , "End" : zero point zero zero zero nine three zero four zero seven , "Percent" : one hundred , "Count" : four } ], "Percentiles" : [ { "Percentile" : fifty , "Value" : 0.0004920823333333334 }, { "Percentile" : seventy-five , "Value" : 0.0007112446666666667 }, { "Percentile" : ninety , "Value" : 0.0008427420666666666 }, { "Percentile" : ninety-nine , "Value" : 0.0009216405066666668 }, { "Percentile" : ninety-nine point nine , "Value" : 0.0009295303506666667 } ] }, "Exactly" : zero , "Jitter" : false , "Uniform" : false , "RunID" : seven , "AccessLoggerInfo" : " " , "RetCodes" : { "200" : four }, "URL" : " http://localhost:8080 " , "NumConnections" : one , "Compression" : false , "DisableFastClient" : false , "HTTP10" : false , "DisableKeepAlive" : false , "AllowHalfClose" : false , "Insecure" : false , "FollowRedirects" : false , "CACert" : " " , "Cert" : " " , "Key" : " " , "Resolve" : " " , "HTTPReqTimeOut" : three billion , "UserCredentials" : " " , "ContentType" : " " , "Payload" : " Zm9v " , "UnixDomainSocket" : " " , "LogErrors" : false , "ID" : zero , "SequentialWarmup" : false , "Sizes" : { "Count" : four , "Min" : one hundred and eighteen , "Max" : one hundred and eighteen , "Sum" : four hundred and seventy-two , "Avg" : one hundred and eighteen , "StdDev" : zero , "Data" : [ { "Start" : one hundred and eighteen , "End" : one hundred and eighteen , "Percent" : one hundred , "Count" : four } ], "Percentiles" : null }, "HeaderSizes" : { "Count" : four , "Min" : one hundred and fifteen , "Max" : one hundred and fifteen , "Sum" : four hundred and sixty , "Avg" : one hundred and fifteen , "StdDev" : zero , "Data" : [ { "Start" : one hundred and fifteen , "End" : one hundred and fifteen , "Percent" : one hundred , "Count" : four } ], "Percentiles" : null }, "SocketCount" : two , "AbortOn" : zero }
-
There is also the fortio/rest/stop endpoint to stop a run by its id or all runs if not specified.
$ curl -s localhost:8080/fortio/rest/dns ? name=debug.fortio.org | jq
{ "Name" : " debug.fortio.org " , "IPv4" : [ " 18.222.136.83 " , " 192.9.142.5 " , " 192.9.227.83 " ], "IPv6" : [ " 2600:1f16:9c6:b400:282c:a766:6cab:4e82 " , " 2603:c024:c00a:d144:7cd0:4951:7106:96b8 " , " 2603:c024:c00a:d144:6663:5896:7efb:fbf3 " ] }
$ fortio load -a -grpc -ping -grpc-ping-delay 0.25s -payload " 01234567890 " -c 2 -s 4 https://fortio-stage.istio.io Fortio X.Y.Z running at 8 queries per second, 8- > 8 procs, for 5s: https://fortio-stage.istio.io 16:32:56 I grpcrunner.go: 139> Starting GRPC Ping Delay=250ms PayloadLength=11 test for https://fortio-stage.istio.io with 4 * 2 threads at 8.0 qps 16:32:56 I grpcrunner.go: 261> stripping https scheme. grpc destination: fortio-stage.istio.io. grpc port: 443 16:32:57 I grpcrunner.go: 261> stripping https scheme. grpc destination: fortio-stage.istio.io. grpc port: 443 Starting at 8 qps with 8 thread(s) [gomax 8] for 5s : 5 calls each (total 40) 16:33:04 I periodic.go: 533> T005 ended after 5.283227589s : 5 calls. qps=0.9463911814835126 [...] Ended after 5.28514474s : 40 calls. qps=7.5684 Sleep times : count 32 avg 0.97034752 +/- 0.002338 min 0.967323561 max 0.974838789 sum 31.0511206 Aggregated Function Time : count 40 avg 0.27731944 +/- 0.001606 min 0.2741372 max 0.280604967 sum 11.0927778 # range, mid point, percentile, count
> = 0.274137 < = 0.280605 , 0.277371 , 100.00, 40 # target 50% 0.277288
# target 75% 0.278947
# target 90% 0.279942
# target 99% 0.280539
# target 99.9% 0.280598 Ping SERVING : forty All done 40 calls (plus 2 warmup) 277.319 ms avg, 7.6 qps Successfully wrote 1210 bytes of Json data to 2018-04-03-163258_fortio_stage_istio_io_ldemailly_macbookpro.json
{ "RunType": "GRPC Ping Delay=250ms PayloadLength=11", "Labels": "fortio-stage.istio.io , ldemailly-macbookpro", "StartTime": "2018-04-03T16:32:58.895472681-07:00", "RequestedQPS": "8", "RequestedDuration": "5s", "ActualQPS": 7.568383075162479, "ActualDuration": 5285144740, "NumThreads": 8, "Version": "0.9.0", "DurationHistogram": { "Count": 40, "Min": 0.2741372, "Max": 0.280604967, "Sum": 11.092777797, "Avg": 0.277319444925, "StdDev": 0.0016060870789948905, "Data": [ { "Start": 0.2741372, "End": 0.280604967, "Percent": 100, "Count": 40 } ], "Percentiles": [ { "Percentile": 50, "Value": 0.2772881634102564 }, { "Percentile": 75, "Value": 0.27894656520512817 }, { "Percentile": 90, "Value": 0.2799416062820513 }, { "Percentile": 99, "Value": 0.28053863092820513 }, { "Percentile": 99.9, "Value": 0.2805983333928205 } ] }, "Exactly": 0, "RetCodes": { "1": 40 }, "Destination": " https://fortio-stage.istio.io ", "Streams": 4, "Ping": true }
-
Load test using gRPC and TLS security. First, start Fortio server with the -cert and -key flags:
fortio server -cert /etc/ssl/certs/server.crt -key /etc/ssl/certs/server.key
fortio load -cacert /etc/ssl/certs/ca.crt -grpc localhost:8079
$ fortio load -curl -H Foo:Bar http://localhost:8080/debug 14:26:26 I http.go: 133> Setting regular extra header Foo: Bar HTTP/1.1 200 OK Content-Type: text/plain ; charset=UTF-8 Date: Mon, 08 Jan 2018 22:26:26 GMT Content-Length: 230 Φορτίο version X.Y.Z echo debug server up for 39s on ldemailly-macbookpro - request from [::1]:65055 GET /debug HTTP/1.1 headers: Host: localhost:8080 User-Agent: fortio.org/fortio-X.Y.Z Foo: Bar body:
$ fortio report -sync-interval 15m -sync " https://storage.googleapis.com/fortio-data?prefix=fortio.istio.io/ " Browse only UI starting - visit: http://localhost:8080/ Https redirector running on :8081
# in one window or & $ fortio server -M " five thousand five hundred and fifty-four http://localhost:8080 http://localhost:8080 " [...] Fortio X.Y.Z Multi on 5554 server listening on [::]:5554 10:09:56 I http_forwarder.go: 152> Multi-server on [::]:5554 running with & {Targets:[{Destination: http://localhost:8080 MirrorOrigin:true} {Destination: http://localhost:8080 MirrorOrigin:true}] Name:Multi on [::]:5554 client:0xc0001ccc00}
# in new window $ fortio curl -payload " a test " http://localhost:5554/debug HTTP/1.1 200 OK Date: Wed, 07 Oct 2020 17:11:06 GMT Content-Length: 684 Content-Type: text/plain ; charset=utf-8 Φορτίο version X.Y.Z unknown goM.m.p echo debug server up for 1m9.3s on C02C77BHMD6R - request from [::1]:51020 POST /debug HTTP/1.1 headers: Host: localhost:8080 Accept-Encoding: gzip Content-Type: application/octet-stream User-Agent: fortio.org/fortio-X.Y.Z X-Fortio-Multi-Id: 1 X-On-Behalf-Of: [::1]:51019 body: a test Φορτίο version X.Y.Z unknown goM.m.p echo debug server up for 1m9.3s on C02C77BHMD6R - request from [::1]:51020 POST /debug HTTP/1.1 headers: Host: localhost:8080 Accept-Encoding: gzip Content-Type: application/octet-stream User-Agent: fortio.org/fortio-X.Y.Z X-Fortio-Multi-Id: 2 X-On-Behalf-Of: [::1]:51019 body: a test
-
pass -mirrorOriginFlag=false to not mirror all headers and request type to targets. -
pass -multi-serial-mode to stream request response serially instead of fetching in parallel and writing combined data after completion.
$ fortio server -P " 8888 [::1]:8080 " -P " [::1]:8889 [::1]:8080 " Fortio X.Y.Z grpc ' ping ' server listening on [::]:8079 Fortio X.Y.Z https redirector server listening on [::]:8081 Fortio X.Y.Z echo server listening on [::]:8080 Data directory is /home/dl UI started - visit: http://localhost:8080/fortio/ (or any host/ip reachable on this server) Fortio X.Y.Z proxy for [::1]:8080 server listening on [::]:8888 Fortio X.Y.Z proxy for [::1]:8080 server listening on [::1]:8889
$ time fortio load -qps 5000 -t 60s -c 8 -r 0.0001 -H "Host: perf-cluster" http://benchmark-2:9090/echo 2017/07/09 02:31:05 Will be setting special Host header to perf-cluster Fortio running at 5000 queries per second for 1m0s: http://benchmark-2:9090/echo Starting at 5000 qps with 8 thread(s) [gomax 4] for 1m0s : 37500 calls each (total 300000) 2017/07/09 02:32:05 T004 ended after 1m0.000907812s : 37500 calls. qps=624.9905437680746 2017/07/09 02:32:05 T000 ended after 1m0.000922222s : 37500 calls. qps=624.9903936684861 2017/07/09 02:32:05 T005 ended after 1m0.00094454s : 37500 calls. qps=624.9901611965524 2017/07/09 02:32:05 T006 ended after 1m0.000944816s : 37500 calls. qps=624.9901583216429 2017/07/09 02:32:05 T001 ended after 1m0.00102094s : 37500 calls. qps=624.9893653892883 2017/07/09 02:32:05 T007 ended after 1m0.001096292s : 37500 calls. qps=624.9885805003184 2017/07/09 02:32:05 T003 ended after 1m0.001045342s : 37500 calls. qps=624.9891112105419 2017/07/09 02:32:05 T002 ended after 1m0.001044416s : 37500 calls. qps=624.9891208560392 Ended after 1m0.00112695s : 300000 calls. qps=4999.9 Aggregated Sleep Time : count 299992 avg 8.8889218e-05 +/- 0.002326 min -0.03490402 max 0.001006041 sum 26.6660543 # range, mid point, percentile, count < 0 , 0 , 8.58, 25726 >= 0 < 0.001 , 0.0005 , 100.00, 274265 >= 0.001 < 0.002 , 0.0015 , 100.00, 1 # target 50% 0.000453102 WARNING 8.58% of sleep were falling behind Aggregated Function Time : count 300000 avg 0.00094608764 +/- 0.0007901 min 0.000510522 max 0.029267604 sum 283.826292 # range, mid point, percentile, count >= 0.0005 < 0.0006 , 0.00055 , 0.15, 456 >= 0.0006 < 0.0007 , 0.00065 , 3.25, 9295 >= 0.0007 < 0.0008 , 0.00075 , 24.23, 62926 >= 0.0008 < 0.0009 , 0.00085 , 62.73, 115519 >= 0.0009 < 0.001 , 0.00095 , 85.68, 68854 >= 0.001 < 0.0011 , 0.00105 , 93.11, 22293 >= 0.0011 < 0.0012 , 0.00115 , 95.38, 6792 >= 0.0012 < 0.0014 , 0.0013 , 97.18, 5404 >= 0.0014 < 0.0016 , 0.0015 , 97.94, 2275 >= 0.0016 < 0.0018 , 0.0017 , 98.34, 1198 >= 0.0018 < 0.002 , 0.0019 , 98.60, 775 >= 0.002 < 0.0025 , 0.00225 , 98.98, 1161 >= 0.0025 < 0.003 , 0.00275 , 99.21, 671 >= 0.003 < 0.0035 , 0.00325 , 99.36, 449 >= 0.0035 < 0.004 , 0.00375 , 99.47, 351 >= 0.004 < 0.0045 , 0.00425 , 99.57, 290 >= 0.0045 < 0.005 , 0.00475 , 99.66, 280 >= 0.005 < 0.006 , 0.0055 , 99.79, 380 >= 0.006 < 0.007 , 0.0065 , 99.82, 92 >= 0.007 < 0.008 , 0.0075 , 99.83, 15 >= 0.008 < 0.009 , 0.0085 , 99.83, 5 >= 0.009 < 0.01 , 0.0095 , 99.83, 1 >= 0.01 < 0.012 , 0.011 , 99.83, 8 >= 0.012 < 0.014 , 0.013 , 99.84, 35 >= 0.014 < 0.016 , 0.015 , 99.92, 231 >= 0.016 < 0.018 , 0.017 , 99.94, 65 >= 0.018 < 0.02 , 0.019 , 99.95, 26 >= 0.02 < 0.025 , 0.0225 , 100.00, 139 >= 0.025 < 0.03 , 0.0275 , 100.00, 14 # target 50% 0.000866935 # target 75% 0.000953452 # target 99% 0.00253875 # target 99.9% 0.0155152 Code 200 : 300000 Response Body Sizes : count 300000 avg 0 +/- 0 min 0 max 0 sum 0
Code 200 : 2929 (97.6 %) Code 429 : 56 (1.9 %) Code 503 : 15 (0.5 %)
make test make lint make release-test
standard --fix ui/static/js/fortio_chart.js