2018-02-18 23:25:02 -08:00
|
|
|
package widgets
|
|
|
|
|
|
|
|
import (
|
2018-02-19 15:02:01 -08:00
|
|
|
"fmt"
|
2018-12-04 21:44:25 -08:00
|
|
|
"log"
|
2018-02-18 23:25:02 -08:00
|
|
|
"time"
|
|
|
|
|
2019-01-30 15:20:09 -08:00
|
|
|
psNet "github.com/shirou/gopsutil/net"
|
|
|
|
|
2018-12-31 16:55:50 -08:00
|
|
|
ui "github.com/cjbassi/gotop/src/termui"
|
2018-05-10 21:23:20 -07:00
|
|
|
"github.com/cjbassi/gotop/src/utils"
|
2018-02-18 23:25:02 -08:00
|
|
|
)
|
|
|
|
|
2019-05-14 18:09:17 +02:00
|
|
|
type NetInterface string
|
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
type NetWidget struct {
|
|
|
|
*ui.SparklineGroup
|
|
|
|
updateInterval time.Duration
|
2019-01-30 15:20:09 -08:00
|
|
|
|
2018-02-23 00:42:39 -08:00
|
|
|
// used to calculate recent network activity
|
2019-02-28 16:29:52 -08:00
|
|
|
totalBytesRecv uint64
|
|
|
|
totalBytesSent uint64
|
2019-05-14 18:09:17 +02:00
|
|
|
NetInterface string
|
2018-02-18 23:25:02 -08:00
|
|
|
}
|
|
|
|
|
2019-05-14 18:09:17 +02:00
|
|
|
func NewNetWidget(netInterface string) *NetWidget {
|
2019-02-28 16:29:52 -08:00
|
|
|
recvSparkline := ui.NewSparkline()
|
|
|
|
recvSparkline.Data = []int{}
|
2018-02-18 23:25:02 -08:00
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
sentSparkline := ui.NewSparkline()
|
|
|
|
sentSparkline.Data = []int{}
|
2018-02-18 23:25:02 -08:00
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
spark := ui.NewSparklineGroup(recvSparkline, sentSparkline)
|
|
|
|
self := &NetWidget{
|
|
|
|
SparklineGroup: spark,
|
|
|
|
updateInterval: time.Second,
|
2019-05-14 18:09:17 +02:00
|
|
|
NetInterface: netInterface,
|
2018-03-03 17:05:52 -08:00
|
|
|
}
|
2018-12-31 16:55:50 -08:00
|
|
|
self.Title = " Network Usage "
|
2019-05-14 18:09:17 +02:00
|
|
|
if netInterface != "all" {
|
|
|
|
self.Title = fmt.Sprintf(" %s Usage ", netInterface)
|
|
|
|
}
|
2018-02-18 23:25:02 -08:00
|
|
|
|
2018-04-12 20:00:34 -07:00
|
|
|
self.update()
|
|
|
|
|
2018-02-18 23:25:02 -08:00
|
|
|
go func() {
|
2019-02-28 16:29:52 -08:00
|
|
|
for range time.NewTicker(self.updateInterval).C {
|
2019-03-07 23:43:10 -08:00
|
|
|
self.Lock()
|
2018-03-27 14:27:23 -07:00
|
|
|
self.update()
|
2019-03-07 23:43:10 -08:00
|
|
|
self.Unlock()
|
2018-02-18 23:25:02 -08:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2018-03-27 14:27:23 -07:00
|
|
|
return self
|
2018-02-18 23:25:02 -08:00
|
|
|
}
|
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
func (self *NetWidget) update() {
|
2018-12-10 14:41:35 -08:00
|
|
|
interfaces, err := psNet.IOCounters(true)
|
2018-12-04 21:44:25 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Printf("failed to get network activity from gopsutil: %v", err)
|
2018-12-13 21:59:45 -08:00
|
|
|
return
|
2018-12-04 21:44:25 -08:00
|
|
|
}
|
2019-02-28 16:29:52 -08:00
|
|
|
|
|
|
|
var totalBytesRecv uint64
|
|
|
|
var totalBytesSent uint64
|
2018-12-10 14:41:35 -08:00
|
|
|
for _, _interface := range interfaces {
|
|
|
|
// ignore VPN interface
|
2019-05-14 18:09:17 +02:00
|
|
|
if _interface.Name != "tun0" && self.NetInterface == "all" {
|
|
|
|
totalBytesRecv += _interface.BytesRecv
|
|
|
|
totalBytesSent += _interface.BytesSent
|
|
|
|
} else if _interface.Name == self.NetInterface {
|
2019-02-28 16:29:52 -08:00
|
|
|
totalBytesRecv += _interface.BytesRecv
|
|
|
|
totalBytesSent += _interface.BytesSent
|
2018-12-10 14:41:35 -08:00
|
|
|
}
|
|
|
|
}
|
2018-02-18 23:25:02 -08:00
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
var recentBytesRecv uint64
|
|
|
|
var recentBytesSent uint64
|
|
|
|
|
|
|
|
if self.totalBytesRecv != 0 { // if this isn't the first update
|
|
|
|
recentBytesRecv = totalBytesRecv - self.totalBytesRecv
|
|
|
|
recentBytesSent = totalBytesSent - self.totalBytesSent
|
2018-02-18 23:25:02 -08:00
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
if int(recentBytesRecv) < 0 {
|
|
|
|
log.Printf("error: negative value for recently received network data from gopsutil. recentBytesRecv: %v", recentBytesRecv)
|
2018-12-04 21:44:25 -08:00
|
|
|
// recover from error
|
2019-02-28 16:29:52 -08:00
|
|
|
recentBytesRecv = 0
|
2018-12-04 21:44:25 -08:00
|
|
|
}
|
2019-02-28 16:29:52 -08:00
|
|
|
if int(recentBytesSent) < 0 {
|
|
|
|
log.Printf("error: negative value for recently sent network data from gopsutil. recentBytesSent: %v", recentBytesSent)
|
2018-12-04 21:44:25 -08:00
|
|
|
// recover from error
|
2019-02-28 16:29:52 -08:00
|
|
|
recentBytesSent = 0
|
2018-12-04 21:44:25 -08:00
|
|
|
}
|
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
self.Lines[0].Data = append(self.Lines[0].Data, int(recentBytesRecv))
|
|
|
|
self.Lines[1].Data = append(self.Lines[1].Data, int(recentBytesSent))
|
2018-02-18 23:25:02 -08:00
|
|
|
}
|
|
|
|
|
2018-03-03 17:05:52 -08:00
|
|
|
// used in later calls to update
|
2019-02-28 16:29:52 -08:00
|
|
|
self.totalBytesRecv = totalBytesRecv
|
|
|
|
self.totalBytesSent = totalBytesSent
|
2018-02-19 15:02:01 -08:00
|
|
|
|
2018-05-21 16:02:31 -07:00
|
|
|
// render widget titles
|
2018-02-19 15:02:01 -08:00
|
|
|
for i := 0; i < 2; i++ {
|
2018-08-23 11:43:21 -07:00
|
|
|
total, label, recent := func() (uint64, string, uint64) {
|
|
|
|
if i == 0 {
|
2019-02-28 16:29:52 -08:00
|
|
|
return totalBytesRecv, "RX", recentBytesRecv
|
2018-08-23 11:43:21 -07:00
|
|
|
}
|
2019-03-21 13:20:50 -03:00
|
|
|
return totalBytesSent, "TX", recentBytesSent
|
2018-08-23 11:43:21 -07:00
|
|
|
}()
|
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
recentConverted, unitRecent := utils.ConvertBytes(uint64(recent))
|
|
|
|
totalConverted, unitTotal := utils.ConvertBytes(uint64(total))
|
2018-08-23 11:43:21 -07:00
|
|
|
|
2019-02-28 16:29:52 -08:00
|
|
|
self.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", label, totalConverted, unitTotal)
|
|
|
|
self.Lines[i].Title2 = fmt.Sprintf(" %s/s: %9.1f %2s/s", label, recentConverted, unitRecent)
|
2018-02-19 15:02:01 -08:00
|
|
|
}
|
2018-02-18 23:25:02 -08:00
|
|
|
}
|