Browse Source

第一次提交

zuoxiupeng 3 years ago
parent
commit
082e3e1644
100 changed files with 32887 additions and 0 deletions
  1. 1 0
      License
  2. 5 0
      build.bat
  3. 25 0
      config/cfg.ini
  4. 117 0
      control
  5. 212 0
      http/http.go
  6. 61 0
      http/websocket.go
  7. 13 0
      i18n/en_US.json
  8. 0 0
      i18n/zh-CN.json
  9. 4 0
      libs/collection/collection.go
  10. 46 0
      libs/collection/cpuinfo.go
  11. 84 0
      libs/collection/disk.go
  12. 15 0
      libs/collection/host.go
  13. 19 0
      libs/collection/load.go
  14. 36 0
      libs/collection/meminfo.go
  15. 82 0
      libs/collection/network.go
  16. 166 0
      libs/collection/ping.go
  17. 47 0
      libs/collection/process.go
  18. 128 0
      libs/collection/process_unix.go
  19. 75 0
      libs/collection/process_windows.go
  20. 106 0
      libs/collection/stat.go
  21. 92 0
      libs/common/aes.go
  22. 102 0
      libs/common/common.go
  23. 19 0
      libs/common/exec.go
  24. 51 0
      libs/common/license.go
  25. 14 0
      libs/common/logs.go
  26. 5 0
      libs/common/rootdir_unix.go
  27. 5 0
      libs/common/rootdir_windows.go
  28. 116 0
      libs/config/config.go
  29. 2 0
      libs/modules/config/ping_hosts
  30. 17 0
      libs/modules/shell_files/arp_cache.sh
  31. 6 0
      libs/modules/shell_files/bandwidth.sh
  32. 11 0
      libs/modules/shell_files/common_applications.sh
  33. 7 0
      libs/modules/shell_files/cpu_info.sh
  34. 13 0
      libs/modules/shell_files/cpu_intensive_processes.sh
  35. 33 0
      libs/modules/shell_files/cpu_utilization.sh
  36. 18 0
      libs/modules/shell_files/cron_history.sh
  37. 14 0
      libs/modules/shell_files/current_ram.sh
  38. 4 0
      libs/modules/shell_files/disk_partitions.sh
  39. 40 0
      libs/modules/shell_files/download_transfer_rate.sh
  40. 28 0
      libs/modules/shell_files/general_info.sh
  41. 9 0
      libs/modules/shell_files/internet_speed.sh
  42. 7 0
      libs/modules/shell_files/io_stats.sh
  43. 15 0
      libs/modules/shell_files/ip_addresses.sh
  44. 10 0
      libs/modules/shell_files/load_avg.sh
  45. 4 0
      libs/modules/shell_files/logged_in_users.sh
  46. 7 0
      libs/modules/shell_files/memcached.sh
  47. 4 0
      libs/modules/shell_files/memory_info.sh
  48. 13 0
      libs/modules/shell_files/network_connections.sh
  49. 7 0
      libs/modules/shell_files/number_of_cpu_cores.sh
  50. 28 0
      libs/modules/shell_files/ping.sh
  51. 12 0
      libs/modules/shell_files/ram_intensive_processes.sh
  52. 10 0
      libs/modules/shell_files/recent_account_logins.sh
  53. 18 0
      libs/modules/shell_files/redis.sh
  54. 88 0
      libs/modules/shell_files/scheduled_crons.sh
  55. 5 0
      libs/modules/shell_files/swap.sh
  56. 40 0
      libs/modules/shell_files/upload_transfer_rate.sh
  57. 14 0
      libs/modules/shell_files/user_accounts.sh
  58. 1 0
      libs/timedtask/kpi.go
  59. 16 0
      libs/timedtask/license.go
  60. 1 0
      libs/timedtask/timedtask.go
  61. 9875 0
      logs/error.log
  62. 87 0
      main.go
  63. 45 0
      public/20160321
  64. 232 0
      public/application.html
  65. 350 0
      public/basic-info.html
  66. BIN
      public/favicon.ico
  67. 342 0
      public/index.html
  68. 311 0
      public/network.html
  69. 14480 0
      public/static/css/components-rounded.css
  70. 19 0
      public/static/css/custom.css
  71. 2428 0
      public/static/css/layout.css
  72. 2570 0
      public/static/css/plugins.css
  73. BIN
      public/static/img/accordion-plusminus.png
  74. BIN
      public/static/img/ajax-loading.gif
  75. BIN
      public/static/img/ajax-modal-loading.gif
  76. BIN
      public/static/img/avatar.png
  77. BIN
      public/static/img/datatable-row-openclose.png
  78. BIN
      public/static/img/input-spinner.gif
  79. BIN
      public/static/img/loading-spinner-blue.gif
  80. BIN
      public/static/img/loading-spinner-default.gif
  81. BIN
      public/static/img/loading-spinner-grey.gif
  82. BIN
      public/static/img/loading.gif
  83. BIN
      public/static/img/logo.jpg
  84. BIN
      public/static/img/logo.png
  85. BIN
      public/static/img/menu-toggler.png
  86. BIN
      public/static/img/overlay-icon.png
  87. BIN
      public/static/img/portlet-collapse-icon-white.png
  88. BIN
      public/static/img/portlet-collapse-icon.png
  89. BIN
      public/static/img/portlet-config-icon-white.png
  90. BIN
      public/static/img/portlet-config-icon.png
  91. BIN
      public/static/img/portlet-expand-icon-white.png
  92. BIN
      public/static/img/portlet-expand-icon.png
  93. BIN
      public/static/img/portlet-reload-icon-white.png
  94. BIN
      public/static/img/portlet-reload-icon.png
  95. BIN
      public/static/img/portlet-remove-icon-white.png
  96. BIN
      public/static/img/portlet-remove-icon.png
  97. BIN
      public/static/img/remove-icon-small.png
  98. BIN
      public/static/img/social/Thumbs.db
  99. BIN
      public/static/img/social/aboutme.png
  100. 0 0
      public/static/img/social/amazon.png

