mirror of
https://github.com/Monibuca/plugin-summary.git
synced 2025-09-27 03:26:06 +08:00
192 lines
4.2 KiB
Go
192 lines
4.2 KiB
Go
package plugin_summary
|
|
|
|
import (
|
|
"github.com/gogf/gf/text/gregex"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
. "github.com/Monibuca/engine/v3"
|
|
. "github.com/Monibuca/utils/v3"
|
|
"github.com/shirou/gopsutil/cpu"
|
|
"github.com/shirou/gopsutil/disk"
|
|
"github.com/shirou/gopsutil/mem"
|
|
"github.com/shirou/gopsutil/net"
|
|
)
|
|
|
|
// Summary 系统摘要数据
|
|
var Summary ServerSummary
|
|
var config = struct {
|
|
SampleRate int
|
|
NetAdapter string //在容器化设备会有很多无效的虚拟网卡,只读取有意义的网卡
|
|
}{1, ""}
|
|
|
|
func init() {
|
|
plugin := PluginConfig{
|
|
Name: "Summary",
|
|
Config: &config,
|
|
HotConfig: map[string]func(interface{}){
|
|
"NetAdapter": func(v interface{}) {
|
|
config.NetAdapter = v.(string)
|
|
},
|
|
},
|
|
}
|
|
plugin.Install(Summary.StartSummary)
|
|
http.HandleFunc("/api/summary", summary)
|
|
}
|
|
func summary(w http.ResponseWriter, r *http.Request) {
|
|
CORS(w, r)
|
|
sse := NewSSE(w, r.Context())
|
|
Summary.Add()
|
|
defer Summary.Done()
|
|
sse.WriteJSON(&Summary)
|
|
ticker := time.NewTicker(time.Second)
|
|
defer ticker.Stop()
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
if err := sse.WriteJSON(&Summary); err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
case <-r.Context().Done():
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// ServerSummary 系统摘要定义
|
|
type ServerSummary struct {
|
|
Address string
|
|
Memory struct {
|
|
Total uint64
|
|
Free uint64
|
|
Used uint64
|
|
Usage float64
|
|
}
|
|
CPUUsage float64
|
|
HardDisk struct {
|
|
Total uint64
|
|
Free uint64
|
|
Used uint64
|
|
Usage float64
|
|
}
|
|
NetWork []NetWorkInfo
|
|
Streams []*Stream
|
|
lastNetWork []net.IOCountersStat
|
|
ref int
|
|
control chan bool
|
|
reportChan chan *ServerSummary
|
|
Children map[string]*ServerSummary
|
|
}
|
|
|
|
// NetWorkInfo 网速信息
|
|
type NetWorkInfo struct {
|
|
Name string
|
|
Receive uint64
|
|
Sent uint64
|
|
ReceiveSpeed uint64
|
|
SentSpeed uint64
|
|
}
|
|
|
|
//StartSummary 开始定时采集数据,每秒一次
|
|
func (s *ServerSummary) StartSummary() {
|
|
ticker := time.NewTicker(time.Second * time.Duration(config.SampleRate))
|
|
s.control = make(chan bool)
|
|
s.reportChan = make(chan *ServerSummary)
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
if s.ref > 0 {
|
|
Summary.collect()
|
|
}
|
|
case v := <-s.control:
|
|
if v {
|
|
if s.ref++; s.ref == 1 {
|
|
log.Println("start report summary")
|
|
TriggerHook("Summary", true)
|
|
}
|
|
} else {
|
|
if s.ref--; s.ref == 0 {
|
|
s.lastNetWork = nil
|
|
log.Println("stop report summary")
|
|
TriggerHook("Summary", false)
|
|
}
|
|
}
|
|
case report := <-s.reportChan:
|
|
s.Children[report.Address] = report
|
|
}
|
|
}
|
|
}
|
|
|
|
// Running 是否正在采集数据
|
|
func (s *ServerSummary) Running() bool {
|
|
return s.ref > 0
|
|
}
|
|
|
|
// Add 增加订阅者
|
|
func (s *ServerSummary) Add() {
|
|
s.control <- true
|
|
}
|
|
|
|
// Done 删除订阅者
|
|
func (s *ServerSummary) Done() {
|
|
s.control <- false
|
|
}
|
|
|
|
// Report 上报数据
|
|
func (s *ServerSummary) Report(slave *ServerSummary) {
|
|
s.reportChan <- slave
|
|
}
|
|
func (s *ServerSummary) collect() {
|
|
v, _ := mem.VirtualMemory()
|
|
d, _ := disk.Usage("/")
|
|
nv, _ := net.IOCounters(true)
|
|
|
|
s.Memory.Total = v.Total / 1024 / 1024
|
|
s.Memory.Free = v.Available / 1024 / 1024
|
|
s.Memory.Used = v.Used / 1024 / 1024
|
|
s.Memory.Usage = v.UsedPercent
|
|
|
|
if cc, _ := cpu.Percent(time.Second, false); len(cc) > 0 {
|
|
s.CPUUsage = cc[0]
|
|
}
|
|
s.HardDisk.Free = d.Free / 1024 / 1024 / 1024
|
|
s.HardDisk.Total = d.Total / 1024 / 1024 / 1024
|
|
s.HardDisk.Used = d.Used / 1024 / 1024 / 1024
|
|
s.HardDisk.Usage = d.UsedPercent
|
|
s.NetWork = make([]NetWorkInfo, 0)
|
|
for i, n := range nv {
|
|
if n.BytesRecv == 0 || !isNetAdapter(n.Name) {
|
|
continue
|
|
}
|
|
info := NetWorkInfo{}
|
|
info.Name = n.Name
|
|
info.Receive = n.BytesRecv
|
|
info.Sent = n.BytesSent
|
|
if s.lastNetWork != nil && len(s.lastNetWork) > i {
|
|
info.ReceiveSpeed = n.BytesRecv - s.lastNetWork[i].BytesRecv
|
|
info.SentSpeed = n.BytesSent - s.lastNetWork[i].BytesSent
|
|
}
|
|
s.NetWork = append(s.NetWork, info)
|
|
}
|
|
s.lastNetWork = nv
|
|
s.Streams = Streams.ToList()
|
|
return
|
|
}
|
|
|
|
//NetAdapter 通过匹配和正则判断要过滤的无效网卡
|
|
func isNetAdapter(name string) bool {
|
|
if name == "" {
|
|
return true
|
|
}
|
|
|
|
//正则用@作正则修饰符
|
|
if !strings.Contains(config.NetAdapter, "@") {
|
|
return strings.Contains(name, config.NetAdapter)
|
|
}
|
|
|
|
return gregex.IsMatchString(strings.Trim(config.NetAdapter, "@"), name)
|
|
}
|