init
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
utils "anytunnel/at-common"
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
host := flag.String("host", "127.0.0.1", "cluster's host")
|
||||
port := flag.Int("port", 37080, "cluster's api port")
|
||||
path := flag.String("path", "/traffic/count", "request path to api")
|
||||
list := flag.Bool("list", false, "show all api path")
|
||||
flag.Parse()
|
||||
if *list {
|
||||
fmt.Println(`1.open a port
|
||||
/port/open/:TunnelID/:ServerToken/:ServerBindIP/:ServerListenPort/:ClientToken/:ClientLocalHost/:ClientLocalPort/:Protocol/:BytesPerSec
|
||||
notice :
|
||||
BytesPerSec : bytes/seconds , zero means no limit
|
||||
Protocol : 1 is tcp , 2 is udp
|
||||
2.close a port
|
||||
/port/close/:TunnelID
|
||||
3.port status
|
||||
/port/close/:TunnelID
|
||||
4.strip a server offline
|
||||
/server/offline/:ServerToken
|
||||
5.strip a clinet offline
|
||||
/client/offline/:ClientToken
|
||||
6.get all tunnel traffic statistics
|
||||
/traffic/count
|
||||
result notice:
|
||||
key : TunnelID
|
||||
negative : download bytes
|
||||
positive : upload bytes
|
||||
7.get a tunnel traffic statistics
|
||||
/traffic/count/:TunnelID
|
||||
`)
|
||||
return
|
||||
}
|
||||
url := fmt.Sprintf("https://%s:%d%s", *host, *port, *path)
|
||||
body, code, err := utils.HttpGet(url)
|
||||
if err != nil {
|
||||
fmt.Printf("ERR:%s", err)
|
||||
} else {
|
||||
b := string(body)
|
||||
fmt.Println(code)
|
||||
fmt.Println(b)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
utils "anytunnel/at-common"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/codeskyblue/kexec"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
host := flag.String("h", "127.0.0.1", "api host")
|
||||
port := flag.Int("p", 37081, "api port")
|
||||
interval := flag.Int("i", 3, "every interval seconds to reporting")
|
||||
interfaceName := flag.String("e", "eth0", "interface name")
|
||||
failSleep := flag.Int("s", 5, "sleep seconds when fail to reporting")
|
||||
pname := flag.String("n", "at-cluster", "program name to counting connections")
|
||||
flag.Parse()
|
||||
sleep := time.Duration(*failSleep)
|
||||
lastbytes := 0
|
||||
for {
|
||||
output, err := kexec.CommandString("netstat -atn|grep -v \"LISTEN\" | wc -l").CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
sysCount, err := strconv.Atoi(strings.Trim(string(output), "\r\n"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
output, err = kexec.CommandString(`netstat -atnp 2>/dev/null |grep -v "LISTEN" |grep ` + *pname + `| wc -l`).CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
programCount, err := strconv.Atoi(strings.Trim(string(output), "\r\n"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
output, err = kexec.CommandString(`cat /proc/net/dev |grep ` + *interfaceName).CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println("exec cat /proc/net/dev ERR:", err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
arr := strings.Fields(string(output))
|
||||
bandwidth := 0
|
||||
if len(arr) > 1 {
|
||||
bytesIn, err := strconv.Atoi(arr[1])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
bytesOut, err := strconv.Atoi(arr[2])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
if lastbytes == 0 {
|
||||
lastbytes = bytesOut + bytesIn
|
||||
}
|
||||
bandwidth = (bytesOut + bytesIn - lastbytes) / (*interval)
|
||||
lastbytes = bytesOut + bytesIn
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://%s:%d/cluster/report", *host, *port)
|
||||
values := map[string]string{
|
||||
"sys_conn_number": strconv.Itoa(sysCount),
|
||||
"tunnel_conn_number": strconv.Itoa(programCount),
|
||||
"bandwidth": fmt.Sprintf("%d", bandwidth),
|
||||
}
|
||||
body, code, err := utils.HttpPost(url, values, nil)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
if code != 204 {
|
||||
fmt.Println("ERR:", code, body)
|
||||
time.Sleep(time.Second * sleep)
|
||||
continue
|
||||
}
|
||||
fmt.Println("report ok ,", sysCount, programCount, bandwidth)
|
||||
time.Sleep(time.Second * time.Duration(*interval))
|
||||
}
|
||||
}
|
||||
@@ -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