+ 1 - 0
License

@@ -0,0 +1 @@
+W36fR5EjoA0FGfFBqYGqtimZZJTdw3cOlNOm9QD307zlfDkh1TqTU4W1pgLrWALOAcmsAny5iQBCpQLLyulsHq0uQow80UmXKZ0JVLTZaIA=

+ 5 - 0
build.bat

@@ -0,0 +1,5 @@
+@echo off
+echo compiling...
+go build -ldflags -H=windowsgui
+echo Compile complete.
+@pause

+ 25 - 0
config/cfg.ini

@@ -0,0 +1,25 @@
+[http]
+enabled = 1
+ipaddr = 0.0.0.0
+port = 88
+static_path = /public/
+script_path = /libs/modules/shell_files
+
+[tcp]
+ipaddr = 0.0.0.0
+port = 1991
+
+[websocket]
+enabled = 1
+ipaddr = 0.0.0.0
+port = 2016
+
+[ping]
+url = www.baidu.com,www.sina.cn,www.baidu.com,www.sina.cn,www.baidu.com,www.sina.cn,www.sina.cn,www.baidu.com,www.sina.cn,www.baidu.com,www.sina.cn
+count = 2
+
+[process]
+php = /bin/php5/php
+htrd-agent = ./htrd-agent
+test = /usr/libexec/secinitd
+mysqld = /Applications/XAMPP/xamppfiles/sbin/mysqld

+ 117 - 0
control

