-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathweb_reporter.go
77 lines (62 loc) · 1.75 KB
/
web_reporter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main
/*
Web Reporter
Will hold a series of Health reports, so that it will be easy to
plot things like time-series.
Every `ReportHealth` invocation will tuck an additional Health value
onto the series.
The series width is fixed and old measurements are dropped (this is a
moving window).
A couple of configuration parameters are relevant here:
historyInterval - at what distance to take measurements in seconds
(every minute, hour, etc)
historyBacklog - how many measurement points to hold. This affects
memory usage
*/
import (
"container/ring"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
type WebReporter struct {
health Health
Mount string
history *ring.Ring
lastReport time.Time
historyInterval int
}
func NewWebReporter(historyInter int, historyBacklog int) (h *WebReporter) {
return &WebReporter{Mount: "/health", history: ring.New(historyBacklog), historyInterval: historyInter}
}
func (self *WebReporter) ReportHealth(h *Health) {
self.health = *h
self.addReading(*h)
}
func (self *WebReporter) addReading(h Health) {
t := time.Now()
if t.Sub(self.lastReport).Seconds() > float64(self.historyInterval) {
self.lastReport = t
p := self.history.Prev()
p.Value = map[string]Health{fmt.Sprintf("%d", t.Unix()): h}
self.history = p
}
}
func (self *WebReporter) Handler(w http.ResponseWriter, r *http.Request) {
hdr := w.Header()
hdr.Add("Access-Control-Allow-Origin", "*")
series := []map[string]Health{}
self.history.Do(func(x interface{}) {
if x != nil {
series = append(series, x.(map[string]Health))
}
})
log.Println("series", series)
enc := json.NewEncoder(w)
err := enc.Encode(&series)
if err != nil {
log.Println("encoding error", err)
}
}