diff --git a/http.go b/http.go deleted file mode 100644 index c50afbd..0000000 --- a/http.go +++ /dev/null @@ -1,11 +0,0 @@ -package main - -import ( - _ "expvar" - "net/http" -) - -func StartHttp(bind string) { - // silently discard error here - http.ListenAndServe(":"+bind, nil) -} diff --git a/self.go b/self.go new file mode 100644 index 0000000..45ceed8 --- /dev/null +++ b/self.go @@ -0,0 +1,46 @@ +package main + +import ( + "expvar" + "fmt" + "net" + "net/http" + "runtime" + "time" +) + +var startTime = time.Now().UTC() + +func goroutines() interface{} { + return runtime.NumGoroutine() +} + +// uptime is an expvar.Func compliant wrapper for uptime info. +func uptime() interface{} { + uptime := time.Since(startTime) + return int64(uptime) +} + +// startPort defines lower port for bind +const startPort = 32768 + +// StartSelfMonitor starts http server on random port and exports expvars. +// +// It tries 1024 ports, starting from startPort and registers some expvars if ok. +func StartSelfMonitor() (string, error) { + for port := startPort; port < startPort+1024; port++ { + bind := fmt.Sprintf("localhost:%d", port) + l, err := net.Listen("tcp", bind) + if err != nil { + continue + } + l.Close() + + expvar.Publish("Goroutines", expvar.Func(goroutines)) + expvar.Publish("Uptime", expvar.Func(uptime)) + go http.ListenAndServe(bind, nil) + return bind, nil + } + + return "", fmt.Errorf("no free ports found") +}