package netflowimport ( "fmt" "log" "node/global" "os" "regexp" "strconv" "strings" "time")var gVar *global.Globalfunc Start(g *global.Global) { gVar = g log.Println("netflow start") gVar.Lock.RLock() ifname := gVar.Str["ifname"] gVar.Lock.RUnlock() for { var interval int64 = 5 go secondNetFlow(ifname, interval) time.Sleep(time.Duration(interval) * time.Second) }}// 每秒流量, 统计完成后完成后发送到接口func secondNetFlow(ifname string, sleep int64) { sleep1 := time.Now().Unix() tx1, rx1 := netflowTxRx(ifname) time.Sleep(time.Duration(sleep) * time.Second) tx2, rx2 := netflowTxRx(ifname) sleep2 := time.Now().Unix() - sleep1 // tx3 := (tx2 - tx1) / sleep2 * 8 // rx3 := (rx2 - rx1) / sleep2 * 8 tx3 := (tx2 - tx1) / sleep2 * 8 / 1000000 //mbps rx3 := (rx2 - rx1) / sleep2 * 8 / 1000000 // log.Printf("tx=%v rx=%v", tx3, rx3) gVar.Lock.Lock() gVar.NetLineInfo.TxRealtime = tx3 if gVar.NetLineInfo.TxLastMax < tx3 { gVar.NetLineInfo.TxLastMax = tx3 } gVar.NetLineInfo.RxRealtime = rx3 if gVar.NetLineInfo.RxLastMax < rx3 { gVar.NetLineInfo.RxLastMax = rx3 } gVar.Lock.Unlock()}// 取得某个接口在 /proc/net/dev 中的数据func getInterfaceNetFlow(ifName, procNetDev string) (tx, rx int64) { regexpStr := fmt.Sprintf(`[\s^]%s:.*`, ifName) // 拼接正则表达式 match1 := regexp.MustCompile(regexpStr).FindString(procNetDev) // 匹配所在行 match2 := regexp.MustCompile(`\S+?(:|\b)`).FindAllString(strings.TrimSpace(match1), 11) // 正则匹配为数组 // 如果匹配成功, 那么数组 len 肯定是 11, 则赋值返回 if len(match2) == 11 { tx, _ = strconv.ParseInt(match2[9], 10, 64) rx, _ = strconv.ParseInt(match2[1], 10, 64) } return}// 取得指定接口流量func netflowTxRx(ifname string) (tx, rx int64) { // 取得流量文件数据 vNetDev, err := os.ReadFile("/proc/net/dev") if err != nil { return } tx, rx = getInterfaceNetFlow(ifname, string(vNetDev)) return}type LineInfo struct { Code int64 `doc:"1表示数据正常"` TxLastMax int64 `doc:"线路拨号以来的最大值"` TxConfMax int64 `doc:"运营商标识的线路最大值"` TxRealtime int64 `doc:"实时速度"` RxLastMax int64 `doc:"线路拨号以来的最大值"` RxConfMax int64 `doc:"运营商标识的线路最大值"` RxRealtime int64 `doc:"实时速度"` Mac string}func NewLineInfo() (obj *LineInfo) { obj = &LineInfo{} obj.Code = 1 v1, err1 := strconv.ParseInt(os.Getenv("MAX_TX"), 10, 64) if err1 == nil { obj.TxConfMax = v1 obj.TxLastMax = v1 } v2, err2 := strconv.ParseInt(os.Getenv("MAX_RX"), 10, 64) if err2 == nil { obj.RxConfMax = v2 obj.RxLastMax = v2 } obj.Mac = os.Getenv("MAC") return}