获取当前时刻一分钟前的网卡流量排序
Gopackage 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) } }
获取指定网卡在某时刻前一分钟的网卡流量
Gopackage 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) } }
改进版:定时任务
Gopackage 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) } }
客户端测试代码
Gopackage 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
Goserver: port: :8080 host: localhost record: time: 100 test: name: en0 time: 2024-07-04 10:17:51