Browse Source

auto update script executed

Toby Chui 1 year ago
parent
commit
1ee4d06cc8
1 changed files with 106 additions and 0 deletions
  1. 106 0
      mod/netstat/netstat.go

+ 106 - 0
mod/netstat/netstat.go

@@ -3,6 +3,7 @@ package netstat
 import (
 	"encoding/json"
 	"errors"
+	"log"
 	"net/http"
 	"os"
 	"os/exec"
@@ -10,10 +11,115 @@ import (
 	"runtime"
 	"strconv"
 	"strings"
+	"time"
 
 	"imuslab.com/zoraxy/mod/utils"
 )
 
+// Float stat store the change of RX and TX
+type FlowStat struct {
+	RX int64
+	TX int64
+}
+
+// A new type of FloatStat that save the raw value from rx tx
+type RawFlowStat struct {
+	RX int64
+	TX int64
+}
+
+type NetStatBuffers struct {
+	StatRecordCount int          //No. of record number to keep
+	PreviousStat    *RawFlowStat //The value of the last instance of netstats
+	Stats           []*FlowStat  //Statistic of the flow
+	StopChan        chan bool    //Channel to stop the ticker
+}
+
+// Get a new network statistic buffers
+func NewNetStatBuffer(recordCount int) (*NetStatBuffers, error) {
+	//Get the initial measurements of netstats
+	rx, tx, err := GetNetworkInterfaceStats()
+	if err != nil {
+		return nil, err
+	}
+	currnetNetSpec := RawFlowStat{
+		RX: rx,
+		TX: tx,
+	}
+
+	//Flood fill the stats with 0
+	initialStats := []*FlowStat{}
+	for i := 0; i < recordCount; i++ {
+		initialStats = append(initialStats, &FlowStat{
+			RX: 0,
+			TX: 0,
+		})
+	}
+
+	//Setup a timer to get the value from NIC accumulation stats
+	ticker := time.NewTicker(time.Second)
+	defer ticker.Stop()
+
+	//Setup a stop channel
+	stopCh := make(chan bool)
+
+	thisNetBuffer := NetStatBuffers{
+		StatRecordCount: recordCount,
+		PreviousStat:    &currnetNetSpec,
+		Stats:           initialStats,
+		StopChan:        stopCh,
+	}
+
+	// Update the buffer every second
+	go func(n *NetStatBuffers) {
+		for {
+			select {
+			case <-stopCh:
+				return
+
+			case <-ticker.C:
+				// Get the latest network interface stats
+				rx, tx, err := GetNetworkInterfaceStats()
+				if err != nil {
+					// Log the error, but don't stop the buffer
+					log.Printf("Failed to get network interface stats: %v", err)
+					continue
+				}
+
+				//Calculate the difference between this and last values
+				drx := rx - n.PreviousStat.RX
+				dtx := tx - n.PreviousStat.TX
+
+				// Push the new stats to the buffer
+				newStat := &FlowStat{
+					RX: drx,
+					TX: dtx,
+				}
+
+				//Set current rx tx as the previous rxtx
+				n.PreviousStat = &RawFlowStat{
+					RX: rx,
+					TX: tx,
+				}
+
+				copy(initialStats, initialStats[1:])
+				initialStats = append(initialStats, newStat)
+			}
+		}
+	}(&thisNetBuffer)
+
+	return &thisNetBuffer, nil
+}
+
+func (n *NetStatBuffers) HandleGetBufferedNetworkInterfaceStats(w http.ResponseWriter, r *http.Request) {
+	js, _ := json.Marshal(n.Stats)
+	utils.SendJSONResponse(w, string(js))
+}
+
+func (n *NetStatBuffers) Close() {
+	n.StopChan <- true
+}
+
 func HandleGetNetworkInterfaceStats(w http.ResponseWriter, r *http.Request) {
 	rx, tx, err := GetNetworkInterfaceStats()
 	if err != nil {