多线程优化,精度丢失问题解决,减少依赖库

pull/92/head
CHN-STUDENT 2021-01-06 11:30:55 +08:00
parent 0757d68a1e
commit 2b55ea83d2
4 changed files with 361 additions and 166 deletions

View File

@ -10,25 +10,15 @@ package main
import (
"fmt"
"io/ioutil"
"os/signal"
"path/filepath"
"syscall"
//下面这是已经封装好的轮子
"github.com/bitcav/nitr-core/cpu"
"github.com/bitcav/nitr-core/host"
"github.com/bitcav/nitr-core/ram"
"github.com/json-iterator/go"
//没轮子的自己封装
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/load"
"github.com/shirou/gopsutil/mem"
nnet "github.com/shirou/gopsutil/net"
"io/ioutil"
"net"
"os"
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
"unsafe"
)
@ -40,6 +30,7 @@ var (
PASSWORD string = "123456"
INTERVAL int = 1
PORBEPORT int = 80
NETWORKCHECK bool = true
CU string = "cu.tz.cloudcpp.com" //120.52.99.224 河北联通
CT string = "ct.tz.cloudcpp.com" //183.78.182.66 北京电信
CM string = "cm.tz.cloudcpp.com" //211.139.145.129 广州移动
@ -55,6 +46,7 @@ type Config struct {
Cu string `json:"cu"`
Ct string `json:"cu"`
Cm string `json:"cm"`
NetworkCheck bool `json:"networkCheck"`
}
func NewConfig() Config {
@ -68,6 +60,7 @@ func NewConfig() Config {
Cu: CU,
Ct: CT,
Cm: CM,
NetworkCheck: NETWORKCHECK,
}
}
@ -132,134 +125,58 @@ func NewDefaultClientInfo() ClientInfo {
}
}
func trafficCount() {
netInfo, err := nnet.IOCounters(true)
if err != nil {
fmt.Println("[trafficCount]Getting traffic count error:",err)
}
var bytesSent uint64 = 0
var bytesRecv uint64 = 0
for _, v := range netInfo {
if strings.Index(v.Name,"lo") > -1 ||
strings.Index(v.Name,"tun") > -1 ||
strings.Index(v.Name,"docker") > -1 ||
strings.Index(v.Name,"veth") > -1 ||
strings.Index(v.Name,"br-") > -1 ||
strings.Index(v.Name,"vmbr") > -1 ||
strings.Index(v.Name,"vnet") > -1 ||
strings.Index(v.Name,"kube") > -1 {
continue
}
bytesSent += v.BytesSent
bytesRecv += v.BytesRecv
}
clientInfo.NetworkIn = bytesRecv
clientInfo.NetworkOut = bytesSent
}
func spaceCount() {
// golang 没有类似于在 python 的 dict 或 tuple 的 in 查找关键字,自己写多重判断实现
diskList, _ := disk.Partitions(false)
var total uint64 = 0
var used uint64 = 0
for _,d := range diskList {
fsType := strings.ToLower(d.Fstype)
//fmt.Println(d.Fstype)
if strings.Index(fsType, "ext4") < 0 &&
strings.Index(fsType, "ext3") < 0 &&
strings.Index(fsType, "ext2") < 0 &&
strings.Index(fsType, "reiserfs") < 0 &&
strings.Index(fsType, "jfs") < 0 &&
strings.Index(fsType, "btrfs") < 0 &&
strings.Index(fsType, "fuseblk") < 0 &&
strings.Index(fsType, "zfs") < 0 &&
strings.Index(fsType, "simfs") < 0 &&
strings.Index(fsType, "ntfs")< 0 &&
strings.Index(fsType, "fat32") < 0 &&
strings.Index(fsType, "exfat") < 0 &&
strings.Index(fsType, "xfs") < 0 {
} else {
if strings.Index(d.Device, "Z:") > -1 { //特殊盘符自己写处理
continue
} else {
diskUsageOf, _ := disk.Usage(d.Mountpoint)
used += diskUsageOf.Used
total += diskUsageOf.Total
}
}
}
clientInfo.HddUsed = used / 1024.0 / 1024.0
clientInfo.HddTotal = total / 1024.0 / 1024.0
}
func getLoad() {
// linux or freebsd only
if host.Info().OS == "linux" || host.Info().OS == "freebsd" {
l, err := load.Avg()
if err != nil {
fmt.Println("[getLoad]Get CPU loads failed:",err)
} else {
clientInfo.Load1 = l.Load1
clientInfo.Load5 = l.Load5
clientInfo.Load15 = l.Load15
}
} else {
clientInfo.Load1 = 0.0
clientInfo.Load5 = 0.0
clientInfo.Load15 = 0.0
}
}
var CU_ADDR = CU + ":" + strconv.Itoa(PORBEPORT)
var CT_ADDR = CT + ":" + strconv.Itoa(PORBEPORT)
var CM_ADDR = CM + ":" + strconv.Itoa(PORBEPORT)
func getNetworkStatus() {
defaulttimeout := 1 * time.Second
count := 0
conn1 , err1 := net.DialTimeout("tcp",CU_ADDR,defaulttimeout)
if err1 != nil {
fmt.Println("[getNetworkStatus]Error try to connect China unicom :", err1)
count += 1
}
tcpconn1, ok := conn1.(*net.TCPConn)
if ok {
tcpconn1.SetLinger(0)
}
if conn1 != nil {
conn1.Close()
}
conn2 , err2 := net.DialTimeout("tcp", CT_ADDR,defaulttimeout)
if err2 != nil {
fmt.Println("[getNetworkStatus]Error try to connect China telecom :", err2)
count += 1
}
tcpconn2, ok := conn2.(*net.TCPConn)
if ok {
tcpconn2.SetLinger(0)
}
if conn2 != nil {
conn2.Close()
}
conn3 , err3 := net.DialTimeout("tcp", CM_ADDR,defaulttimeout)
if err3 != nil {
fmt.Println("[getNetworkStatus]Error try to connect China mobile :", err3)
count += 1
}
tcpconn3, ok := conn2.(*net.TCPConn)
if ok {
tcpconn3.SetLinger(0)
}
if conn3 != nil {
conn3.Close()
}
if count >= 2 {
clientInfo.IpStatus = false
} else {
clientInfo.IpStatus = true
}
count = 0
}
//func getNetworkStatus() {
// defaulttimeout := 1 * time.Second
// count := 0
// conn1 , err1 := net.DialTimeout("tcp",CU_ADDR,defaulttimeout)
// if err1 != nil {
// fmt.Println("[getNetworkStatus]Error try to connect China unicom :", err1)
// count += 1
// }
// tcpconn1, ok := conn1.(*net.TCPConn)
// if ok {
// tcpconn1.SetLinger(0)
// }
// if conn1 != nil {
// conn1.Close()
// }
// conn2 , err2 := net.DialTimeout("tcp", CT_ADDR,defaulttimeout)
// if err2 != nil {
// fmt.Println("[getNetworkStatus]Error try to connect China telecom :", err2)
// count += 1
// }
// tcpconn2, ok := conn2.(*net.TCPConn)
// if ok {
// tcpconn2.SetLinger(0)
// }
// if conn2 != nil {
// conn2.Close()
// }
// conn3 , err3 := net.DialTimeout("tcp", CM_ADDR,defaulttimeout)
// if err3 != nil {
// fmt.Println("[getNetworkStatus]Error try to connect China mobile :", err3)
// count += 1
// }
// tcpconn3, ok := conn2.(*net.TCPConn)
// if ok {
// tcpconn3.SetLinger(0)
// }
// if conn3 != nil {
// conn3.Close()
// }
// if count >= 2 {
// clientInfo.IpStatus = false
// } else {
// clientInfo.IpStatus = true
// }
// count = 0
//}
func str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
@ -280,10 +197,13 @@ func SetupCloseHandler() {
<-c
fmt.Println("\r[main] Ctrl+C pressed in Terminal,Stop client program")
if mainConnect != nil {
pingValueCU.Stop()
pingValueCT.Stop()
pingValueCM.Stop()
if NETWORKCHECK == true {
pingValueCU.Stop()
pingValueCT.Stop()
pingValueCM.Stop()
}
netSpeed.Stop()
run.StopRunInfo()
mainConnect.Close()
}
os.Exit(0)
@ -292,6 +212,7 @@ func SetupCloseHandler() {
var mainConnect net.Conn
var netSpeed *NetSpeed
var run *Run
var pingValueCU *PingValue
var pingValueCT *PingValue
var pingValueCM *PingValue
@ -314,6 +235,7 @@ func main() {
data, err := ioutil.ReadFile(path)
if err != nil {
fmt.Printf("[main]Read config file error:%s\n",err)
goto Run
}
err = jsoniter.Unmarshal(data, &config)
if err != nil {
@ -346,6 +268,8 @@ func main() {
if config.Server != "" {
SERVER = config.Server
}
NETWORKCHECK = config.NetworkCheck
Run:
for _, args := range os.Args {
if strings.Index(args,"SERVER") > -1 {
strArr := strings.Split(args,"SERVER=")
@ -362,18 +286,28 @@ func main() {
} else if strings.Index( args,"INTERVAL") > -1{
strArr := strings.Split(args,"INTERVAL=")
INTERVAL, _ = strconv.Atoi(strArr[len(strArr)-1])
} else if strings.Index( args,"NETWORKCHECK") > -1{
strArr := strings.Split(args,"NETWORKCHECK=")
settings := strings.ToUpper(strArr[len(strArr)-1])
if strings.Index(settings,"FALSE") > -1 {
NETWORKCHECK = false
}
}
}
defaulttimeout := 30 * time.Second
clientInfo = NewDefaultClientInfo()
netSpeed = NewNetSpeed()
pingValueCU = NewPingValue()
pingValueCT = NewPingValue()
pingValueCM = NewPingValue()
pingValueCU.RunCU()
pingValueCT.RunCT()
pingValueCM.RunCM()
netSpeed.Run()
if NETWORKCHECK == true {
pingValueCU = NewPingValue()
pingValueCT = NewPingValue()
pingValueCM = NewPingValue()
pingValueCU.RunCU()
pingValueCT.RunCT()
pingValueCM.RunCM()
}
run = NewRunInfo()
run.StartGetRunInfo()
for {
var err error
mainConnect , err = net.DialTimeout("tcp", SERVER + ":" + strconv.Itoa(PORT),defaulttimeout)
@ -436,26 +370,35 @@ func main() {
// fmt.Println(str)
//}
//fmt.Println(checkIP)
var (
status10086 uint = 0
status189 uint = 0
status10010 uint = 0
)
for {
clientInfo.MemoryTotal = ram.Info().Total / 1024 // 需要转单位
clientInfo.MemoryUsed = ram.Info().Usage / 1024 // 需要转单位
clientInfo.CPU = cpu.Info().Usage
clientInfo.Uptime = host.Info().Uptime
//swap 没有造好的轮子,自己加的
swapMemory, _ := mem.SwapMemory()
clientInfo.SwapTotal = swapMemory.Total / 1024 // 需要转单位
clientInfo.SwapUsed = swapMemory.Used / 1024 // 需要转单位
getLoad()
tupd()
trafficCount()
spaceCount()
getNetworkStatus()
run.GetRunInfo()
//getNetworkStatus()
netSpeed.Get()
clientInfo.Ping10086, clientInfo.Time10086 = pingValueCM.Get()
clientInfo.Ping189, clientInfo.Time189 = pingValueCT.Get()
clientInfo.Ping10010, clientInfo.Time10010 = pingValueCU.Get()
if NETWORKCHECK {
clientInfo.Ping10086, clientInfo.Time10086, status10086 = pingValueCM.Get()
clientInfo.Ping189, clientInfo.Time189, status189 = pingValueCT.Get()
clientInfo.Ping10010, clientInfo.Time10010,status10010 = pingValueCU.Get()
if (status189+status10010+status10086) >= 2 {
clientInfo.IpStatus = false
} else {
clientInfo.IpStatus = true
}
} else {
clientInfo.Ping10086, clientInfo.Time10086 = 0.0,0
clientInfo.Ping189, clientInfo.Time189 = 0.0,0
clientInfo.Ping10010, clientInfo.Time10010 = 0.0,0
clientInfo.IpStatus = false
}
status10086 = 0
status189 = 0
status10010 = 0
//结构体转json字符串
data, err := jsoniter.MarshalToString(&clientInfo)
data, err := clientInfo.MarshalToString()
//fmt.Println(data)
if err != nil {
fmt.Println("[main]Error transforming client info: ", err)
@ -472,4 +415,25 @@ func main() {
}
func (info *ClientInfo) MarshalToString() (string, error) {
type Alias ClientInfo
return jsoniter.MarshalToString(&struct {
CPU float64 `json:"cpu"`
Ping10010 float64 `json:"ping_10010"`
Ping10086 float64 `json:"ping_10086"`
Ping189 float64 `json:"ping_189"`
Load1 float64 `json:"load_1"`
Load5 float64 `json:"load_5"`
Load15 float64 `json:"load_15"`
*Alias
}{
CPU: info.CPU,
Ping10010: info.Ping10010,
Ping10086: info.Ping10086,
Ping189: info.Ping189,
Load1: info.Load1,
Load5: info.Load5,
Load15: info.Load15,
Alias: (*Alias)(info),
})
}

View File

@ -33,7 +33,7 @@ func NewNetSpeed() *NetSpeed{
func (netSpeed *NetSpeed) Run() {
go func() {
t1 := time.Duration(INTERVAL) * time.Second
t1 := time.Duration(1) * time.Second
t := time.NewTicker(t1)
for {
select {

View File

@ -9,6 +9,7 @@ import (
type PingValue struct {
ping uint64
status uint
lostRate float64
stop chan struct{}
mtx sync.Mutex
@ -16,6 +17,7 @@ type PingValue struct {
func NewPingValue() *PingValue {
return &PingValue{
status: 0,
ping: 0.0,
lostRate: 0.0,
stop: make (chan struct{}),
@ -63,8 +65,10 @@ func (pingValue *PingValue) RunCU() {
//fmt.Printf("%10d %10d %10f\n",allPacket,lostPacket,pingValue.lostRate)
if lostConnect {
pingValue.ping = 0
pingValue.status = 1
} else {
pingValue.ping = uint64(diffTime/time.Millisecond)
pingValue.status = 0
}
lostConnect = false
resetTime := uint64(time.Since(startTime) / time.Second)
@ -116,8 +120,10 @@ func (pingValue *PingValue) RunCT() {
}
if lostConnect {
pingValue.ping = 0
pingValue.status = 1
} else {
pingValue.ping = uint64(diffTime/time.Millisecond)
pingValue.status = 0
}
lostConnect = false
resetTime := uint64(time.Since(startTime) / time.Second)
@ -169,8 +175,10 @@ func (pingValue *PingValue) RunCM() {
}
if lostConnect {
pingValue.ping = 0
pingValue.status = 1
} else {
pingValue.ping = uint64(diffTime/time.Millisecond)
pingValue.status = 0
}
lostConnect = false
resetTime := uint64(time.Since(startTime) / time.Second)
@ -189,8 +197,10 @@ func (pingValue *PingValue) Stop() {
close(pingValue.stop)
}
func (pingValue *PingValue) Get() (float64,uint64) {
func (pingValue *PingValue) Get() (float64,uint64,uint) {
pingValue.mtx.Lock()
defer pingValue.mtx.Unlock()
return pingValue.lostRate,pingValue.ping
status := pingValue.status
pingValue.status = 0
return pingValue.lostRate,pingValue.ping,status
}

View File

@ -0,0 +1,221 @@
package main
import (
"fmt"
"strings"
"sync"
"time"
"github.com/shirou/gopsutil/host"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
"github.com/shirou/gopsutil/load"
"github.com/shirou/gopsutil/mem"
nnet "github.com/shirou/gopsutil/net"
)
type Run struct {
memoryTotal uint64
memoryUsed uint64
CPU float64
uptime uint64
swapTotal uint64
swapUsed uint64
load1 float64
load5 float64
load15 float64
networkIn uint64
networkOut uint64
hddUsed uint64
hddTotal uint64
stop chan struct{}
mtx sync.Mutex
}
func NewRunInfo() *Run{
return &Run{
memoryTotal: 0,
memoryUsed: 0,
CPU: 0.0,
uptime: 0,
swapTotal: 0,
swapUsed: 0,
load1: 0.0,
load5: 0.0,
load15: 0.0,
networkIn: 0,
networkOut: 0,
hddUsed: 0,
hddTotal: 0,
stop: make (chan struct{}),
}
}
func (run *Run) StopRunInfo() {
close(run.stop)
}
func (run *Run) GetRunInfo() {
run.mtx.Lock()
defer run.mtx.Unlock()
clientInfo.HddUsed = run.hddUsed
clientInfo.HddTotal = run.hddTotal
clientInfo.MemoryTotal = run.memoryTotal
clientInfo.MemoryUsed = run.memoryUsed
clientInfo.CPU = run.CPU
clientInfo.Uptime = run.uptime
clientInfo.SwapTotal = run.swapTotal
clientInfo.SwapUsed = run.swapUsed
clientInfo.NetworkIn = run.networkIn
clientInfo.NetworkOut = run.networkOut
clientInfo.Load1 = run.load1
clientInfo.Load5 = run.load5
clientInfo.Load15 = run.load15
}
func (run *Run) StartGetRunInfo() {
go func() {
t1 := time.Duration(1) * time.Second
t := time.NewTicker(t1)
for {
select {
case <- run.stop:
t.Stop()
return
case <-t.C:
run.mtx.Lock()
memInfo, err := mem.VirtualMemory()
if err != nil {
fmt.Println("[getInfo]Get memory usage error:",err)
run.memoryTotal = 0
run.memoryUsed = 0
} else {
run.memoryTotal = memInfo.Total / 1024 // 需要转单位
run.memoryUsed = memInfo.Used / 1024 // 需要转单位
}
totalPercent, err := cpu.Percent(time.Second, false)
if err != nil {
fmt.Println("[GetInfo]Get cpu usage error:",err)
run.CPU = 0.0
} else {
if totalPercent != nil {
run.CPU = totalPercent[0]
} else {
fmt.Println("[getInfo]Get cpu usage error:",err)
}
}
hInfo, err := host.Info()
if err != nil {
fmt.Println("[getInfo]get uptime error",err)
clientInfo.Uptime = 0
} else {
clientInfo.Uptime = hInfo.Uptime
}
//swap 没有造好的轮子,自己加的
swapMemory, err := mem.SwapMemory()
if err != nil {
fmt.Println("[getInfo]Get swap memory error:",err)
run.swapTotal = 0
run.swapUsed = 0
} else {
run.swapTotal = swapMemory.Total / 1024 // 需要转单位
run.swapUsed = swapMemory.Used / 1024 // 需要转单位
}
getLoad()
trafficCount()
spaceCount()
tupd()
run.mtx.Unlock()
}
}
}()
}
func trafficCount() {
netInfo, err := nnet.IOCounters(true)
if err != nil {
fmt.Println("[trafficCount]Getting traffic count error:",err)
}
var bytesSent uint64 = 0
var bytesRecv uint64 = 0
for _, v := range netInfo {
if strings.Index(v.Name,"lo") > -1 ||
strings.Index(v.Name,"tun") > -1 ||
strings.Index(v.Name,"docker") > -1 ||
strings.Index(v.Name,"veth") > -1 ||
strings.Index(v.Name,"br-") > -1 ||
strings.Index(v.Name,"vmbr") > -1 ||
strings.Index(v.Name,"vnet") > -1 ||
strings.Index(v.Name,"kube") > -1 {
continue
}
bytesSent += v.BytesSent
bytesRecv += v.BytesRecv
}
run.networkIn = bytesRecv
run.networkOut = bytesSent
}
func spaceCount() {
// golang 没有类似于在 python 的 dict 或 tuple 的 in 查找关键字,自己写多重判断实现
diskList, _ := disk.Partitions(false)
var total uint64 = 0
var used uint64 = 0
for _,d := range diskList {
fsType := strings.ToLower(d.Fstype)
//fmt.Println(d.Fstype)
if strings.Index(fsType, "ext4") < 0 &&
strings.Index(fsType, "ext3") < 0 &&
strings.Index(fsType, "ext2") < 0 &&
strings.Index(fsType, "reiserfs") < 0 &&
strings.Index(fsType, "jfs") < 0 &&
strings.Index(fsType, "btrfs") < 0 &&
strings.Index(fsType, "fuseblk") < 0 &&
strings.Index(fsType, "zfs") < 0 &&
strings.Index(fsType, "simfs") < 0 &&
strings.Index(fsType, "ntfs")< 0 &&
strings.Index(fsType, "fat32") < 0 &&
strings.Index(fsType, "exfat") < 0 &&
strings.Index(fsType, "xfs") < 0 {
} else {
if strings.Index(d.Device, "Z:") > -1 { //特殊盘符自己写处理
continue
} else {
diskUsageOf, _ := disk.Usage(d.Mountpoint)
used += diskUsageOf.Used
total += diskUsageOf.Total
}
}
}
run.hddUsed = used / 1024.0 / 1024.0
run.hddTotal = total / 1024.0 / 1024.0
}
func getLoad() {
// linux or freebsd only
hInfo, err := host.Info()
if err != nil {
fmt.Println("[getLoad]get load info error",err)
run.load1 = 0.0
run.load5 = 0.0
run.load15 = 0.0
} else {
if hInfo.OS == "linux" || hInfo.OS == "freebsd" {
l, err := load.Avg()
if err != nil {
fmt.Println("[getLoad]Get CPU loads failed:",err)
run.load1 = 0.0
run.load5 = 0.0
run.load15 = 0.0
} else {
run.load1 = l.Load1
run.load5 = l.Load5
run.load15 = l.Load15
}
} else {
run.load1 = 0.0
run.load5 = 0.0
run.load15 = 0.0
}
}
}