Skip to content

Commit

Permalink
Enhance ui
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Foerster <tim.foerster@hetzner.de>
  • Loading branch information
tonobo committed Dec 15, 2017
1 parent 8845a8c commit 6b35e53
Show file tree
Hide file tree
Showing 744 changed files with 179,992 additions and 17 deletions.
33 changes: 29 additions & 4 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ package main
import (
"errors"
"fmt"
"sync"
"time"

tm "github.com/buger/goterm"
"github.com/spf13/cobra"
)

var (
COUNT = 5
TIMEOUT = 800 * time.Millisecond
INTERVAL = 100 * time.Millisecond
MAX_HOPS = 64
RING_BUFFER_SIZE = 8
RING_BUFFER_SIZE = 50
)

// rootCmd represents the root command
Expand All @@ -22,17 +26,38 @@ var RootCmd = &cobra.Command{
return errors.New("No target provided")
}
fmt.Println("Start:", time.Now())
m := NewMTR(args[0])
m, ch := NewMTR(args[0], TIMEOUT, INTERVAL)
tm.Clear()
mu := &sync.Mutex{}
go func(ch chan struct{}) {
for {
mu.Lock()
<-ch
render(m)
mu.Unlock()
}
}(ch)
for i := 0; i < COUNT; i++ {
m.Run()
m.Run(ch)
}
m.Render()
close(ch)
mu.Lock()
render(m)
mu.Unlock()
return nil
},
}

func render(m *MTR) {
tm.MoveCursor(1, 1)
m.Render(1)
tm.Flush() // Call it every time at the end of rendering
}

func init() {
RootCmd.Flags().IntVarP(&COUNT, "count", "c", COUNT, "Amount of pings per target")
RootCmd.Flags().DurationVarP(&TIMEOUT, "timeout", "t", TIMEOUT, "ICMP reply timeout")
RootCmd.Flags().DurationVarP(&INTERVAL, "interval", "i", INTERVAL, "Wait time between icmp packets before sending new one")
RootCmd.Flags().IntVar(&MAX_HOPS, "max-hops", MAX_HOPS, "Maximal TTL count")
RootCmd.Flags().IntVar(&RING_BUFFER_SIZE, "buffer-size", RING_BUFFER_SIZE, "Cached packet buffer size")
}
21 changes: 21 additions & 0 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package: github.com/tonobo/mtr
import:
- package: github.com/buger/goterm
- package: github.com/spf13/cobra
- package: golang.org/x/net
subpackages:
- icmp
- ipv4
13 changes: 8 additions & 5 deletions hop.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"container/ring"
"fmt"
"time"

gm "github.com/buger/goterm"
)

type HopStatistic struct {
Expand All @@ -17,16 +19,15 @@ type HopStatistic struct {
}

func (h *HopStatistic) Render(ttl int) {
failedCounter := 0
successCounter := 0
packets := []byte{}
h.Packets.Do(func(f interface{}) {
if f == nil {
return
}
if !f.(ICMPReturn).Success {
failedCounter++
packets = append(packets, '?')
} else {
successCounter++
packets = append(packets, '.')
}
})
addr := "???"
Expand All @@ -37,7 +38,8 @@ func (h *HopStatistic) Render(ttl int) {
if !(h.Sent-h.Lost == 0) {
avg = h.SumElapsed.Seconds() * 1000 / float64(h.Sent-h.Lost)
}
fmt.Printf("%3d:|-- %-20s %5.1f%% %4d %6.1f %6.1f %6.1f %6.1f\n",
l := fmt.Sprintf("%d", RING_BUFFER_SIZE)
gm.Printf("%3d:|-- %-20s %5.1f%% %4d %6.1f %6.1f %6.1f %6.1f %"+l+"s\n",
ttl,
addr,
float32(h.Lost)/float32(h.Sent)*100.0,
Expand All @@ -46,5 +48,6 @@ func (h *HopStatistic) Render(ttl int) {
avg,
h.Best.Elapsed.Seconds()*1000,
h.Worst.Elapsed.Seconds()*1000,
packets,
)
}
28 changes: 20 additions & 8 deletions mtr.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@ import (
"os"
"sync"
"time"

gm "github.com/buger/goterm"
)

type MTR struct {
mutex *sync.RWMutex
timeout time.Duration
interval time.Duration
Address string `json:"destination"`
Statistic map[int]*HopStatistic `json:"statistic"`
}

func NewMTR(addr string) *MTR {
func NewMTR(addr string, timeout time.Duration, interval time.Duration) (*MTR, chan struct{}) {
return &MTR{
interval: interval,
timeout: timeout,
Address: addr,
mutex: &sync.RWMutex{},
Statistic: map[int]*HopStatistic{},
}
}, make(chan struct{})
}

func (m *MTR) registerStatistic(ttl int, r ICMPReturn) {
Expand All @@ -41,7 +47,6 @@ func (m *MTR) registerStatistic(ttl int, r ICMPReturn) {
return
}
s := m.Statistic[ttl]
s.Packets = s.Packets.Next()
s.Packets.Value = r
s.Sent++
s.SumElapsed = r.Elapsed + s.SumElapsed
Expand All @@ -55,39 +60,46 @@ func (m *MTR) registerStatistic(ttl int, r ICMPReturn) {
if s.Worst.Elapsed < r.Elapsed {
s.Worst = r
}
s.Packets = s.Packets.Next()
}

func (m *MTR) Render() {
fmt.Printf("HOP: %-20s %5s%% %4s %6s %6s %6s %6s\n", "Address", "Loss", "Sent", "Last", "Avg", "Best", "Worst")
func (m *MTR) Render(offset int) {
gm.MoveCursor(1, offset)
l := fmt.Sprintf("%d", RING_BUFFER_SIZE)
gm.Printf("HOP: %-20s %5s%% %4s %6s %6s %6s %6s %"+l+"s\n", "Address", "Loss", "Sent", "Last", "Avg", "Best", "Worst", "Packets")
for i := 1; i <= len(m.Statistic); i++ {
gm.MoveCursor(1, offset+i)
m.mutex.RLock()
m.Statistic[i].Render(i)
m.mutex.RUnlock()
}
return
}

func (m *MTR) Run() {
func (m *MTR) Run(ch chan struct{}) {
ipAddr := net.IPAddr{IP: net.ParseIP(m.Address)}
pid := os.Getpid() & 0xffff
timeout := 500 * time.Millisecond
ttlDoubleBump := false

for ttl := 1; ttl < 64; ttl++ {
hopReturn, err := Icmp("0.0.0.0", &ipAddr, ttl, pid, timeout)
time.Sleep(m.interval)
hopReturn, err := Icmp("0.0.0.0", &ipAddr, ttl, pid, m.timeout)
if err != nil || !hopReturn.Success {
if ttlDoubleBump {
break
}
m.mutex.Lock()
m.registerStatistic(ttl, hopReturn)
m.mutex.Unlock()
ch <- struct{}{}
ttlDoubleBump = true
continue
}
ttlDoubleBump = false
m.mutex.Lock()
m.registerStatistic(ttl, hopReturn)
m.mutex.Unlock()
ch <- struct{}{}
if hopReturn.Addr == m.Address {
break
}
Expand Down
21 changes: 21 additions & 0 deletions vendor/github.com/buger/goterm/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

119 changes: 119 additions & 0 deletions vendor/github.com/buger/goterm/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6b35e53

Please sign in to comment.