Very basic status service

This commit is contained in:
Jakob Borg 2015-08-20 12:59:44 +02:00
parent d7949aa58e
commit f76a66fc55
3 changed files with 56 additions and 2 deletions

View File

@ -32,6 +32,8 @@ var (
globalLimitBps int
sessionLimiter *ratelimit.Bucket
globalLimiter *ratelimit.Bucket
statusAddr string
)
func main() {
@ -47,6 +49,7 @@ func main() {
flag.IntVar(&sessionLimitBps, "per-session-rate", sessionLimitBps, "Per session rate limit, in bytes/s")
flag.IntVar(&globalLimitBps, "global-rate", globalLimitBps, "Global rate limit, in bytes/s")
flag.BoolVar(&debug, "debug", false, "Enable debug output")
flag.StringVar(&statusAddr, "status-srv", ":22070", "Listen address for status service (blank to disable)")
flag.Parse()
@ -99,5 +102,9 @@ func main() {
go sessionListener(listenSession)
if statusAddr != "" {
go statusService(statusAddr)
}
protocolListener(listenProtocol, tlsCfg)
}

View File

@ -9,6 +9,7 @@ import (
"log"
"net"
"sync"
"sync/atomic"
"time"
"github.com/juju/ratelimit"
@ -18,8 +19,10 @@ import (
)
var (
sessionMut = sync.Mutex{}
sessions = make(map[string]*session, 0)
sessionMut = sync.Mutex{}
sessions = make(map[string]*session, 0)
numProxies int64
bytesProxied int64
)
type session struct {
@ -178,6 +181,9 @@ func (s *session) proxy(c1, c2 net.Conn) error {
log.Println("Proxy", c1.RemoteAddr(), "->", c2.RemoteAddr())
}
atomic.AddInt64(&numProxies, 1)
defer atomic.AddInt64(&numProxies, -1)
buf := make([]byte, 65536)
for {
c1.SetReadDeadline(time.Now().Add(networkTimeout))
@ -186,6 +192,8 @@ func (s *session) proxy(c1, c2 net.Conn) error {
return err
}
atomic.AddInt64(&bytesProxied, int64(n))
if debug {
log.Printf("%d bytes from %s to %s", n, c1.RemoteAddr(), c2.RemoteAddr())
}

39
status.go Normal file
View File

@ -0,0 +1,39 @@
package main
import (
"encoding/json"
"log"
"net/http"
"runtime"
"sync/atomic"
)
func statusService(addr string) {
http.HandleFunc("/status", getStatus)
if err := http.ListenAndServe(addr, nil); err != nil {
log.Fatal(err)
}
}
func getStatus(w http.ResponseWriter, r *http.Request) {
status := make(map[string]interface{})
sessionMut.Lock()
status["numSessions"] = len(sessions)
sessionMut.Unlock()
status["numProxies"] = atomic.LoadInt64(&numProxies)
status["bytesProxied"] = atomic.LoadInt64(&bytesProxied)
status["goVersion"] = runtime.Version()
status["goOS"] = runtime.GOOS
status["goAarch"] = runtime.GOARCH
status["goMaxProcs"] = runtime.GOMAXPROCS(-1)
bs, err := json.MarshalIndent(status, "", " ")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(bs)
}