Skip to content

Commit 62f5b90

Browse files
committed
Merge branch 'main' into demo
2 parents b6cff46 + 589eb25 commit 62f5b90

File tree

14 files changed

+518
-101
lines changed

14 files changed

+518
-101
lines changed

server/app/models/LoadsterPayload.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,21 @@ type WorkerData struct {
3434
OtherFailRPS int64 `json:"otherFailRPS"`
3535
TimeTaken int64 `json:"timeTaken"`
3636
Latency []models.Loadster `json:"latency"`
37+
LoadAvg []models.Loadster `json:"loadAvg"`
38+
CpuUsage []models.Loadster `json:"cpuUsage"`
39+
Ingress []models.Loadster `json:"ingress"`
40+
Outgress []models.Loadster `json:"outgress"`
41+
RamUsage []models.Loadster `json:"ramUsage"`
3742
Success []models.Loadster `json:"success"`
3843
Fail []models.Loadster `json:"fail"`
3944
OtherFail []models.Loadster `json:"otherFail"`
4045
FailPercentage int `json:"failPercentage"`
4146
MinLatency int64 `json:"minLatency"`
4247
MaxLatency int64 `json:"maxLatency"`
48+
// cpu usage
49+
LastCpuUsage int64 `json:"lastCpuUsage"`
50+
LastLoadAvg int64 `json:"lastLoadAvg"`
51+
LastRamUsage int64 `json:"lastRamUsage"`
52+
LastIngress int64 `json:"lastIngress"`
53+
LastOutgress int64 `json:"lastOutgress"`
4354
}

server/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
github.com/jinzhu/inflection v1.0.0 // indirect
3333
github.com/jinzhu/now v1.1.5 // indirect
3434
github.com/klauspost/compress v1.16.3 // indirect
35+
github.com/mackerelio/go-osstat v0.2.4 // indirect
3536
github.com/mattn/go-colorable v0.1.13 // indirect
3637
github.com/mattn/go-isatty v0.0.18 // indirect
3738
github.com/mattn/go-runewidth v0.0.14 // indirect

server/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx
5151
github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
5252
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
5353
github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
54+
github.com/mackerelio/go-osstat v0.2.4 h1:qxGbdPkFo65PXOb/F/nhDKpF2nGmGaCFDLXoZjJTtUs=
55+
github.com/mackerelio/go-osstat v0.2.4/go.mod h1:Zy+qzGdZs3A9cuIqmgbJvwbmLQH9dJvtio5ZjJTbdlQ=
5456
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
5557
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
5658
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=

server/pkg/configs/fiber.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ func FiberConfig() fiber.Config {
1717
// Return Fiber configuration.
1818
return fiber.Config{
1919
ReadTimeout: time.Second * time.Duration(readTimeoutSecondsCount),
20-
Prefork: true,
20+
// Prefork: true,
2121
}
2222
}