@@ -0,0 +1,117 @@
+#!/bin/bash
+
+WORKSPACE=$(cd $(dirname $0)/; pwd)
+cd $WORKSPACE
+
+mkdir -p var
+
+module=agent
+app=htrd-$module
+version=1.0
+pidfile=var/agent.pid
+logfile=var/agent.log
+
+function check_pid() {
+    if [ -f $pidfile ];then
+        pid=`cat $pidfile`
+        if [ -n $pid ]; then
+            running=`ps -p $pid|grep -v "PID TTY" |wc -l`
+            return $running
+        fi
+    fi
+    return 0
+}
+
+function start() {
+    check_pid
+    running=$?
+    if [ $running -gt 0 ];then
+        echo -n "$app now is running already, pid="
+        cat $pidfile
+        return 1
+    fi
+
+    nohup ./$app &> $logfile &
+    sleep 1
+    running=`ps -p $! | grep -v "PID TTY" | wc -l`
+    if [ $running -gt 0 ];then
+        echo $! > $pidfile
+        echo "$app started..., pid=$!"
+    else
+        echo "$app failed to start."
+        return 1
+    fi
+}
+
+function stop() {
+    pid=`cat $pidfile`
+    kill $pid
+    rm -f $pidfile
+    echo "$app stoped..."
+}
+
+function restart() {
+    stop
+    sleep 1
+    start
+}
+
+function status() {
+    check_pid
+    running=$?
+    if [ $running -gt 0 ];then
+        echo started
+    else
+        echo stoped
+    fi
+}
+
+function tailf() {
+    tail -f $logfile
+}
+
+function build() {
+    go build
+    if [ $? -ne 0 ]; then
+        exit $?
+    fi
+    mv $module $app
+}
+
+function pack() {
+    build
+    file_list="public control logs i18n config License README.md $app"
+    echo "...tar $app-$version.tar.gz <= $file_list"
+    tar zcf $app-$version.tar.gz $file_list
+}
+
+function packbin() {
+    build
+    tar zcvf $app-bin-$version.tar.gz $app
+}
+
+function help() {
+    echo "$0 build|pack|start|stop|restart|status|tail"
+}
+
+if [ "$1" == "" ]; then
+    help
+elif [ "$1" == "stop" ];then
+    stop
+elif [ "$1" == "start" ];then
+    start
+elif [ "$1" == "restart" ];then
+    restart
+elif [ "$1" == "status" ];then
+    status
+elif [ "$1" == "tail" ];then
+    tailf
+elif [ "$1" == "build" ];then
+    build
+elif [ "$1" == "pack" ];then
+    pack
+elif [ "$1" == "packbin" ];then
+    packbin
+else
+    help
+fi

+ 212 - 0
http/http.go

