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)保存并展示