github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/catgo/cat-go/cat/monitor.go (about) 1 package cat 2 3 import ( 4 "bytes" 5 "encoding/xml" 6 "runtime" 7 "time" 8 9 "github.com/shirou/gopsutil/cpu" 10 11 "github.com/artisanhe/tools/catgo/cat-go/message" 12 ) 13 14 type catMonitor struct { 15 scheduleMixin 16 collectors []Collector 17 } 18 19 func (m *catMonitor) GetName() string { 20 return "Monitor" 21 } 22 23 func sleep2NextMinute() *time.Timer { 24 var delta = 60 - time.Now().Second() 25 return time.NewTimer(time.Duration(delta) * time.Second) 26 } 27 28 func (m *catMonitor) afterStart() { 29 LogEvent(typeSystem, nameReboot) 30 m.collectAndSend() 31 } 32 33 func (m *catMonitor) process() { 34 timer := sleep2NextMinute() 35 defer timer.Stop() 36 37 select { 38 case sig := <-m.signals: 39 m.handle(sig) 40 case <-timer.C: 41 m.collectAndSend() 42 } 43 } 44 45 func (m *catMonitor) buildXml() *bytes.Buffer { 46 type ExtensionDetail struct { 47 Id string `xml:"id,attr"` 48 Value string `xml:"value,attr"` 49 } 50 51 type Extension struct { 52 Id string `xml:"id,attr"` 53 Desc string `xml:"description"` 54 Details []ExtensionDetail `xml:"extensionDetail"` 55 } 56 57 type CustomInfo struct { 58 Key string `xml:"key,attr"` 59 Value string `xml:"value,attr"` 60 } 61 62 type Status struct { 63 XMLName xml.Name `xml:"status"` 64 Extensions []Extension `xml:"extension"` 65 CustomInfos []CustomInfo `xml:"customInfo"` 66 } 67 68 status := Status{ 69 Extensions: make([]Extension, 0, len(m.collectors)), 70 CustomInfos: make([]CustomInfo, 0, 3), 71 } 72 73 for _, collector := range m.collectors { 74 extension := Extension{ 75 Id: collector.GetId(), 76 Desc: collector.GetDesc(), 77 Details: make([]ExtensionDetail, 0), 78 } 79 80 for k, v := range collector.GetProperties() { 81 detail := ExtensionDetail{ 82 Id: k, 83 Value: v, 84 } 85 extension.Details = append(extension.Details, detail) 86 } 87 status.Extensions = append(status.Extensions, extension) 88 } 89 90 // add custom information. 91 status.CustomInfos = append(status.CustomInfos, CustomInfo{"catgolangclient-version", CatClientVersion}) 92 status.CustomInfos = append(status.CustomInfos, CustomInfo{"go-version", runtime.Version()}) 93 94 buf := bytes.NewBuffer([]byte{}) 95 encoder := xml.NewEncoder(buf) 96 encoder.Indent("", "\t") 97 98 if err := encoder.Encode(status); err != nil { 99 buf.Reset() 100 buf.WriteString(err.Error()) 101 return buf 102 } 103 return buf 104 } 105 106 func (m *catMonitor) collectAndSend() { 107 var trans = message.NewTransaction(typeSystem, "Status", manager.flush) 108 defer trans.Complete() 109 110 trans.LogEvent("Cat_golang_Client_Version", CatClientVersion) 111 112 // NOTE type & name is useless while sending a heartbeat 113 heartbeat := message.NewHeartbeat("Heartbeat", config.ip, nil) 114 heartbeat.SetData(m.buildXml().String()) 115 heartbeat.Complete() 116 117 trans.AddChild(heartbeat) 118 } 119 120 var monitor = catMonitor{ 121 scheduleMixin: makeScheduleMixedIn(signalMonitorExit), 122 collectors: []Collector{ 123 &memStatsCollector{}, 124 &cpuInfoCollector{ 125 lastTime: &cpu.TimesStat{}, 126 lastCPUTime: 0, 127 }, 128 }, 129 } 130 131 func AddMonitorCollector(collector Collector) { 132 monitor.collectors = append(monitor.collectors, collector) 133 }