-
Notifications
You must be signed in to change notification settings - Fork 42
/
monitor.go
122 lines (97 loc) · 2.4 KB
/
monitor.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
122
package main
import (
"fmt"
"os"
"os/signal"
"time"
)
type Monitor struct {
c *Context
collector chan *Record
output chan *Stats
}
type Stats struct {
responseTimeData []time.Duration
totalRequests int
totalExecutionTime time.Duration
totalResponseTime time.Duration
totalReceived int64
totalFailedReqeusts int
errLength int
errConnect int
errReceive int
errException int
errResponse int
}
func NewMonitor(context *Context, collector chan *Record) *Monitor {
return &Monitor{context, collector, make(chan *Stats)}
}
func (m *Monitor) Run() {
// catch interrupt signal
userInterrupt := make(chan os.Signal, 1)
signal.Notify(userInterrupt, os.Interrupt)
stats := &Stats{}
stats.responseTimeData = make([]time.Duration, 0, m.c.config.requests)
var timelimiter <-chan time.Time
if m.c.config.timelimit > 0 {
t := time.NewTimer(time.Duration(m.c.config.timelimit) * time.Second)
defer t.Stop()
timelimiter = t.C
}
// waiting for all of http workers to start
m.c.start.Wait()
fmt.Printf("Benchmarking %s (be patient)\n", m.c.config.host)
sw := &StopWatch{}
sw.Start()
loop:
for {
select {
case record := <-m.collector:
updateStats(stats, record)
if record.Error != nil && !ContinueOnError {
break loop
}
if stats.totalRequests >= 10 && stats.totalRequests%(m.c.config.requests/10) == 0 {
fmt.Printf("Completed %d requests\n", stats.totalRequests)
}
if stats.totalRequests == m.c.config.requests {
fmt.Printf("Finished %d requests\n", stats.totalRequests)
break loop
}
case <-timelimiter:
break loop
case <-userInterrupt:
break loop
}
}
sw.Stop()
stats.totalExecutionTime = sw.Elapsed
// shutdown benchmark and all of httpworkers to stop
close(m.c.stop)
signal.Stop(userInterrupt)
m.output <- stats
}
func updateStats(stats *Stats, record *Record) {
stats.totalRequests++
if record.Error != nil {
stats.totalFailedReqeusts++
switch record.Error.(type) {
case *ConnectError:
stats.errConnect++
case *ExceptionError:
stats.errException++
case *LengthError:
stats.errLength++
case *ReceiveError:
stats.errReceive++
case *ResponseError:
stats.errResponse++
default:
stats.errException++
}
} else {
stats.totalResponseTime += record.responseTime
stats.totalReceived += record.contentSize
stats.responseTimeData = append(stats.responseTimeData, record.responseTime)
}
}