This commit is contained in:
arraykeys
2019-08-08 17:13:34 +08:00
parent e8e5966a8c
commit f0bf2d5fec
2885 changed files with 1195993 additions and 12 deletions
+49
View File
@@ -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)
}
}
+98
View File
@@ -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))
}
}
+217
View File
@@ -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
}