mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-23 11:28:59 +00:00
Improve status reporter
This commit is contained in:
parent
a413b83c01
commit
f407ff8861
@ -7,6 +7,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
syncthingprotocol "github.com/syncthing/protocol"
|
syncthingprotocol "github.com/syncthing/protocol"
|
||||||
@ -17,6 +18,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
outboxesMut = sync.RWMutex{}
|
outboxesMut = sync.RWMutex{}
|
||||||
outboxes = make(map[syncthingprotocol.DeviceID]chan interface{})
|
outboxes = make(map[syncthingprotocol.DeviceID]chan interface{})
|
||||||
|
numConnections int64
|
||||||
)
|
)
|
||||||
|
|
||||||
func protocolListener(addr string, config *tls.Config) {
|
func protocolListener(addr string, config *tls.Config) {
|
||||||
@ -122,7 +124,7 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config) {
|
|||||||
outboxesMut.RUnlock()
|
outboxesMut.RUnlock()
|
||||||
if !ok {
|
if !ok {
|
||||||
if debug {
|
if debug {
|
||||||
log.Println(id, "is looking", requestedPeer, "which does not exist")
|
log.Println(id, "is looking for", requestedPeer, "which does not exist")
|
||||||
}
|
}
|
||||||
protocol.WriteMessage(conn, protocol.ResponseNotFound)
|
protocol.WriteMessage(conn, protocol.ResponseNotFound)
|
||||||
conn.Close()
|
conn.Close()
|
||||||
@ -219,6 +221,9 @@ func protocolConnectionHandler(tcpConn net.Conn, config *tls.Config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) {
|
func messageReader(conn net.Conn, messages chan<- interface{}, errors chan<- error) {
|
||||||
|
atomic.AddInt64(&numConnections, 1)
|
||||||
|
defer atomic.AddInt64(&numConnections, -1)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
msg, err := protocol.ReadMessage(conn)
|
msg, err := protocol.ReadMessage(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -110,30 +110,31 @@ func (s *session) Serve() {
|
|||||||
close(s.conns)
|
close(s.conns)
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
log.Println("Session", s, "starting between", conns[0].RemoteAddr(), conns[1].RemoteAddr())
|
log.Println("Session", s, "starting between", conns[0].RemoteAddr(), "and", conns[1].RemoteAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
|
||||||
errors := make(chan error, 2)
|
var err0 error
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
errors <- s.proxy(conns[0], conns[1])
|
err0 = s.proxy(conns[0], conns[1])
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var err1 error
|
||||||
go func() {
|
go func() {
|
||||||
errors <- s.proxy(conns[1], conns[0])
|
err1 = s.proxy(conns[1], conns[0])
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if debug {
|
if debug {
|
||||||
log.Println("Session", s, "ended, outcomes:", <-errors, <-errors)
|
log.Println("Session", s, "ended, outcomes:", err0, "and", err1)
|
||||||
}
|
}
|
||||||
goto done
|
goto done
|
||||||
|
|
||||||
case <-timedout:
|
case <-timedout:
|
||||||
if debug {
|
if debug {
|
||||||
log.Println("Session", s, "timed out")
|
log.Println("Session", s, "timed out")
|
||||||
|
@ -6,9 +6,14 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var rc *rateCalculator
|
||||||
|
|
||||||
func statusService(addr string) {
|
func statusService(addr string) {
|
||||||
|
rc = newRateCalculator(360, 10*time.Second, &bytesProxied)
|
||||||
|
|
||||||
http.HandleFunc("/status", getStatus)
|
http.HandleFunc("/status", getStatus)
|
||||||
if err := http.ListenAndServe(addr, nil); err != nil {
|
if err := http.ListenAndServe(addr, nil); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -21,12 +26,21 @@ func getStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
sessionMut.Lock()
|
sessionMut.Lock()
|
||||||
status["numSessions"] = len(sessions)
|
status["numSessions"] = len(sessions)
|
||||||
sessionMut.Unlock()
|
sessionMut.Unlock()
|
||||||
|
status["numConnections"] = atomic.LoadInt64(&numConnections)
|
||||||
status["numProxies"] = atomic.LoadInt64(&numProxies)
|
status["numProxies"] = atomic.LoadInt64(&numProxies)
|
||||||
status["bytesProxied"] = atomic.LoadInt64(&bytesProxied)
|
status["bytesProxied"] = atomic.LoadInt64(&bytesProxied)
|
||||||
status["goVersion"] = runtime.Version()
|
status["goVersion"] = runtime.Version()
|
||||||
status["goOS"] = runtime.GOOS
|
status["goOS"] = runtime.GOOS
|
||||||
status["goAarch"] = runtime.GOARCH
|
status["goAarch"] = runtime.GOARCH
|
||||||
status["goMaxProcs"] = runtime.GOMAXPROCS(-1)
|
status["goMaxProcs"] = runtime.GOMAXPROCS(-1)
|
||||||
|
status["kbps10s1m5m15m30m60m"] = []int64{
|
||||||
|
rc.rate(10/10) * 8 / 1000,
|
||||||
|
rc.rate(60/10) * 8 / 1000,
|
||||||
|
rc.rate(5*60/10) * 8 / 1000,
|
||||||
|
rc.rate(15*60/10) * 8 / 1000,
|
||||||
|
rc.rate(30*60/10) * 8 / 1000,
|
||||||
|
rc.rate(60*60/10) * 8 / 1000,
|
||||||
|
}
|
||||||
|
|
||||||
bs, err := json.MarshalIndent(status, "", " ")
|
bs, err := json.MarshalIndent(status, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -37,3 +51,42 @@ func getStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.Write(bs)
|
w.Write(bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type rateCalculator struct {
|
||||||
|
rates []int64
|
||||||
|
prev int64
|
||||||
|
counter *int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRateCalculator(keepIntervals int, interval time.Duration, counter *int64) *rateCalculator {
|
||||||
|
r := &rateCalculator{
|
||||||
|
rates: make([]int64, keepIntervals),
|
||||||
|
counter: counter,
|
||||||
|
}
|
||||||
|
|
||||||
|
go r.updateRates(interval)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rateCalculator) updateRates(interval time.Duration) {
|
||||||
|
for {
|
||||||
|
now := time.Now()
|
||||||
|
next := now.Truncate(interval).Add(interval)
|
||||||
|
time.Sleep(next.Sub(now))
|
||||||
|
|
||||||
|
cur := atomic.LoadInt64(r.counter)
|
||||||
|
rate := int64(float64(cur-r.prev) / interval.Seconds())
|
||||||
|
copy(r.rates[1:], r.rates)
|
||||||
|
r.rates[0] = rate
|
||||||
|
r.prev = cur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *rateCalculator) rate(periods int) int64 {
|
||||||
|
var tot int64
|
||||||
|
for i := 0; i < periods; i++ {
|
||||||
|
tot += r.rates[i]
|
||||||
|
}
|
||||||
|
return tot / int64(periods)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user