@@ -0,0 +1,212 @@
+package http
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"strconv"
+	"time"
+
+	"53it.net/agent/libs/collection"
+	"53it.net/agent/libs/common"
+	"53it.net/agent/libs/config"
+)
+
+// 画线数据,每条线数据结构
+type Plot struct {
+	Key   string `json:"key"`
+	Value string `json:"value"`
+}
+
+// 最终数据结构
+type Data struct {
+	State string `json:"state"`
+	Msg   string `json:"msg"`
+	Data  Lists  `json:"data"`
+	Time  string `json:"time"`
+}
+
+// ajax每行内容
+type ListRow interface{}
+
+// ajax列表数据
+type Lists []ListRow
+
+// ajax请求包
+type T struct {
+	ModuleName string `json:"module_name"`
+	Time       string `json:"time"`
+}
+
+// 启动http服务
+func StartHttp() {
+	// 获取配置文件http服务配置
+	listenAddress := config.CFG.Http.Ipaddr + ":" + config.CFG.Http.Port // 启动ip和端口
+	staticPath := common.GetRootDir() + config.CFG.Http.StaticPath       // 静态文件路径
+
+	// 静态文件服务器
+	http.Handle("/", http.FileServer(http.Dir(staticPath)))
+	// ajax请求数据表数据
+	http.HandleFunc("/data/", httpAjaxTableData)
+	// 重置配置文件
+	http.HandleFunc("/config/", httpAjaxConfig)
+
+	fmt.Println("正在启动http服务:", listenAddress)
+	err := http.ListenAndServe(listenAddress, nil)
+	if err != nil {
+		fmt.Println("http服务启动失败:", err)
+		common.LogFile.W(fmt.Sprintf("http服务启动失败:%s", err.Error()), "http", "StartHttp")
+	}
+}
+
+// 处理ajax请求的表格数据
+func httpAjaxTableData(w http.ResponseWriter, r *http.Request) {
+	// 接收参数
+	module := r.URL.Query().Get("module_name")
+	// 当前时间
+	strTime := time.Now().Format("15:04:05")
+	// 最终发送的数据包
+	data := &Data{State: "0", Msg: module, Time: strTime}
+	// 判断是否未传参数
+	if len(module) > 0 {
+		// 根据modelname获取列表数据
+		plot := getDataList(module)
+		data.Data = plot
+	} else {
+		data.State = "1"
+		data.Data = Lists{}
+	}
+	// 转json
+	wdata, err := json.Marshal(data)
+	if err != nil {
+		common.LogFile.E("ajax输出转json失败", "http", "httpAjaxTableData")
+	}
+	// 发送数据
+	w.Write(wdata)
+}
+
+// 配置文件操作
+func httpAjaxConfig(w http.ResponseWriter, r *http.Request) {
+	// 接收参数
+	module := r.URL.Query().Get("handle")
+	// 最终发送的数据包
+	data := &Data{State: "0", Msg: module, Data: Lists{}}
+	if len(module) > 0 {
+		err := config.ResetConfig()
+		if err != nil {
+			data.Msg = "配置文件重置失败"
+		} else {
+			data.Msg = "配置文件已重置"
+		}
+	} else {
+		data.State = "1"
+		data.Msg = "参数错误"
+	}
+	// 转json
+	wdata, err := json.Marshal(data)
+	if err != nil {
+		common.LogFile.E("ajax输出转json失败", "http", "httpAjaxConfig")
+	}
+	// 发送数据
+	w.Write(wdata)
+}
+
+// 获取列表内容
+func getDataList(moduleName string) (plot Lists) {
+	switch moduleName {
+	case "ram_usage":
+		v := collection.GetMemUsageRate()
+		plot = append(plot, Plot{Key: strconv.FormatInt(time.Now().Unix(), 10), Value: fmt.Sprintf("%2f", v)})
+		break
+	case "cpu_utilization":
+		v := collection.GetCPUUsageRate()
+		plot = append(plot, Plot{Key: strconv.FormatInt(time.Now().Unix(), 10), Value: fmt.Sprintf("%2f", v)})
+		break
+	case "cpu_avg_load":
+		v1, v5, v15 := collection.GetLoadAvg()
+		plot = append(plot, Plot{Key: strconv.FormatInt(time.Now().Unix(), 10), Value: fmt.Sprintf("%2f", v1)})
+		plot = append(plot, Plot{Key: strconv.FormatInt(time.Now().Unix(), 10), Value: fmt.Sprintf("%2f", v5)})
+		plot = append(plot, Plot{Key: strconv.FormatInt(time.Now().Unix(), 10), Value: fmt.Sprintf("%2f", v15)})
+		break
+	case "ram_Intensive_processes":
+		rams := collection.GetRAMIntensiveProcesses()
+		for _, v := range rams {
+			plot = append(plot, v)
+		}
+		break
+	case "disk_processes":
+		disks, _ := collection.GetDiskUsages()
+		for _, v := range disks {
+			plot = append(plot, v)
+		}
+		break
+	case "general_info":
+		hostInfo := collection.GetHostInfo()
+		plot = append(plot, hostInfo)
+		break
+	case "mem_info":
+		memInfo := collection.GetMenInfos()
+		plot = append(plot, memInfo)
+		break
+	case "cpu_info":
+		cpuInfo := collection.GetCPUInfos()
+		for _, v := range cpuInfo {
+			plot = append(plot, v)
+		}
+		break
+	case "disk_io_stat":
+		diskIo := collection.GetDiskIOCountersStat()
+		for _, v := range diskIo {
+			plot = append(plot, v)
+		}
+		break
+	case "network_flow":
+		netFlow := collection.GetNetworkFlow()
+		for _, v := range netFlow {
+			plot = append(plot, v)
+		}
+		break
+	case "network_addrs":
+		netAddrs := collection.GetNetworkAddrs()
+		for _, v := range netAddrs {
+			plot = append(plot, v)
+		}
+		break
+	case "ping":
+		pings, err := collection.PingConf()
+		if err == nil {
+			for _, v := range pings {
+				plot = append(plot, v)
+			}
+		}
+		break
+	case "processes_run":
+		runs, err := collection.ChackProcessCmd()
+		if err == nil {
+			for _, v := range runs {
+				plot = append(plot, v)
+			}
+		}
+		break
+	case "network_client_count":
+		netCount := collection.GetNetworkClientCount()
+		plot = append(plot, netCount)
+		break
+	case "disk_io_kbps":
+		diskKbps := collection.GetDiskIOKbps()
+		for _, v := range diskKbps {
+			plot = append(plot, v)
+		}
+		break
+	case "processes_count":
+		count := collection.GetProcessCount()
+		plot = append(plot, count)
+		break
+	}
+
+	if len(plot) == 0 {
+		plot = make(Lists, 0)
+	}
+
+	return plot
+}

+ 61 - 0
http/websocket.go

