-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstats.go
121 lines (107 loc) · 3.33 KB
/
stats.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package main
import (
"encoding/json"
"fmt"
"sort"
)
type Stats struct {
Url string
Connections int
Threads int
AvgDuration float64
Duration float64
Sum float64
Times []int
Transferred int64
Success int64
Errors int64
}
func CalcStats(responseChannel chan *Response, duration int64) []byte {
stats := &Stats{
Url: target,
Connections: *numConnections,
Threads: *numThreads,
Times: make([]int, len(responseChannel)),
Duration: float64(duration),
AvgDuration: float64(duration),
}
i := 0
for res := range responseChannel {
switch {
case res.StatusCode == 0:
stats.Success++
default:
stats.Errors++
}
stats.Sum += float64(res.Duration)
stats.Times[i] = int(res.Duration)
i++
stats.Transferred += res.Size
if res.Error {
stats.Errors++
}
if len(responseChannel) == 0 {
break
}
}
sort.Ints(stats.Times)
PrintStats(stats)
b, err := json.Marshal(&stats)
if err != nil {
fmt.Println(err)
}
return b
}
func CalcDistStats(distChan chan string) {
if len(distChan) == 0 {
return
}
allStats := &Stats{
Url: target,
Connections: *numConnections,
Threads: *numThreads,
}
statCount := len(distChan)
for res := range distChan {
var stats Stats
err := json.Unmarshal([]byte(res), &stats)
if err != nil {
fmt.Println(err)
}
allStats.Duration += stats.Duration
allStats.Sum += stats.Sum
allStats.Times = append(allStats.Times, stats.Times...)
allStats.Success += stats.Success
allStats.Errors += stats.Errors
if len(distChan) == 0 {
break
}
}
allStats.AvgDuration = allStats.Duration / float64(statCount)
PrintStats(allStats)
}
func PrintStats(allStats *Stats) {
sort.Ints(allStats.Times)
total := float64(len(allStats.Times))
totalInt := int64(total)
fmt.Println("==========================BENCHMARK==========================")
fmt.Printf("URL:\t\t\t\t%s\n\n", allStats.Url)
fmt.Printf("Used Connections:\t\t%d\n", allStats.Connections)
fmt.Printf("Used Threads:\t\t\t%d\n", allStats.Threads)
fmt.Printf("Total number of calls:\t\t%d\n\n", totalInt)
fmt.Println("===========================TIMINGS===========================")
fmt.Printf("Total time passed:\t\t%.2fs\n", allStats.AvgDuration/1E6)
fmt.Printf("Avg time per request:\t\t%.2fms\n", allStats.Sum/total/1000)
fmt.Printf("Requests per second:\t\t%.2f\n", total/(allStats.AvgDuration/1E6))
fmt.Printf("Median time per request:\t%.2fms\n", float64(allStats.Times[(totalInt-1)/2])/1000)
fmt.Printf("99th percentile time:\t\t%.2fms\n", float64(allStats.Times[(totalInt/100*99)])/1000)
fmt.Printf("Slowest time for request:\t%.2fms\n\n", float64(allStats.Times[totalInt-1]/1000))
fmt.Println("=============================DATA=============================")
fmt.Printf("Total response body sizes:\t\t%d\n", allStats.Transferred)
fmt.Printf("Avg response body per request:\t\t%.2f Byte\n", float64(allStats.Transferred)/total)
tr := float64(allStats.Transferred) / (allStats.AvgDuration / 1E6)
fmt.Printf("Transfer rate per second:\t\t%.2f Mb/s\n", 8*tr/1E6)
fmt.Println("==========================RESPONSES==========================")
fmt.Printf("Success Responses:\t\t%d\t(%.2f%%)\n", allStats.Success, float64(allStats.Success)/total*1e2)
fmt.Printf("Error Responses:\t\t%d\t(%.2f%%)\n", allStats.Errors, float64(allStats.Errors)/total*1e2)
}