golang实现网卡流量监控

news/2024/7/7 18:38:18 标签: golang, xcode, 开发语言

获取当前时刻一分钟前的网卡流量排序

package main

import (
	"fmt"
	"github.com/mackerelio/go-osstat/network"
	"log"
	"net/http"
	"sort"
	"strconv"
	"time"
)

var arr []map[string]int
var arr2 []map[string]int

func get(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/plain;charset=UTF-8")
	//获取一分钟前数据
	var m = make(map[string]int)
	var m2 = make(map[string]int)
	for mp := range arr[0:len(arr)] {
		for key, value := range arr[mp] {
			m[key] += value
		}
	}
	for mp := range arr[0:len(arr2)] {
		for key, value := range arr2[mp] {
			m2[key] += value
		}
	}
	//按值排序
	keys := make([]string, 0, len(m))
	for key, _ := range m {
		keys = append(keys, key)
	}
	sort.Slice(keys, func(i, j int) bool {
		return m[keys[i]]+m2[keys[i]] > m[keys[j]]+m2[keys[j]]
	})
	for _, key := range keys {
		fmt.Fprintf(w, key+" 接收流量"+strconv.Itoa(m[key]/60)+"B/s"+" 发送流量"+strconv.Itoa(m2[key]/60)+
"B/S"+"\n")

	}
}

func fun() {
	var mp = make(map[string]int)
	var mp2 = make(map[string]int)
	for {
		beforeStats, _ := network.Get()
		// 等待1秒钟
		time.Sleep(1 * time.Second)
		afterStats, _ := network.Get()
		for _, item := range beforeStats {
			mp[item.Name] -= int(item.RxBytes)
			mp2[item.Name] -= int(item.TxBytes)
		}
		for _, item := range afterStats {
			mp[item.Name] += int(item.RxBytes)
			mp2[item.Name] += int(item.TxBytes)
			//fmt.Println(item.Name, item.RxBytes, mp[item.Name])
		}
		arr = append(arr, mp)
		arr2 = append(arr2, mp2)
		if len(arr) == 61 {
			arr = arr[1:61]
		}
		if len(arr2) == 61 {
			arr2 = arr2[1:61]
		}
	}

}
func main() {
	go fun()
	http.HandleFunc("/hello", get)
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}

}

获取指定网卡在某时刻前一分钟的网卡流量

package main

import (
	"fmt"
	"github.com/mackerelio/go-osstat/network"
	"log"
	"net/http"
	"strconv"
	"sync"
	"time"
)

type Record struct {
	arr         map[string]map[string]int
	arr2        map[string]map[string]int
	record_Time int
	mutex       sync.Mutex
}

var record = Record{
	arr:         make(map[string]map[string]int),
	arr2:        make(map[string]map[string]int),
	record_Time: 1000,
	mutex:       sync.Mutex{},
}

func get(w http.ResponseWriter, r *http.Request) {
	record.mutex.Lock()
	defer record.mutex.Unlock()
	w.Header().Set("Content-Type", "text/plain;charset=UTF-8")
	queryParams := r.URL.Query()
	queryTime := queryParams.Get("time")
	queryInterface := queryParams.Get("interface")

	//获取指定时间一秒前的流量
	in_Speed := record.arr[queryTime][queryInterface]
	out_Speed := record.arr2[queryTime][queryInterface]
	fmt.Fprintf(w, queryTime+"入口流量"+strconv.Itoa(in_Speed)+" B/s 出口流量"+strconv.Itoa(out_Speed)+"B/s\n")
}

func fun() {

	for {
		var mp = make(map[string]int)
		var mp2 = make(map[string]int)
		record.mutex.Lock()
		beforeStats, _ := network.Get()
		// 等待1秒钟
		time.Sleep(1 * time.Second)
		afterStats, _ := network.Get()
		//获取一秒内的流量
		for _, item := range beforeStats {
			mp[item.Name] -= int(item.RxBytes)
			mp2[item.Name] -= int(item.TxBytes)
		}
		for _, item := range afterStats {
			mp[item.Name] += int(item.RxBytes)
			mp2[item.Name] += int(item.TxBytes)
		}
		//记录每个时间点的流量
		now := time.Now().String()[0:19]
		record.arr[now] = mp
		record.arr2[now] = mp2
		fmt.Println(now)
		record.mutex.Unlock()
	}
}
func main() {

	go fun()
	http.HandleFunc("/get", get)
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}

