1. package netflow
    2. import (
    3. "fmt"
    4. "log"
    5. "node/global"
    6. "os"
    7. "regexp"
    8. "strconv"
    9. "strings"
    10. "time"
    11. )
    12. var gVar *global.Global
    13. func Start(g *global.Global) {
    14. gVar = g
    15. log.Println("netflow start")
    16. gVar.Lock.RLock()
    17. ifname := gVar.Str["ifname"]
    18. gVar.Lock.RUnlock()
    19. for {
    20. var interval int64 = 5
    21. go secondNetFlow(ifname, interval)
    22. time.Sleep(time.Duration(interval) * time.Second)
    23. }
    24. }
    25. // 每秒流量, 统计完成后完成后发送到接口
    26. func secondNetFlow(ifname string, sleep int64) {
    27. sleep1 := time.Now().Unix()
    28. tx1, rx1 := netflowTxRx(ifname)
    29. time.Sleep(time.Duration(sleep) * time.Second)
    30. tx2, rx2 := netflowTxRx(ifname)
    31. sleep2 := time.Now().Unix() - sleep1
    32. // tx3 := (tx2 - tx1) / sleep2 * 8
    33. // rx3 := (rx2 - rx1) / sleep2 * 8
    34. tx3 := (tx2 - tx1) / sleep2 * 8 / 1000000 //mbps
    35. rx3 := (rx2 - rx1) / sleep2 * 8 / 1000000
    36. // log.Printf("tx=%v rx=%v", tx3, rx3)
    37. gVar.Lock.Lock()
    38. gVar.NetLineInfo.TxRealtime = tx3
    39. if gVar.NetLineInfo.TxLastMax < tx3 {
    40. gVar.NetLineInfo.TxLastMax = tx3
    41. }
    42. gVar.NetLineInfo.RxRealtime = rx3
    43. if gVar.NetLineInfo.RxLastMax < rx3 {
    44. gVar.NetLineInfo.RxLastMax = rx3
    45. }
    46. gVar.Lock.Unlock()
    47. }
    48. // 取得某个接口在 /proc/net/dev 中的数据
    49. func getInterfaceNetFlow(ifName, procNetDev string) (tx, rx int64) {
    50. regexpStr := fmt.Sprintf(`[\s^]%s:.*`, ifName) // 拼接正则表达式
    51. match1 := regexp.MustCompile(regexpStr).FindString(procNetDev) // 匹配所在行
    52. match2 := regexp.MustCompile(`\S+?(:|\b)`).FindAllString(strings.TrimSpace(match1), 11) // 正则匹配为数组
    53. // 如果匹配成功, 那么数组 len 肯定是 11, 则赋值返回
    54. if len(match2) == 11 {
    55. tx, _ = strconv.ParseInt(match2[9], 10, 64)
    56. rx, _ = strconv.ParseInt(match2[1], 10, 64)
    57. }
    58. return
    59. }
    60. // 取得指定接口流量
    61. func netflowTxRx(ifname string) (tx, rx int64) {
    62. // 取得流量文件数据
    63. vNetDev, err := os.ReadFile("/proc/net/dev")
    64. if err != nil {
    65. return
    66. }
    67. tx, rx = getInterfaceNetFlow(ifname, string(vNetDev))
    68. return
    69. }
    70. type LineInfo struct {
    71. Code int64 `doc:"1表示数据正常"`
    72. TxLastMax int64 `doc:"线路拨号以来的最大值"`
    73. TxConfMax int64 `doc:"运营商标识的线路最大值"`
    74. TxRealtime int64 `doc:"实时速度"`
    75. RxLastMax int64 `doc:"线路拨号以来的最大值"`
    76. RxConfMax int64 `doc:"运营商标识的线路最大值"`
    77. RxRealtime int64 `doc:"实时速度"`
    78. Mac string
    79. }
    80. func NewLineInfo() (obj *LineInfo) {
    81. obj = &LineInfo{}
    82. obj.Code = 1
    83. v1, err1 := strconv.ParseInt(os.Getenv("MAX_TX"), 10, 64)
    84. if err1 == nil {
    85. obj.TxConfMax = v1
    86. obj.TxLastMax = v1
    87. }
    88. v2, err2 := strconv.ParseInt(os.Getenv("MAX_RX"), 10, 64)
    89. if err2 == nil {
    90. obj.RxConfMax = v2
    91. obj.RxLastMax = v2
    92. }
    93. obj.Mac = os.Getenv("MAC")
    94. return
    95. }