0、初始化连接InfluxDB

var (
	cli                    client.Client
	LastNetIoStatTimeStamp int64    //上次获取网络数据的时间
	lastNetInfo            *NetInfo //上次的数据

)

func InitInfluxDB() (err error) {
	cli, err = client.NewHTTPClient(client.HTTPConfig{
		Addr:     "http://127.0.0.1:8086",
		Username: "admin",
		Password: "",
	})

	return
}

1.获取服务器的状态信息

a、获取cpu状态信息

func GetCpuInfo() {
   percent, _ := cpu.Percent(time.Second, false)
   //fmt.Printf("cpu percent:%v\n", percent)
   //写入数据库
   var cpuInfo CpuInfo
   cpuInfo.CpuPercent = percent[0]
   writesCpuPoints(cpuInfo)
}
//记录cpu信息
type CpuInfo struct {
	CpuPercent float64 `json:"cpu_percent"`
}

b、获取内存状态信息

func GetMemInfo() {
	info, err := mem.VirtualMemory()
	if err != nil {
		log.Fatal("get mem info failed ")
		return
	}
	//fmt.Printf("cpu percent:%v\n", percent)
	//写入数据库
	var memInfo MemInfo
	memInfo.Total = info.Total
	memInfo.Available = info.Available
	memInfo.UsedPercent = info.UsedPercent
	memInfo.Used = info.Used
	memInfo.Buffers = info.Buffers
	memInfo.Cached = info.Cached

	writesMemPoints(memInfo)
}

内存信息结构体:

type MemInfo struct {
	Total       uint64  `json:"total"`
	Available   uint64  `json:"available"`
	Used        uint64  `json:"used"`
	UsedPercent float64 `json:"usedPercent"`
	Buffers     uint64  `json:"buffers"`
	Cached      uint64  `json:"cached"`
}

c、获取磁盘状态信息

func GetDiskInfo() {
	parts, _ := disk.Partitions(true)
	var diskInfo = &DiskInfo{
		PartitionUsageStat: make(map[string]*disk.UsageStat),
	}
	for _, part := range parts {
		//	拿到每个分区
		usageState, err := disk.Usage(part.Mountpoint) //传入挂载点
		if err != nil {
			log.Fatal("disk info get failed err:", err)
			continue
		}
		diskInfo.PartitionUsageStat[part.Mountpoint] = usageState

	}
	writesDiskPoints(diskInfo)
}

磁盘接收信息结构体:

type UsageStat struct {
	Path              string  `json:"path"`
	Fstype            string  `json:"fstype"`
	Total             uint64  `json:"total"`
	Free              uint64  `json:"free"`
	Used              uint64  `json:"used"`
	UsedPercent       float64 `json:"usedPercent"`
	InodesTotal       uint64  `json:"inodesTotal"`
	InodesUsed        uint64  `json:"inodesUsed"`
	InodesFree        uint64  `json:"inodesFree"`
	InodesUsedPercent float64 `json:"inodesUsedPercent"`
}

type DiskInfo struct {
	PartitionUsageStat map[string]*disk.UsageStat
}

此处需要注意,磁盘信息的结构体不再使用自定义的结构体,使用"github.com/shirou/gopsutil/disk"包里的磁盘信息,使用自定义的需要在发送到influxDB时进行一一赋值

d、获取网络IO状态信息

func GetNetInfo() {
	var netInfo = &NetInfo{
		NetIoCountersStat: make(map[string]*IoStat),
	}
	netIos, err := net.IOCounters(true)
	if err != nil {
		log.Fatal("net IO  info get failed err:", err)
		return
	}
	curruntTimeStamp := time.Now().Unix()
	for _, netIo := range netIos {
		var ioStat = new(IoStat)
		ioStat.BytesRecv = netIo.BytesSent
		ioStat.BytesSent = netIo.BytesSent
		ioStat.PacketsSent = netIo.PacketsSent
		ioStat.PacketsRecv = netIo.PacketsRecv
		//将具体的网卡数据存起来
		netInfo.NetIoCountersStat[netIo.Name] = ioStat
		//计算相关顺序
		if LastNetIoStatTimeStamp == 0 || lastNetInfo == nil {
			continue
		}
		//计算时间间隔
		interval := curruntTimeStamp - LastNetIoStatTimeStamp
		ioStat.BytesSentRate = (float64(ioStat.BytesSent) - float64(lastNetInfo.NetIoCountersStat[netIo.Name].BytesSent)) / float64(interval)
		ioStat.BytesRecvRate = (float64(ioStat.BytesRecv) - float64(lastNetInfo.NetIoCountersStat[netIo.Name].BytesRecv)) / float64(interval)
		ioStat.PacketsSentRate = (float64(ioStat.PacketsSent) - float64(lastNetInfo.NetIoCountersStat[netIo.Name].PacketsSent)) / float64(interval)
		ioStat.PacketsRecvRate = (float64(ioStat.PacketsRecv) - float64(lastNetInfo.NetIoCountersStat[netIo.Name].PacketsRecv)) / float64(interval)

	}
	LastNetIoStatTimeStamp = curruntTimeStamp //更新时间
	lastNetInfo = netInfo
	writesNetPoints(netInfo)
}

