Skip to content
This repository has been archived by the owner on Mar 29, 2024. It is now read-only.

Commit

Permalink
Add crane traffic stats
Browse files Browse the repository at this point in the history
  • Loading branch information
dhaavi committed Jan 19, 2022
1 parent 6bd393d commit eddd9a8
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docks/crane.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ func (crane *Crane) unloadUntilFull(buf []byte) error {
if bytesRead == len(buf) {
// Submit metrics.
crane.submitCraneTrafficStats(bytesRead)
crane.NetState.ReportTraffic(uint64(bytesRead), true)

return nil
}
Expand Down Expand Up @@ -688,6 +689,7 @@ func (crane *Crane) load(c *container.Container) error {

// Submit metrics.
crane.submitCraneTrafficStats(len(readyToSend))
crane.NetState.ReportTraffic(uint64(len(readyToSend)), false)

// Load onto ship.
err = crane.ship.Load(readyToSend)
Expand Down
60 changes: 59 additions & 1 deletion docks/crane_netstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,35 @@ package docks

import (
"sync"
"sync/atomic"
"time"
)

const NetStatePeriodInterval = 15 * time.Hour

type NetworkOptimizationState struct {
sync.Mutex

// lastSuggestedAt holds the time when the connnection to the connected Hub was last suggested by the network optimization.
lastSuggestedAt time.Time

lifetimeBytesIn *uint64
lifetimeBytesOut *uint64
lifetimeStarted time.Time
periodBytesIn *uint64
periodBytesOut *uint64
periodStarted time.Time
}

func newNetworkOptimizationState() *NetworkOptimizationState {
return &NetworkOptimizationState{}
return &NetworkOptimizationState{
lifetimeBytesIn: new(uint64),
lifetimeBytesOut: new(uint64),
lifetimeStarted: time.Now(),
periodBytesIn: new(uint64),
periodBytesOut: new(uint64),
periodStarted: time.Now(),
}
}

func (netState *NetworkOptimizationState) UpdateLastSuggestedAt() {
Expand All @@ -29,3 +46,44 @@ func (netState *NetworkOptimizationState) LastSuggestedAt() time.Time {

return netState.lastSuggestedAt
}

func (netState *NetworkOptimizationState) ReportTraffic(bytes uint64, in bool) {
if in {
atomic.AddUint64(netState.lifetimeBytesIn, bytes)
atomic.AddUint64(netState.periodBytesIn, bytes)
} else {
atomic.AddUint64(netState.lifetimeBytesOut, bytes)
atomic.AddUint64(netState.periodBytesOut, bytes)
}
}

func (netState *NetworkOptimizationState) LapsePeriod() {
netState.Lock()
defer netState.Unlock()

// Reset period if interval elapsed.
if time.Now().Add(-NetStatePeriodInterval).After(netState.periodStarted) {
atomic.StoreUint64(netState.periodBytesIn, 0)
atomic.StoreUint64(netState.periodBytesOut, 0)
netState.periodStarted = time.Now()
}
}

func (netState *NetworkOptimizationState) GetTrafficStats() (
lifetimeBytesIn uint64,
lifetimeBytesOut uint64,
lifetimeStarted time.Time,
periodBytesIn uint64,
periodBytesOut uint64,
periodStarted time.Time,
) {
netState.Lock()
defer netState.Unlock()

return atomic.LoadUint64(netState.lifetimeBytesIn),
atomic.LoadUint64(netState.lifetimeBytesOut),
netState.lifetimeStarted,
atomic.LoadUint64(netState.periodBytesIn),
atomic.LoadUint64(netState.periodBytesOut),
netState.periodStarted
}
50 changes: 43 additions & 7 deletions navigator/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/awalterschulze/gographviz"
"github.com/safing/portbase/api"
"github.com/safing/portbase/log"
"github.com/safing/spn/docks"
"github.com/safing/spn/hub"
)

Expand Down Expand Up @@ -177,10 +178,13 @@ func handleMapMeasurementsTableRequest(ar *api.Request) (data []byte, err error)
list := m.pinList(true)
sort.Sort(sortByLowestMeasuredCost(list))

// Get cranes for usage stats.
assignedCranes := docks.GetAllAssignedCranes()

// Build table and return.
buf := bytes.NewBuffer(nil)
tabWriter := tabwriter.NewWriter(buf, 8, 4, 3, ' ', 0)
fmt.Fprint(tabWriter, "Remote\tCountry\tLatency\tCapacity\tCost\n")
fmt.Fprint(tabWriter, "Hub Name\tCountry\tLatency\tCapacity\tCost\tHub ID\tLifetime Usage\tPeriod Usage\tProt\tMine\n")
for _, pin := range list {
// Only print regarded Hubs.
if !matcher(pin) {
Expand All @@ -190,13 +194,43 @@ func handleMapMeasurementsTableRequest(ar *api.Request) (data []byte, err error)
// Add row.
pin.measurements.Lock()
defer pin.measurements.Unlock()
fmt.Fprint(tabWriter, strings.Join([]string{
pin.Hub.Name(),
fmt.Fprintf(tabWriter,
"%s\t%s\t%s\t%.2fMbit/s\t%.2fc\t%s",
pin.Hub.Info.Name,
getPinCountry(pin),
pin.measurements.Latency.String(),
fmt.Sprintf("%.2fMbit/s", float64(pin.measurements.Capacity)/1000000),
fmt.Sprintf("%.2fc", pin.measurements.CalculatedCost),
}, "\t"))
pin.measurements.Latency,
float64(pin.measurements.Capacity)/1000000,
pin.measurements.CalculatedCost,
pin.Hub.ID,
)

// Add usage stats.
if crane, ok := assignedCranes[pin.Hub.ID]; ok {
ltIn, ltOut, ltStart, pIn, pOut, pStart := crane.NetState.GetTrafficStats()
ltDuration := time.Since(ltStart)
pDuration := time.Since(pStart)
var mine string
if crane.IsMine() {
mine = "yes"
if crane.Stopping.IsSet() {
mine += " (stopping)"
}
}

fmt.Fprintf(tabWriter,
"\t%.2fGB %.2fMbit/s %.2f%%out since %s\t%.2fGB %.2fMbit/s %.2f%%out since %s\t%s\t%s",
float64(ltIn+ltOut)/1000000000,
(float64(ltIn+ltOut)/1000000/ltDuration.Seconds())*8,
float64(ltOut)/float64(ltIn+ltOut)*100,
ltDuration.Truncate(time.Second),
float64(pIn+pOut)/1000000000,
(float64(pIn+pOut)/1000000/pDuration.Seconds())*8,
float64(pOut)/float64(pIn+pOut)*100,
pDuration.Truncate(time.Second),
crane.Transport().Protocol,
mine,
)
}

// Add linebreak.
fmt.Fprint(tabWriter, "\n")
Expand Down Expand Up @@ -372,12 +406,14 @@ func graphNodeTooltip(pin *Pin) string {
return fmt.Sprintf(
`"ID: %s
States: %s
Version: %s
IPv4: %s
IPv6: %s
Load: %d
Cost: %.2f"`,
pin.Hub.ID,
pin.State,
pin.Hub.Status.Version,
v4Info,
v6Info,
pin.Hub.Status.Load,
Expand Down
6 changes: 6 additions & 0 deletions navigator/optimize.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"sort"
"time"

"github.com/safing/spn/docks"
"github.com/safing/spn/hub"
)

Expand Down Expand Up @@ -188,6 +189,11 @@ func (m *Map) optimize(opts *Options) (result *OptimizationResult, err error) {
return nil, err
}

// Lapse traffic stats after optimizing for good fresh data next time.
for _, crane := range docks.GetAllAssignedCranes() {
crane.NetState.LapsePeriod()
}

// Clean and return.
result.regardedPins = nil
return result, nil
Expand Down

0 comments on commit eddd9a8

Please sign in to comment.