@@ -0,0 +1,61 @@
+package http
+
+import (
+	"fmt"
+	"net/http"
+	"time"
+
+	"53it.net/agent/libs/common"
+
+	"53it.net/agent/libs/config"
+	"golang.org/x/net/websocket"
+)
+
+// 启动Websocket服务
+func StartWebsocket() {
+	// 监听/json路径
+	http.Handle("/json", websocket.Handler(jsonServer))
+	socketAddress := config.CFG.Websocket.Ipaddr + ":" + config.CFG.Websocket.Port
+	fmt.Println("启动websocket服务:", socketAddress)
+	err := http.ListenAndServe(socketAddress, nil)
+	if err != nil {
+		fmt.Println("websocket服务启动失败:", err)
+		common.LogFile.W(fmt.Sprintf("websocket服务启动失败:%s", err.Error()), "http", "StartWebsocket")
+	}
+}
+
+// websocket 使用json通讯
+func jsonServer(ws *websocket.Conn) {
+	common.LogFile.I("有客户端链接上了websocket", "http", "jsonServer")
+	//	fmt.Println("jsonServer 连接成功")
+	for {
+		// 接收信息转成json数据
+		var msg T
+		err := websocket.JSON.Receive(ws, &msg)
+		if err != nil {
+			common.LogFile.W(fmt.Sprintf("接收数据转失败:%s", err.Error()), "http", "jsonServer")
+			break
+		}
+		//fmt.Printf("recv:%#v\n", msg)
+
+		go timedTask(ws, msg) // 处理一个表格数据-开一个协程
+	}
+}
+
+// 定时发送数据到客户端
+func timedTask(ws *websocket.Conn, msg T) {
+	// 根据modelname获取列表数据
+	plot := getDataList(msg.ModuleName)
+	// 当前时间
+	strTime := time.Now().Format("15:04:05")
+	// 最终发送的数据包
+	data := &Data{State: "0", Msg: msg.ModuleName, Data: plot, Time: strTime}
+	err := websocket.JSON.Send(ws, data)
+	if err != nil {
+		common.LogFile.W(fmt.Sprintf("发送数据转失败:%s", err.Error()), "http", "timedTask")
+		fmt.Println(err)
+		ws.Close()
+		return
+	}
+	return
+}

+ 13 - 0
i18n/en_US.json

@@ -0,0 +1,13 @@
+{
+    "main.title" : "CutleryPlus",
+    "main.subtitle" : "Knives that put cut in cutlery.",
+    "menu" : {
+    	"home" : "Home",
+    	"products": {
+    		"self": "Products",
+    		"forks" : "Forks",
+    		"knives" : "Knives",
+    		"spoons" : "Spoons"
+    	}
+    }
+}

+ 0 - 0
i18n/zh-CN.json


+ 4 - 0
libs/collection/collection.go

@@ -0,0 +1,4 @@
+package collection
+
+func init() {
+}

+ 46 - 0
libs/collection/cpuinfo.go

@@ -0,0 +1,46 @@
+package collection
+
+import (
+	"runtime"
+	"strconv"
+	"time"
+
+	"53it.net/agent/libs/common"
+	"github.com/shirou/gopsutil/cpu"
+)
+
+// cpu 利用率
+func GetCPUUsageRate() float64 {
+	c, err := cpu.CPUTimes(false)
+	if err != nil {
+		common.LogFile.W("计算cpu使用率,获取内存信息失败", "cpuinfo", "GetCPUUsageRate")
+		return 0.0
+	}
+	// 获取两次数据求差
+	cc := c[0]
+	idel1 := cc.Idle
+	total1 := cc.Idle + cc.Guest + cc.GuestNice + cc.Iowait + cc.Irq + cc.Nice + cc.Softirq + cc.Steal + cc.Stolen + cc.System + cc.User
+	// 睡1秒
+	time.Sleep(1 * time.Second)
+	c, _ = cpu.CPUTimes(false)
+	cc = c[0]
+	idel2 := c[0].Idle
+	tota2 := cc.Idle + cc.Guest + cc.GuestNice + cc.Iowait + cc.Irq + cc.Nice + cc.Softirq + cc.Steal + cc.Stolen + cc.System + cc.User
+
+	return (1000*((tota2-total1)-(idel2-idel1))/(tota2-total1) + 5) / 10
+}
+
+// cpu核心数
+func CpuNum() string {
+	return strconv.Itoa(runtime.NumCPU())
+}
+
+// 获取cpu信息
+func GetCPUInfos() []cpu.CPUInfoStat {
+	cpuInfo, err := cpu.CPUInfo()
+	if err != nil {
+		common.LogFile.W("获取内存信息失败", "meninfo", "GetMenInfos")
+		return nil
+	}
+	return cpuInfo
+}