改进版:定时任务

package main

import (
	"fmt"
	"github.com/mackerelio/go-osstat/network"
	"github.com/spf13/viper"
	"log"
	"net/http"
	"os"
	"strconv"
	"sync"
	"time"
)

type Record struct {
	arr      map[string]map[string]int
	arr2     map[string]map[string]int
	mutex    sync.Mutex
	stopChan chan bool
	ticker   time.Ticker
}

var record = Record{
	arr:      make(map[string]map[string]int),
	arr2:     make(map[string]map[string]int),
	mutex:    sync.Mutex{},
	stopChan: make(chan bool, 3),
	ticker:   *time.NewTicker(time.Second),
}

func get(w http.ResponseWriter, r *http.Request) {
	//加互斥锁
	record.mutex.Lock()
	defer record.mutex.Unlock()
	w.Header().Set("Content-Type", "text/plain;charset=UTF-8")
	queryParams := r.URL.Query()
	queryTime := queryParams.Get("time")
	queryInterface := queryParams.Get("name")

	//获取指定时间一秒前的流量
	in_Speed := record.arr[queryTime][queryInterface]
	out_Speed := record.arr2[queryTime][queryInterface]
	fmt.Fprintf(w, queryTime+"入口流量"+strconv.Itoa(in_Speed)+" B/s 出口流量"+strconv.Itoa(out_Speed)+"B/s\n")
}

func fun() {
	//读取配置
	viper.SetConfigName("config")
	viper.SetConfigType("yml")
	viper.AddConfigPath(".")
	viper.ReadInConfig()
	//日志输出位置
	f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
	if err != nil {
		return
	}
	defer func() {
		f.Close()
	}()
	log.SetOutput(f)
	beforeStats, _ := network.Get()
	for {
		//非阻塞通道读取
		select {
		case <-record.stopChan:
			log.Println("停止记录网卡流量")
			return
		case <-record.ticker.C:
			var mp = make(map[string]int)
			var mp2 = make(map[string]int)
			//互斥锁
			record.mutex.Lock()

			afterStats, _ := network.Get()
			for _, item := range beforeStats {
				mp[item.Name] -= int(item.RxBytes)
				mp2[item.Name] -= int(item.TxBytes)
			}
			for _, item := range afterStats {
				mp[item.Name] += int(item.RxBytes)
				mp2[item.Name] += int(item.TxBytes)
			}
			beforeStats = afterStats

			now := time.Now().String()[0:19]
			//超出后删除最久的元素
			if len(record.arr) > viper.GetInt("record.time") {
				lastTime, _ := time.Parse("2006-01-02 15:04:05", now)
				last := lastTime.Add(-time.Second * time.Duration(viper.GetInt("record.time"))).String()[0:19]
				delete(record.arr, last)
				log.Println("删除时间点:" + last)
			}
			record.arr[now] = mp
			record.arr2[now] = mp2
			log.Println("已记录时间点:" + now + "入口流量:" + strconv.Itoa(mp["en0"]) + "出口流量:" + strconv.Itoa(mp2["en0"]))
			record.mutex.Unlock()
		}
	}
}
func main() {

	//多线程
	go fun()
	http.HandleFunc("/get", get)
	//开启服务器
	if err := http.ListenAndServe(viper.GetString("server.port"), nil); err != nil {
		log.Fatal(err)
	}
}

客户端测试代码

package main_test

import (
	"fmt"
	"github.com/spf13/viper"
	"io"
	"net/http"
	"net/url"
	"testing"
)