server/pkg/executor/systemMonit.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package executor
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
metrics "github.com/cirnum/loadtester/server/pkg/executor/metrics"
8+
"github.com/mackerelio/go-osstat/cpu"
9+
"github.com/mackerelio/go-osstat/loadavg"
10+
"github.com/mackerelio/go-osstat/memory"
11+
"github.com/mackerelio/go-osstat/network"
12+
log "github.com/sirupsen/logrus"
13+
)
14+
15+
const slLA1 string = "LA1"
16+
const cpuUser string = "CPU"
17+
const ramUsing string = "RAM"
18+
19+
// systemload report the current host system load like cpu, ram, and network
20+
// status
21+
22+
// systemloadSetup setup the metrics for systemload
23+
func (e *Executor) systemloadSetup(reqId string) (err error) {
24+
group := metrics.Group{
25+
Name: "System Load",
26+
Graphs: []metrics.Graph{
27+
{
28+
Title: "Load average",
29+
Unit: "*100",
30+
Metrics: []metrics.Metric{
31+
{
32+
Title: slLA1,
33+
Type: metrics.Gauge,
34+
},
35+
},
36+
},
37+
{
38+
Title: "CPU",
39+
Unit: "%",
40+
Metrics: []metrics.Metric{
41+
{
42+
Title: cpuUser,
43+
Type: metrics.Gauge,
44+
},
45+
},
46+
},
47+
{
48+
Title: "RAM",
49+
Unit: "%",
50+
Metrics: []metrics.Metric{
51+
{
52+
Title: ramUsing,
53+
Type: metrics.Gauge,
54+
},
55+
},
56+
},
57+
},
58+
}
59+
60+
// generate network metrics
61+
nss, err := network.Get()
62+
if err != nil {
63+
return
64+
}
65+
txMetrics := make([]metrics.Metric, 0, len(nss))
66+
rxMetrics := make([]metrics.Metric, 0, len(nss))
67+
for _, ns := range nss {
68+
// txMetrics = append(txMetrics, metrics.Metric{
69+
txMetrics = append(txMetrics, metrics.Metric{
70+
Title: ns.Name + " transmit",
71+
Type: metrics.Gauge,
72+
})
73+
rxMetrics = append(rxMetrics, metrics.Metric{
74+
Title: ns.Name + " receive",
75+
Type: metrics.Gauge,
76+
})
77+
}
78+
group.Graphs = append(group.Graphs, metrics.Graph{
79+
Title: "Network transmit",
80+
Unit: "KiB/s",
81+
Metrics: txMetrics,
82+
})
83+
group.Graphs = append(group.Graphs, metrics.Graph{
84+
Title: "Network receive",
85+
Unit: "KiB/s",
86+
Metrics: rxMetrics,
87+
})
88+
89+
groups := []metrics.Group{
90+
group,
91+
}
92+
err = Setup(groups, reqId)
93+
return
94+
}
95+
96+
type rtxBytes struct {
97+
rxBytes, txBytes uint64
98+
}
99+
100+
// systemloadRun start collect the metrics
101+
func (e *Executor) systemloadRun(ctx context.Context) (err error) {
102+
ch := make(chan interface{})
103+
104+
go func(channel chan interface{}) {
105+
for range time.Tick(poll * time.Second) {
106+
channel <- struct{}{}
107+
}
108+
}(ch)
109+
110+
nssPre := make(map[string]rtxBytes)
111+
nssPreTime := time.Now()
112+
113+
var cpuPre *cpu.Stats
114+
// cpuPreTime := time.Now()
115+
116+
for {
117+
select {
118+
case <-ctx.Done():
119+
log.Info("systemloadRun canceled")
120+
return nil
121+
122+
case <-ch:
123+
// load average
124+
if la, err := loadavg.Get(); err == nil {
125+
la1 := int64(la.Loadavg1 * 100)
126+
Notify(slLA1, la1)
127+
}
128+
129+
// network status
130+
if nss, err := network.Get(); err == nil {
131+
now := time.Now()
132+
for _, ns := range nss {
133+
prv, ok := nssPre[ns.Name]
134+
if ok {
135+
diffTime := now.Sub(nssPreTime).Seconds()
136+
137+
tx := float64(ns.TxBytes-prv.txBytes) / diffTime // Bps
138+
rx := float64(ns.RxBytes-prv.rxBytes) / diffTime // Bps
139+
Notify(ns.Name+" transmit", int64(tx/1000)) // KBps
140+
Notify(ns.Name+" receive", int64(rx/1000)) // KBps
141+
}
142+
// update prv values
143+
nssPre[ns.Name] = rtxBytes{
144+
rxBytes: ns.RxBytes,
145+
txBytes: ns.TxBytes,
146+
}
147+
}
148+
nssPreTime = now
149+
}
150+
151+
if cpuNow, err := cpu.Get(); err == nil {
152+
if cpuPre != nil {
153+
total := float64(cpuNow.Total - cpuPre.Total)
154+
user := float64(cpuNow.User-cpuPre.User) / total * 100
155+
Notify(cpuUser, int64(user))
156+
}
157+
cpuPre = cpuNow
158+
}
159+
160+
if mem, err := memory.Get(); err == nil {
161+
r := float64(mem.Used) / float64(mem.Total) * 100.0
162+
Notify(ramUsing, int64(r))
163+
}
164+
}
165+
}
166+
}

