init
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
utils "anytunnel/at-common"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/dustin/go-humanize"
|
||||
ui "gopkg.in/gizak/termui.v2"
|
||||
)
|
||||
|
||||
type Msg struct {
|
||||
Code int
|
||||
Message string
|
||||
Data utils.TrafficStatistics
|
||||
}
|
||||
|
||||
var lastStatistics utils.TrafficStatistics
|
||||
|
||||
func main() {
|
||||
|
||||
host := flag.String("host", "127.0.0.1", "cluster's host")
|
||||
port := flag.Int("port", 37080, "cluster's api port")
|
||||
flag.Parse()
|
||||
var err error
|
||||
url := fmt.Sprintf("https://%s:%d/traffic/count", *host, *port)
|
||||
|
||||
err = ui.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer ui.Close()
|
||||
// handle key q pressing
|
||||
ui.Handle("/sys/kbd/q", func(ui.Event) {
|
||||
// press q to quit
|
||||
ui.StopLoop()
|
||||
})
|
||||
var first = true
|
||||
|
||||
var sleep = 2
|
||||
go func() {
|
||||
for {
|
||||
statistics, err := getData(url)
|
||||
if first {
|
||||
first = false
|
||||
lastStatistics = statistics
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Printf("ERR:%s\n", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
speedUpload := humanize.Bytes((statistics.Total.UploadBytes-lastStatistics.Total.UploadBytes)/uint64(sleep)) + "/s"
|
||||
speedDownload := humanize.Bytes((statistics.Total.DownloadBytes-lastStatistics.Total.DownloadBytes)/uint64(sleep)) + "/s"
|
||||
speedTotal := humanize.Bytes((statistics.Total.UploadBytes+statistics.Total.DownloadBytes-lastStatistics.Total.DownloadBytes-lastStatistics.Total.UploadBytes)/uint64(sleep)) + "/s"
|
||||
|
||||
ui.Clear()
|
||||
table2 := ui.NewTable()
|
||||
table2.FgColor = ui.ColorYellow
|
||||
table2.BgColor = ui.ColorBlack
|
||||
table2.BorderFg = ui.ColorYellow
|
||||
table2.TextAlign = ui.AlignCenter
|
||||
table2.Separator = true
|
||||
table2.Border = true
|
||||
table2.Rows = [][]string{
|
||||
[]string{"Tunnels", "Servers", "Clients", "Connections", "Upload", "Download", "Total"},
|
||||
[]string{strconv.Itoa(statistics.Total.Tunnels),
|
||||
strconv.Itoa(statistics.Total.Servers),
|
||||
strconv.Itoa(statistics.Total.Clients),
|
||||
strconv.Itoa(statistics.Total.Connections),
|
||||
strconv.FormatUint(statistics.Total.UploadBytes, 10) + " / " + humanize.Bytes(statistics.Total.UploadBytes) + " (" + speedUpload + ")",
|
||||
strconv.FormatUint(statistics.Total.DownloadBytes, 10) + " / " + humanize.Bytes(statistics.Total.DownloadBytes) + " (" + speedDownload + ")",
|
||||
strconv.FormatUint(statistics.Total.TotalBytes, 10) + " / " + humanize.Bytes(statistics.Total.TotalBytes) + " (" + speedTotal + ")",
|
||||
},
|
||||
}
|
||||
table2.Analysis()
|
||||
table2.SetSize()
|
||||
|
||||
table3 := ui.NewTable()
|
||||
table3.FgColor = ui.ColorWhite
|
||||
table3.BgColor = ui.ColorDefault
|
||||
table3.TextAlign = ui.AlignCenter
|
||||
table3.Separator = true
|
||||
table3.Border = true
|
||||
table3.Rows = [][]string{
|
||||
[]string{"TunnelID", "Connections", "Upload", "Download", "Total", "Limit"},
|
||||
}
|
||||
for _, total := range sortTunnels(statistics.Traffic, 20) {
|
||||
TunnelID := strconv.FormatUint(total["TunnelID"], 10)
|
||||
speedUpload := ""
|
||||
speedDownload := ""
|
||||
speedTotal := ""
|
||||
var connections uint64
|
||||
if v, ok := lastStatistics.Traffic[TunnelID]; ok {
|
||||
speedUpload = humanize.Bytes((total["positive"]-v["positive"])/uint64(sleep)) + "/s"
|
||||
speedDownload = humanize.Bytes((total["negative"]-v["negative"])/uint64(sleep)) + "/s"
|
||||
_speedTotal := (total["positive"] + total["negative"] - v["negative"] - v["positive"]) / uint64(sleep)
|
||||
speedTotal = humanize.Bytes(_speedTotal) + "/s"
|
||||
if total["limit"] > 0 {
|
||||
connections = _speedTotal / total["limit"]
|
||||
}
|
||||
if _speedTotal > 0 && connections == 0 {
|
||||
connections = 1
|
||||
}
|
||||
|
||||
} else {
|
||||
speedUpload = ""
|
||||
speedDownload = ""
|
||||
speedTotal = ""
|
||||
}
|
||||
table3.Rows = append(table3.Rows, []string{TunnelID,
|
||||
strconv.FormatUint(connections, 10),
|
||||
strconv.FormatUint(total["positive"], 10) + " / " + humanize.Bytes(total["positive"]) + " (" + speedUpload + ")",
|
||||
strconv.FormatUint(total["negative"], 10) + " / " + humanize.Bytes(total["negative"]) + " (" + speedDownload + ")",
|
||||
strconv.FormatUint(total["positive"]+total["negative"], 10) + " / " + humanize.Bytes(total["positive"]+total["negative"]) + " (" + speedTotal + ")",
|
||||
humanize.Bytes(total["limit"]) + "/s",
|
||||
})
|
||||
}
|
||||
table3.Analysis()
|
||||
table3.SetSize()
|
||||
|
||||
ui.Body.Rows = []*ui.Row{}
|
||||
ui.Body.AddRows(
|
||||
ui.NewRow(
|
||||
ui.NewCol(12, 0, table2),
|
||||
),
|
||||
ui.NewRow(
|
||||
ui.NewCol(12, 0, table3),
|
||||
),
|
||||
)
|
||||
ui.Body.Align()
|
||||
ui.Render(ui.Body)
|
||||
lastStatistics = statistics
|
||||
time.Sleep(time.Second * time.Duration(sleep))
|
||||
}
|
||||
}()
|
||||
|
||||
ui.Loop()
|
||||
}
|
||||
func getData(url string) (statistics utils.TrafficStatistics, err error) {
|
||||
body, code, err := utils.HttpGet(url)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("ERR:%s", err)
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
err = fmt.Errorf("ERR: http code %d,body : %s", code, string(body))
|
||||
return
|
||||
}
|
||||
|
||||
var msg Msg
|
||||
err = json.Unmarshal(body, &msg)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("ERR:%s", err)
|
||||
return
|
||||
}
|
||||
if msg.Code != 1 {
|
||||
err = fmt.Errorf("ERR:%s", msg.Message)
|
||||
return
|
||||
}
|
||||
statistics = msg.Data
|
||||
return
|
||||
}
|
||||
|
||||
type DirRange []uint64
|
||||
|
||||
func (a DirRange) Len() int { return len(a) }
|
||||
func (a DirRange) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a DirRange) Less(i, j int) bool { return a[i] > a[j] }
|
||||
|
||||
func sortTunnels(data map[string]map[string]uint64, limit int) []map[string]uint64 {
|
||||
sortMap := map[string]uint64{}
|
||||
sortUint := DirRange{}
|
||||
for k, v := range data {
|
||||
var p uint64 = 0
|
||||
if ov, ok := lastStatistics.Traffic[k]; ok {
|
||||
p = ov["positive"] + ov["negative"]
|
||||
}
|
||||
total := (v["positive"] + v["negative"]) - p
|
||||
sortMap[k] = total
|
||||
sortUint = append(sortUint, total)
|
||||
}
|
||||
sortUintUniqueMap := map[uint64]bool{}
|
||||
for _, v := range sortUint {
|
||||
sortUintUniqueMap[v] = true
|
||||
}
|
||||
uniqueSortUint := DirRange{}
|
||||
for k := range sortUintUniqueMap {
|
||||
uniqueSortUint = append(uniqueSortUint, k)
|
||||
}
|
||||
sort.Sort(uniqueSortUint)
|
||||
reslut := []map[string]uint64{}
|
||||
i := 0
|
||||
for _, v := range uniqueSortUint {
|
||||
for k, v1 := range sortMap {
|
||||
if v == v1 {
|
||||
id, _ := strconv.ParseUint(k, 10, 64)
|
||||
newItem := map[string]uint64{
|
||||
"positive": data[k]["positive"],
|
||||
"negative": data[k]["negative"],
|
||||
"TunnelID": id,
|
||||
"limit": data[k]["limit"],
|
||||
}
|
||||
reslut = append(reslut, newItem)
|
||||
}
|
||||
}
|
||||
i++
|
||||
if i > limit {
|
||||
break
|
||||
}
|
||||
}
|
||||
return reslut
|
||||
}
|
||||
Reference in New Issue
Block a user