func Test(t *testing.T) {
	//配置日志
	viper.SetConfigName("config")
	viper.SetConfigType("yml")
	viper.AddConfigPath(".")
	viper.ReadInConfig()
	//拼接url
	targetUrl := "http://" +
		viper.GetString("server.host") +
		viper.GetString("server.port") + "/get"
	u, _ := url.ParseRequestURI(targetUrl)
	data := url.Values{}
	data.Set("name", viper.GetString("test.name"))
	data.Set("time", viper.GetString("test.time")[0:19])
	u.RawQuery = data.Encode()

	req, _ := http.NewRequest("GET", u.String(), nil)
	//设置user-agent
	req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36")
	client := &http.Client{}
	resp, _ := client.Do(req)
	defer resp.Body.Close()
	//获取返回结果
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}

config.yml

server:
  port:
    :8080
  host:
    localhost
record:
  time:
    100
test:
  name:
    en0
  time:
    2024-07-04 10:17:51

 


http://www.niftyadmin.cn/n/5534871.html

相关文章

JavaScript——属性的增删改查

目录 任务描述 相关知识 属性的获取 方式一 方式二 属性的修改与新增 删除属性 编程要求 任务描述 Luma Restaurant 以前的财务人员在统计销售额的时候不小心把数据弄错了&#xff0c;现在的财务人员想通过一个 JavaScript 函数方便的修改数据&#xff0c;并署上自己的…

基于 Windows Server 2019 部署域控服务器

文章目录 前言1. 域控服务器设计规划2. 安装部署域控服务器2.1. 添加 Active Directory 域服务2.2. 将服务器提升为域控制器2.3. 检查域控服务器配置信息 3. 管理域账号3.1. 新建域管理员账号3.2. 新建普通域账号 4. 服务器加域和退域4.1. 服务器加域操作4.2. 服务器退域操作 总…

word图题表题公式按照章节编号(不用题注)

预期效果&#xff1a; 其中3表示第三章&#xff0c;4表示第3章里的第4个图。标题、公式编号也是类似的。 为了达到这种按照章节编号的效果&#xff0c;原本可以用插入题注里的“包含章节编号” 但实际情况是&#xff0c;这不仅需要一级标题的序号是用“开始->多级列表”自动…

Spring Boot 学习第八天:AOP代理机制对性能的影响

1 概述 在讨论动态代理机制时&#xff0c;一个不可避免的话题是性能。无论采用JDK动态代理还是CGLIB动态代理&#xff0c;本质上都是在原有目标对象上进行了封装和转换&#xff0c;这个过程需要消耗资源和性能。而JDK和CGLIB动态代理的内部实现过程本身也存在很大差异。下面将讨…

CSS filter(滤镜)属性,并实现页面置灰效果

目录 一、filter&#xff08;滤镜&#xff09;属性 二、准备工作 三、常用的filter属性值 1、blur(px) 2、brightness(%) 3、contrast(%) 4、grayscale(%) 5、opacity(%) 6、saturate(%) 7、sepia(%) 8、invert(%) 9、hue-rotate(deg) 10、drop-shadow(h-shadow v…

flutter开发实战-ListWheelScrollView与自定义TimePicker时间选择器

flutter开发实战-ListWheelScrollView与自定义TimePicker 最近在使用时间选择器的时候&#xff0c;需要自定义一个TimePicker效果&#xff0c;当然这里就使用了ListWheelScrollView。ListWheelScrollView与ListView类似&#xff0c;但ListWheelScrollView渲染效果类似滚筒效果…

使用React复刻ThreeJS官网示例——keyframes动画

最近在看three.js相关的东西&#xff0c;想着学习一下threejs给的examples。源码是用html结合js写的&#xff0c;恰好最近也在学习react&#xff0c;就用react框架学习一下。 本文参考的是threeJs给的第一个示例 three.js examples (threejs.org) 一、下载threeJS源码 通常我们…

【LC刷题】DAY22:491 46 47 332 51 37

【LC刷题】DAY22&#xff1a;491 46 47 332 51 37 文章目录 【LC刷题】DAY22&#xff1a;491 46 47 332 51 37491. 非递减子序列 [link](https://leetcode.cn/problems/non-decreasing-subsequences/description/)46. 全排列 [link](https://leetcode.cn/problems/permutations…