+ 84 - 0
libs/collection/disk.go

@@ -0,0 +1,84 @@
+package collection
+
+import (
+	"strconv"
+	"time"
+
+	"53it.net/agent/libs/common"
+	"github.com/shirou/gopsutil/disk"
+)
+
+type Disk struct {
+	Name              string `json:"name"`
+	Path              string `json:"path"`
+	Total             string `json:"total"`
+	Free              string `json:"free"`
+	Used              string `json:"used"`
+	UsedPercent       string `json:"used_percent"`
+	InodesUsedPercent string `json:"inodes_used_percent"`
+}
+
+type DiskIO struct {
+	Name       string `json:"name"`
+	ReadBytes  uint64 `json:"read_bytes"`
+	WriteBytes uint64 `json:"write_bytes"`
+	ReadCount  uint64 `json:"read_count"`
+	WriteCount uint64 `json:"write_count"`
+}
+
+// 获取各磁盘分区使用率
+func GetDiskUsages() ([]Disk, error) {
+	dList, err := disk.DiskPartitions(true)
+	if err != nil {
+		common.LogFile.W("磁盘使用率获取失败,磁盘列表", "disk", "GetDiskUsages")
+		return nil, err
+	}
+	// 定义返回数组
+	var diskList []Disk
+	for _, v := range dList {
+		dUsage, err := disk.DiskUsage(v.Mountpoint)
+		if err != nil {
+			continue
+		}
+		d := Disk{Name: v.Device, Path: v.Mountpoint, Total: common.FormatUnit(dUsage.Total), Free: common.FormatUnit(dUsage.Free), Used: common.FormatUnit(dUsage.Used), UsedPercent: strconv.FormatFloat(dUsage.UsedPercent, 'g', 5, 32), InodesUsedPercent: strconv.FormatFloat(dUsage.InodesUsedPercent, 'g', 5, 32)}
+		diskList = append(diskList, d)
+	}
+	return diskList, nil
+}
+
+// 获取磁盘读写速率
+func GetDiskIOCountersStat() map[string]disk.DiskIOCountersStat {
+	diskIo, err := disk.DiskIOCounters()
+	if err != nil {
+		common.LogFile.W("磁盘IO获取失败", "disk", "GetDiskIOCountersStat")
+		return nil
+	}
+	return diskIo
+}
+
+// shi shi disk du xie
+func GetDiskIOKbps() []DiskIO {
+	diskIo1, err := disk.DiskIOCounters()
+	if err != nil {
+		common.LogFile.W("磁盘IO获取失败", "disk", "GetDiskIOKbps")
+		return nil
+	}
+	// 停一秒
+	time.Sleep(1 * time.Second)
+	diskIo2, err := disk.DiskIOCounters()
+	// ji suan mei miao du xie shu
+	var diskList []DiskIO
+	for _, v := range diskIo1 {
+		for _, vv := range diskIo2 {
+			if v.Name == vv.Name {
+				diskOne := DiskIO{Name: v.Name, ReadCount: vv.ReadCount, WriteCount: vv.WriteCount}
+				// ji suan cha zhi
+				diskOne.ReadBytes = vv.ReadBytes - v.ReadBytes
+				diskOne.WriteBytes = vv.WriteBytes - v.WriteBytes
+				// zhui jia dao shu zu
+				diskList = append(diskList, diskOne)
+			}
+		}
+	}
+	return diskList
+}

+ 15 - 0
libs/collection/host.go

@@ -0,0 +1,15 @@
+package collection
+
+import (
+	"53it.net/agent/libs/common"
+	"github.com/shirou/gopsutil/host"
+)
+
+func GetHostInfo() *host.HostInfoStat {
+	info, err := host.HostInfo()
+	if err != nil {
+		common.LogFile.W("获取系统基本信息失败", "host", "GetHostInfo")
+		return nil
+	}
+	return info
+}