注意:在获取网络IO发送接收信息时,只获取net包的发送和接收大小是没有没有意义的,我们需要知道发送和接收的速度,保证实时了解网络的状态,所以将netStat的结构体定义为下列情景,同时全局变量保存上次的接受包大小,和当前的大小,记录时间差进行计算。

//网络状态结构体
type IoStat struct {
	BytesSent       uint64  `json:"bytesSent"`
	BytesRecv       uint64  `json:"bytesRecv"`
	PacketsSent     uint64  `json:"packetsSent"` //
	PacketsRecv     uint64  `json:"packetsRecv"`
	BytesSentRate   float64 `json:"bytes_sent_rate"`   //
	BytesRecvRate   float64 `json:"bytes_recv_rate"`   //
	PacketsSentRate float64 `json:"packets_sent_rate"` //
	PacketsRecvRate float64 `json:"packets_recv_rate"`
}
type NetInfo struct {
	NetIoCountersStat map[string]*IoStat
}

2.发送到influxDB数据库保存

a、发送cpu状态信息到influxDB

func writesCpuPoints(data CpuInfo) {
	bp, err := client.NewBatchPoints(client.BatchPointsConfig{
		Database:  "monitor",
		Precision: "s", //精度,默认ns
	})
	if err != nil {
		log.Fatal(err)
	}

	tags := map[string]string{"cpu": "cpu0"}
	fields := map[string]interface{}{
		"cpu_per": data.CpuPercent,
	}

	pt, err := client.NewPoint("cpu_per", tags, fields, time.Now())
	if err != nil {
		log.Fatal(err)
	}
	bp.AddPoint(pt)
	err = cli.Write(bp)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("insert cpu info success")
}

b、发送mem状态信息到influxDB

func writesMemPoints(data MemInfo) {
	bp, err := client.NewBatchPoints(client.BatchPointsConfig{
		Database:  "monitor",
		Precision: "s", //精度,默认ns
	})
	if err != nil {
		log.Fatal(err)
	}

	tags := map[string]string{"mem": "mem0"}
	fields := map[string]interface{}{
		"total":       int64(data.Total), //因为不支持uint64 强转一下
		"available":   int64(data.Available),
		"user":        int64(data.Used),
		"userPercent": data.UsedPercent,
		"buffers":     int64(data.Buffers),
		"cached":      int64(data.Cached),
	}

	pt, err := client.NewPoint("memInfo", tags, fields, time.Now())
	if err != nil {
		log.Fatal(err)
	}
	bp.AddPoint(pt)
	err = cli.Write(bp)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("insert mem info success")
}

c、发送disk状态信息到influxDB

func writesDiskPoints(data *DiskInfo) {
	bp, err := client.NewBatchPoints(client.BatchPointsConfig{
		Database:  "monitor",
		Precision: "s", //精度,默认ns
	})
	if err != nil {
		log.Fatal(err)
	}
	for k, v := range data.PartitionUsageStat {
		tags := map[string]string{"path": k}
		fields := map[string]interface{}{
			"totle":             int64(v.Total),
			"free":              int64(v.Free),
			"used":              int64(v.Used),
			"usedPercent":       v.UsedPercent,
			"inodesTotal":       int64(v.InodesTotal),
			"inodesUsed":        int64(v.InodesUsed),
			"inodesFree":        int64(v.InodesFree),
			"inodesUsedPercent": v.InodesUsedPercent,
		}
		pt, err := client.NewPoint("DiskInfo", tags, fields, time.Now())
		if err != nil {
			log.Fatal(err)
		}
		bp.AddPoint(pt)
	}

	err = cli.Write(bp)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("insert disk info success")
}

d、发送NETIo状态信息到influxDB

func writesNetPoints(data *NetInfo) {
	bp, err := client.NewBatchPoints(client.BatchPointsConfig{
		Database:  "monitor",
		Precision: "s", //精度,默认ns
	})
	if err != nil {
		log.Fatal(err)
	}

	for k, v := range data.NetIoCountersStat {
		tags := map[string]string{"name": k}
		fields := map[string]interface{}{
			"bytes_sent_rate":   v.BytesSentRate,
			"bytes_recv_rate":   v.PacketsRecvRate,
			"packets_sent_rate": v.PacketsSentRate,
			"packets_recv_rate": v.PacketsRecvRate,
		}
		pt, err := client.NewPoint("NetInfo", tags, fields, time.Now())
		if err != nil {
			log.Fatal(err)
		}
		bp.AddPoint(pt)
	}

	err = cli.Write(bp)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("insert net info success")
}

3、Grafana连接接收数据库数据,并实时展示

1)选择数据库服务器

 

2)选择存放数据数据库

 

 

3)选择展示字段和标签

 

4)选择展示方式折线、散点、饼状图

 

 

 

5)选择横纵坐标的单位

 

6)保存并展示