Skip to content

Commit 098d6a2

Browse files
committed
apian->xcheck
Signed-off-by: kl7sn <mex7.0828@gmail.com>
1 parent 64362c2 commit 098d6a2

File tree

14 files changed

+642
-3
lines changed

14 files changed

+642
-3
lines changed

xcheck/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Brief Introduction
2+
3+
To solve the problem of service abnormal OOM, the OOM generated by sudden memory growth cann't be quickly located.
4+
The purpose of this service is to help users automatically locate the OOM problem and provide the corresponding OOM analysis report.
5+
6+
# Module Introduction
7+
- **Monitor Module**: Memory changes are detected every second
8+
- **Forward Module**: The memory change data is sent to the server
9+
- Support Webhook
10+
11+
# TODO
12+
13+
## v0.1.0
14+
- [x] Support trigger indicator hot loading
15+
- use `Apply` to reload the trigger indicator
16+
- [x] Provide default trigger indicator
17+
- if cooling time is 0, use the default cooling time [1m]
18+
- if memory absolute value is 0, use the default value [128Mib]
19+
- if diff is 0, use the default diff [10%]

xcheck/consts.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package xcheck
2+
3+
import (
4+
"time"
5+
)
6+
7+
const (
8+
defaultCoolingTime = time.Minute
9+
10+
defaultMemTriggerValue = 128 // 128MB
11+
defaultMemTriggerPercent = 80 // 80%
12+
defaultMemTriggerDiff = 10 // 10%
13+
)

xcheck/example/main.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
"time"
7+
8+
"github.com/gotomicro/cetus/xcheck"
9+
)
10+
11+
func main() {
12+
a, _ := xcheck.New(
13+
xcheck.WithMemOpts(0, 0, 0, 0),
14+
)
15+
_ = a.EnableMem().Start()
16+
go func() {
17+
for i := 0; i < 100; i++ {
18+
// memoryLeaking()
19+
time.Sleep(time.Second)
20+
}
21+
}()
22+
23+
time.Sleep(time.Second * 10)
24+
// reload the config
25+
_ = a.Apply(xcheck.WithMemOpts(1024, 10, 20, time.Hour))
26+
27+
time.Sleep(time.Hour)
28+
}
29+
30+
// memoryLeaking 16MB
31+
func memoryLeaking() {
32+
type T struct {
33+
v [1 << 20]int
34+
t *T
35+
}
36+
37+
var finalizer = func(t *T) {
38+
fmt.Println("finalizer called")
39+
}
40+
41+
var x, y T
42+
43+
// 此SetFinalizer函数调用将使x逃逸到堆上。
44+
runtime.SetFinalizer(&x, finalizer)
45+
46+
// 下面这行将形成一个包含x和y的循环引用值组。
47+
// 这有可能造成x和y不可回收。
48+
x.t, y.t = &y, &x // y也逃逸到了堆上。
49+
}

xcheck/go.mod

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module github.com/gotomicro/cetus/xcheck
2+
3+
go 1.19
4+
5+
require (
6+
github.com/go-resty/resty/v2 v2.7.0
7+
github.com/gotomicro/ego v1.1.11
8+
github.com/shirou/gopsutil/v3 v3.21.6
9+
)
10+
11+
require (
12+
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
13+
github.com/davecgh/go-spew v1.1.1 // indirect
14+
github.com/go-logr/logr v1.2.3 // indirect
15+
github.com/go-logr/stdr v1.2.2 // indirect
16+
github.com/go-ole/go-ole v1.2.6 // indirect
17+
github.com/google/go-cmp v0.5.9 // indirect
18+
github.com/gotomicro/logrotate v0.0.0-20211108034117-46d53eedc960 // indirect
19+
github.com/mitchellh/mapstructure v1.5.0 // indirect
20+
github.com/spf13/cast v1.4.1 // indirect
21+
github.com/stretchr/testify v1.8.3 // indirect
22+
github.com/tklauser/go-sysconf v0.3.6 // indirect
23+
github.com/tklauser/numcpus v0.2.2 // indirect
24+
go.opentelemetry.io/otel v1.7.0 // indirect
25+
go.opentelemetry.io/otel/trace v1.7.0 // indirect
26+
go.uber.org/atomic v1.7.0 // indirect
27+
go.uber.org/multierr v1.6.0 // indirect
28+
go.uber.org/zap v1.21.0 // indirect
29+
golang.org/x/net v0.10.0 // indirect
30+
golang.org/x/sys v0.8.0 // indirect
31+
google.golang.org/grpc v1.46.0 // indirect
32+
gopkg.in/yaml.v3 v3.0.1 // indirect
33+
)