+ 19 - 0
libs/collection/load.go

@@ -0,0 +1,19 @@
+package collection
+
+import (
+	"runtime"
+
+	"53it.net/agent/libs/common"
+	"github.com/shirou/gopsutil/load"
+)
+
+// 内存使用率
+func GetLoadAvg() (float64, float64, float64) {
+	loadinfo, err := load.LoadAvg()
+	if err != nil {
+		common.LogFile.W("获取1,5,15分钟平均负载失败", "load", "GetLoadAvg")
+		return 0.0, 0.0, 0.0
+	}
+	numberOfCores := float64(runtime.NumCPU()) // cpu核心数
+	return loadinfo.Load1 * 100 / numberOfCores, loadinfo.Load5 * 100 / numberOfCores, loadinfo.Load15 * 100 / numberOfCores
+}

+ 36 - 0
libs/collection/meminfo.go

@@ -0,0 +1,36 @@
+package collection
+
+import (
+	"53it.net/agent/libs/common"
+	"github.com/shirou/gopsutil/mem"
+)
+
+// 内存使用率
+func GetMemUsageRate() float64 {
+	meminfo, err := mem.VirtualMemory()
+	if err != nil {
+		common.LogFile.W("计算内存使用率,获取内存信息失败", "meninfo", "GetMemUsageRate")
+		return 0.0
+	}
+	return meminfo.UsedPercent
+}
+
+// 后去内存大小
+func GetMenSize() (uint64, error) {
+	meminfo, err := mem.VirtualMemory()
+	if err != nil {
+		common.LogFile.W("获取内存大小失败", "meninfo", "GetMenSize")
+		return 0, err
+	}
+	return meminfo.Total, nil
+}
+
+// 获取内存基本信息
+func GetMenInfos() *mem.VirtualMemoryStat {
+	meminfo, err := mem.VirtualMemory()
+	if err != nil {
+		common.LogFile.W("获取内存信息失败", "meninfo", "GetMenInfos")
+		return nil
+	}
+	return meminfo
+}

+ 82 - 0
libs/collection/network.go

@@ -0,0 +1,82 @@
+package collection
+
+import (
+	"time"
+
+	"53it.net/agent/libs/common"
+
+	"github.com/shirou/gopsutil/net"
+)
+
+type NetFlow struct {
+	Name      string `json:"name"`
+	BytesSent uint64 `json:"bytes_sent"`
+	BytesRecv uint64 `json:"bytes_recv"`
+}
+
+type NetAddr struct {
+	Name  string                 `json:"name"`
+	Addrs []net.NetInterfaceAddr `json:"addrs"`
+	RX    uint64                 `json:"rx"` // 发出数据包
+	TX    uint64                 `json:"tx"` // 接收数据包
+}
+
+// 网络流量
+func GetNetworkFlow() []NetFlow {
+	netFlow, err := net.NetIOCounters(true)
+	if err != nil {
+		common.LogFile.W("获取网络流量失败", "network", "GetNetworkFlow")
+		return nil
+	}
+	// 停一秒
+	time.Sleep(1 * time.Second)
+	netFlow1, err := net.NetIOCounters(true)
+	// 计算流量
+	var netFlowList []NetFlow
+
+	for k, v := range netFlow {
+		for _, vv := range netFlow1 {
+			if v.Name == vv.Name {
+				sent := netFlow1[k].BytesSent - v.BytesSent
+				recv := netFlow1[k].BytesRecv - v.BytesRecv
+				netFlowList = append(netFlowList, NetFlow{Name: v.Name, BytesSent: sent, BytesRecv: recv})
+			}
+		}
+	}
+	return netFlowList
+}
+
+// 获取网卡喝ip地址流量信息
+func GetNetworkAddrs() []NetAddr {
+	netAddrs, err := net.NetIOCounters(true)
+	if err != nil {
+		common.LogFile.W("获取网卡基本信息失败", "network", "GetNetworkAddrs")
+		return nil
+	}
+	// 获取网卡信息
+	netInfos, _ := net.NetInterfaces()
+	// 网卡信息
+	var netAddrList []NetAddr
+	var oneNetAddr NetAddr
+	for _, v := range netAddrs {
+		oneNetAddr = NetAddr{Name: v.Name, RX: v.PacketsSent, TX: v.PacketsRecv}
+		// 获取IP地址
+		for _, vv := range netInfos {
+			if vv.Name == v.Name {
+				oneNetAddr.Addrs = vv.Addrs
+			}
+		}
+		netAddrList = append(netAddrList, oneNetAddr)
+	}
+	return netAddrList
+}
+
+// 获取网络连接数
+func GetNetworkClientCount() int {
+	netList, err := net.NetConnections("all")
+	if err != nil {
+		common.LogFile.W("获取网络连接数", "network", "GetNetworkClientCount")
+		return 0
+	}
+	return len(netList)
+}

