2015-10-27 01:16:02 +00:00
|
|
|
package stats
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2015-10-27 22:23:39 +00:00
|
|
|
"fmt"
|
2015-10-27 01:16:02 +00:00
|
|
|
"net/http"
|
2015-10-27 22:23:39 +00:00
|
|
|
"time"
|
2015-10-27 01:16:02 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Server struct {
|
|
|
|
base
|
2015-10-27 22:23:39 +00:00
|
|
|
|
|
|
|
history map[string][]*baseSnapshot
|
2015-10-27 01:16:02 +00:00
|
|
|
}
|
|
|
|
|
2015-10-27 22:23:39 +00:00
|
|
|
const (
|
|
|
|
serverSnapshotIntervl = 5 * time.Second
|
|
|
|
serverHistorySize = 360 // 30 minutes of 5 second snapshots
|
|
|
|
)
|
|
|
|
|
2015-10-27 01:16:02 +00:00
|
|
|
func NewServer() *Server {
|
|
|
|
s := &Server{}
|
|
|
|
s.init()
|
2015-10-27 22:23:39 +00:00
|
|
|
s.history = make(map[string][]*baseSnapshot)
|
|
|
|
go s.takeSnapshots()
|
2015-10-27 01:16:02 +00:00
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2015-10-27 22:23:39 +00:00
|
|
|
func (s *Server) History(rw http.ResponseWriter, _ *http.Request) {
|
|
|
|
encoded, err := json.Marshal(s.history)
|
2015-10-27 01:16:02 +00:00
|
|
|
if err != nil {
|
2015-10-27 22:23:39 +00:00
|
|
|
http.Error(rw, fmt.Sprintf("%v", err), http.StatusInternalServerError)
|
|
|
|
return
|
2015-10-27 01:16:02 +00:00
|
|
|
}
|
|
|
|
|
2015-10-27 23:27:44 +00:00
|
|
|
rw.Header().Add("Access-Control-Allow-Origin", "*")
|
2015-10-27 01:16:02 +00:00
|
|
|
rw.Write(encoded)
|
|
|
|
}
|
2015-10-27 22:23:39 +00:00
|
|
|
|
|
|
|
func (s *Server) takeSnapshots() {
|
|
|
|
for range time.NewTicker(serverSnapshotIntervl).C {
|
|
|
|
s.Lock()
|
|
|
|
for name, stat := range s.stats {
|
|
|
|
if len(s.history[name]) >= serverHistorySize {
|
|
|
|
s.history[name] = s.history[name][1:]
|
|
|
|
}
|
|
|
|
s.history[name] = append(s.history[name], stat.snapshot())
|
|
|
|
}
|
|
|
|
s.Unlock()
|
|
|
|
}
|
|
|
|
}
|