xcheck/go.sum

Lines changed: 208 additions & 0 deletions
Large diffs are not rendered by default.

xcheck/model/dto/forwarder.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package dto
2+
3+
type Forwarder struct {
4+
WebHook Webhook `json:"webhook"`
5+
}
6+
7+
type Webhook struct {
8+
Url string `json:"url"`
9+
Headers map[string]string `json:"headers"`
10+
Body map[string]interface{} `json:"body"`
11+
}
12+
13+
type AttachInfo struct {
14+
CurrentAbs uint64 `json:"currentAbs,omitempty"`
15+
CurrentDiff int `json:"currentDiff,omitempty"`
16+
17+
// Rule
18+
OptAbs uint64 `json:"optAbs,omitempty"`
19+
OptDiff uint64 `json:"optDiff,omitempty"`
20+
OptCoolingTimeSec int `json:"optCoolingTimeSec,omitempty"`
21+
}

xcheck/model/dto/monitor.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package dto
2+
3+
type Monitor struct{}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package webhook
2+
3+
import (
4+
"github.com/go-resty/resty/v2"
5+
"github.com/gotomicro/ego/core/elog"
6+
7+
"github.com/gotomicro/cetus/xcheck/model/utils"
8+
9+
"github.com/gotomicro/cetus/xcheck/model/dto"
10+
)
11+
12+
func Webhook(fw dto.Webhook, attach dto.AttachInfo) {
13+
client := resty.New()
14+
r := client.R().SetHeader("Content-Type", "application/json")
15+
for k, v := range fw.Headers {
16+
r.SetHeader(k, v)
17+
}
18+
if _, ok := fw.Body["mode"]; ok {
19+
ip, err := utils.GetOutBoundIP()
20+
if err != nil {
21+
elog.Error("forward", elog.FieldEvent("GetOutBoundIP"), elog.FieldErr(err), elog.String("msg", "get outbound ip error"))
22+
return
23+
}
24+
fw.Body["addr"] = ip + ":9003"
25+
elog.Info("xcheck", elog.Any("size", attach.CurrentAbs), elog.Any("attach", attach), elog.String("ip", ip), elog.Any("body", fw.Body))
26+
}
27+
r.SetBody(fw.Body)
28+
resp, err := r.Post(fw.Url)
29+
if err != nil {
30+
elog.Error("forward", elog.FieldEvent("post"), elog.FieldErr(err), elog.Any("fw", fw), elog.String("resp", resp.String()))
31+
return
32+
}
33+
}

xcheck/module/monitor/monitor.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package monitor
2+
3+
import (
4+
"os"
5+
6+
"github.com/shirou/gopsutil/v3/process"
7+
8+
"github.com/gotomicro/cetus/xcheck/model/dto"
9+
)
10+
11+
func New(m dto.Monitor) {
12+
13+
}
14+
15+
// ReadMemStats unit is MB
16+
func ReadMemStats() (uint64, float64) {
17+
p, err := process.NewProcess(int32(os.Getpid()))
18+
if err != nil {
19+
return 0, 0
20+
}
21+
mem, err := p.MemoryInfo()
22+
if err != nil {
23+
return 0, 0
24+
}
25+
// fmt.Printf("TotalAlloc = %v MiB", m.TotalAlloc/1024/1024)
26+
// usedPercent, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", float64(mem.RSS)/float64(m.Sys)), 64)
27+
return mem.RSS / 1024 / 1024, 0
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package monitor
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestReadMemStats(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
want uint64
11+
}{
12+
// TODO: Add test cases.
13+
{"test1", 0},
14+
}
15+
for _, tt := range tests {
16+
t.Run(tt.name, func(t *testing.T) {
17+
if got, _ := ReadMemStats(); got != tt.want {
18+
t.Errorf("ReadMemStats() = %v, want %v", got, tt.want)
19+
}
20+
})
21+
}
22+
}

0 commit comments

Comments
 (0)