+ 166 - 0
libs/collection/ping.go

@@ -0,0 +1,166 @@
+package collection
+
+import (
+	"errors"
+	"fmt"
+	"net"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+
+	"53it.net/agent/libs/common"
+	"53it.net/agent/libs/config"
+)
+
+type PingTime struct {
+	Host  string `json:"host"`
+	Total string `json:"total"`
+	Min   string `json:"min"`
+	Max   string `json:"max"`
+	Avg   string `json:"avg"`
+}
+
+// ping 配置文件
+func PingConf() ([]PingTime, error) {
+	urls := strings.Split(config.CFG.Ping.Url, ",")
+	if len(urls) < 1 {
+		common.LogFile.W("未配置ping主机", "ping", "PingConf")
+		return nil, errors.New("未配置ping主机")
+	}
+	// ping次数
+	count, err := strconv.Atoi(config.CFG.Ping.Count)
+	if err != nil {
+		count = 2
+	}
+	// 定义返回数据
+	var pings []PingTime
+	// 并发ping主机
+	c := make(chan PingTime, len(urls))
+	for _, v := range urls {
+		go func(v string) {
+			var p PingTime
+			p, err := Ping(v, count)
+			if err != nil {
+				return
+			}
+			p.Host = v
+			c <- p
+		}(v)
+	}
+	// 取值
+	for i := 0; i < len(urls); i++ {
+		pings = append(pings, <-c)
+	}
+
+	return pings, nil
+}
+
+// ping 主机名和次数
+func Ping(host string, numPings int) (PingTime, error) {
+	rAddr, err := net.ResolveIPAddr("ip4", host)
+	if err != nil {
+		return PingTime{}, err
+	}
+
+	conn, err := net.DialIP("ip4:icmp", nil, rAddr)
+	if err != nil {
+		return PingTime{}, err
+	}
+	defer conn.Close()
+
+	pid := os.Getpid()
+	var id1 = byte(pid & 0xff00 >> 8)
+	var id2 = byte(pid & 0xff)
+
+	var timeout = 1 * time.Second
+	var interval = 1 * time.Second
+	var messageLength = 64
+
+	pingTimes := []time.Duration{}
+	for i := 0; i < numPings; i++ {
+		msg := MakeEchoRequest(i, messageLength, id1, id2)
+
+		startTime := time.Now()
+		deadline := startTime.Add(timeout)
+		conn.SetDeadline(deadline)
+
+		if _, err = conn.Write(msg[0:messageLength]); err != nil {
+			continue
+		}
+
+		response := make([]byte, 64)
+		for {
+			_, _, err := conn.ReadFrom(response)
+			if err != nil {
+				return PingTime{}, err
+				break
+			}
+			if response[0] == 0 {
+				duration := time.Since(startTime)
+				pingTimes = append(pingTimes, duration)
+			}
+			break
+		}
+		time.Sleep(interval)
+	}
+
+	total, min, max, avg := ComputeStats(pingTimes)
+
+	return PingTime{Total: fmt.Sprintf("%v", total), Min: fmt.Sprintf("%v", min), Max: fmt.Sprintf("%v", max), Avg: fmt.Sprintf("%v", avg)}, nil
+}
+
+func CheckSum(buf []byte) uint16 {
+	var sum uint32
+	for i := 0; i < len(buf)-1; i += 2 {
+		sum += uint32(buf[i+1])<<8 | uint32(buf[i])
+	}
+
+	// Take care of left over byte
+	if len(buf)%2 != 0 {
+		sum += uint32(buf[len(buf)-1])
+	}
+
+	sum = (sum >> 16) + (sum & 0xffff)
+	s