Eclectic Media Git pingstats-go / master pingstats.go
master

Tree @master (Download .tar.gz)

pingstats.go @masterraw · history · blame

// Copyright, Ariana Giroux <ariana.giroux@gmail.com>, circa June 2019 under the MIT license
//
// Clones basic functionality of git://eclecticmedia.hopto.org/pingstats
//
// Provides simple method of plotting one's ping to google.ca on the command line.
//
// Breaks on any OS other than POSIX standard Ubuntu/Debian distributions
package main

import "fmt"
import "github.com/guptarohit/asciigraph"
import terminal "github.com/wayneashleyberry/terminal-dimensions"
import "os/exec"
import "strconv"
import "strings"
import "time"

// define a pingstats clone in go
func main() {
	var returnTimes []float64 // make collection of return times

	for i := 0; i < 500; i++ { // loop for a while, would be infinite in real program
		width, height := termsize() // obtain termsize, account for changing size
		returnTimes = append(returnTimes, get_return_time("google.ca"))

		graph := asciigraph.Plot(returnTimes,
			asciigraph.Width(int(width)-10),
			asciigraph.Height(int(height)-2))

		fmt.Println(graph)
		time.Sleep(100 * time.Millisecond)
		clear() // fails on windows
	}
}

func get_return_time(host string) float64 { // retrieve return time from ping as float64
	pingCmd := exec.Command("ping", "-c 1", host) // Run ping command
	pingOut, err := pingCmd.Output()              // Obtain command output

	var returnTime float64

	if err != nil {
		panic(err)
	}

	// note, line searching is ugly, could be easier implemented with regex
	// note, line searching will break on non debian/ubuntu distributions
	for _, line := range strings.Split(string(pingOut), "\n") { // split output by line
		if strings.Contains(string(line), "time=") { // line has time value on it
			// line similar to: 64 bytes from yyz12s06-in-f3.1e100.net (172.217.165.3): icmp_seq=1 ttl=56 time=62.8 ms
			timeIndex := strings.Index(line, "time")                     // get index of time data
			subIndex := strings.Index(string(line[timeIndex:]), "=") + 1 // Get index of equals sign, plus one
			endIndex := strings.Index(string(line[timeIndex:]), " ")     // get index of trailing characters

			rTime, err := strconv.ParseFloat(
				string(line)[timeIndex:][subIndex:endIndex], // return relevant data as float
				64,
			)

			if err != nil {
				panic(err)
			} else {
				returnTime = rTime // if no errors, set returnTime to data
			}
		}
	}

	return returnTime
}

func termsize() (int, int) { // return size of terminal
	// obtain width
	width, err := terminal.Width()
	if err != nil {
		panic(err)
	}

	// obtain height
	height, err := terminal.Height()
	if err != nil {
		panic(err)
	}

	return int(width), int(height)
}

func clear() { // clear terminal
	exec.Command("clear") // not available on windows
}