server/pkg/executor/worker.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ func (e *Executor) Setup(groups []metrics.Group, reqId string) error {
8888
for _, group := range groups {
8989
for _, graph := range group.Graphs {
9090
for _, m := range graph.Metrics {
91+
indetifier := e.appID + m.Title
9192
if m.Type == metrics.Counter {
9293
c := gometrics.NewCounter()
93-
if err := gometrics.Register(e.appID+m.Title, c); err != nil {
94+
if err := gometrics.Register(indetifier, c); err != nil {
9495
if _, ok := err.(gometrics.DuplicateMetric); ok {
9596
continue
9697
}
@@ -106,7 +107,7 @@ func (e *Executor) Setup(groups []metrics.Group, reqId string) error {
106107
if m.Type == metrics.Histogram {
107108
s := gometrics.NewExpDecaySample(1028, 0.015)
108109
h := gometrics.NewHistogram(s)
109-
if err := gometrics.Register(e.appID, h); err != nil {
110+
if err := gometrics.Register(indetifier, h); err != nil {
110111
if _, ok := err.(gometrics.DuplicateMetric); ok {
111112
continue
112113
}
@@ -120,8 +121,9 @@ func (e *Executor) Setup(groups []metrics.Group, reqId string) error {
120121
}
121122
}
122123
if m.Type == metrics.Gauge {
124+
123125
g := gometrics.NewGauge()
124-
if err := gometrics.Register(e.appID, g); err != nil {
126+
if err := gometrics.Register(indetifier, g); err != nil {
125127
if _, ok := err.(gometrics.DuplicateMetric); ok {
126128
continue
127129
}
@@ -137,6 +139,7 @@ func (e *Executor) Setup(groups []metrics.Group, reqId string) error {
137139
}
138140
}
139141
}
142+
140143
// aggregate units
141144
for k, v := range units {
142145
e.units[k] = v
@@ -146,11 +149,13 @@ func (e *Executor) Setup(groups []metrics.Group, reqId string) error {
146149
}
147150

148151
func (e *Executor) Run(ctx context.Context, conf models.Request) (err error) {
152+
e.systemloadSetup(conf.ID)
149153
e.status = Running
150154
finished := make(chan error)
151155
// when the runScen finished, we should stop the logScaled and systemloadRun
152156
// also; however, not necessary since the executor will be shutdown anyway
153157
go e.logScaled(ctx, poll*time.Second)
158+
go e.systemloadRun(ctx)
154159
select {
155160
case err = <-finished:
156161
case <-ctx.Done():
@@ -215,6 +220,17 @@ func (e *Executor) GrabCounter(ctx context.Context, units map[string]unit) ([]mo
215220
StartTime: e.startTime,
216221
}
217222
data = append(data, histo)
223+
case metrics.Gauge:
224+
counter := models.Loadster{
225+
Count: u.g.Value(),
226+
Type: string(u.Type),
227+
Title: u.Title,
228+
ReqId: e.appID,
229+
ServerId: e.serverId,
230+
Created: now,
231+
StartTime: e.startTime,
232+
}
233+
data = append(data, counter)
218234
}
219235
}
220236
e.mu.Unlock()
@@ -245,7 +261,7 @@ func (e *Executor) logScaledOnCue(ctx context.Context, ch chan interface{}) erro
245261
log.Error("Failed to connect to master host", err.Error())
246262
}
247263
if res != nil {
248-
log.Warnf("For url: %s, statusCode: %s", url, res.StatusCode)
264+
log.Warnf("For url: %s, statusCode: %d", url, res.StatusCode)
249265
}
250266
} else {
251267
db.Provider.AddLoadByRequestId(ctx, value)

server/pkg/utils/loadster.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package utils
22

33
import (
4+
"fmt"
5+
46
customModels "github.com/cirnum/loadtester/server/app/models"
57
"github.com/cirnum/loadtester/server/db/models"
68
)
@@ -43,6 +45,13 @@ func CalculateRPSByTitle(loadsByServer map[string][]models.Loadster) customModel
4345
okHTTP, lastOkHttp := HttpReqByType(load, ".http_ok")
4446
failHTTP, lastFailHTTP := HttpReqByType(load, ".http_fail")
4547
otherFailHTTP, lastOtherFailHTTP := HttpReqByType(load, ".http_other_fail")
48+
loadAvg1, lastLoadAvg := HttpReqByType(load, "LA1")
49+
cpu, lastCpuUsage := HttpReqByType(load, "CPU")
50+
ram, lastRamUsage := HttpReqByType(load, "RAM")
51+
outgress, lastOutgress := HttpReqByType(load, "en0 transmit")
52+
ingress, lastIngress := HttpReqByType(load, "en0 receive")
53+
54+
fmt.Println("lastCpuUsage", lastCpuUsage)
4655
totalTimeTaken := lastLatency.CreatedAt - lastLatency.StartTime
4756

4857
if lastFailHTTP.Count > 0 {
@@ -77,6 +86,18 @@ func CalculateRPSByTitle(loadsByServer map[string][]models.Loadster) customModel
7786
loadPayload.MaxLatency = lastLatency.Max
7887
loadPayload.Latency = latency
7988
loadPayload.Success = okHTTP
89+
// Server details
90+
loadPayload.LoadAvg = loadAvg1
91+
loadPayload.CpuUsage = cpu
92+
loadPayload.RamUsage = ram
93+
loadPayload.Ingress = ingress
94+
loadPayload.Outgress = outgress
95+
loadPayload.LastLoadAvg = lastLoadAvg.Count
96+
loadPayload.LastCpuUsage = lastCpuUsage.Count
97+
loadPayload.LastRamUsage = lastRamUsage.Count
98+
loadPayload.LastIngress = lastIngress.Count
99+
loadPayload.LastOutgress = lastOutgress.Count
100+
80101
loadPayload.Fail = failHTTP
81102
loadPayload.OtherFail = otherFailHTTP
82103
loadPayload.TimeTaken = totalTimeTaken

0 commit comments

Comments
 (0)