aboutsummaryrefslogtreecommitdiff
path: root/go/stats
diff options
context:
space:
mode:
Diffstat (limited to 'go/stats')
-rw-r--r--go/stats/disk.go26
-rw-r--r--go/stats/disk_windows.go17
-rw-r--r--go/stats/duration_counter.go83
-rw-r--r--go/stats/stats.go113
4 files changed, 239 insertions, 0 deletions
diff --git a/go/stats/disk.go b/go/stats/disk.go
new file mode 100644
index 000000000..acbbd51b9
--- /dev/null
+++ b/go/stats/disk.go
@@ -0,0 +1,26 @@
+// +build !windows
+
+package stats
+
+import (
+ "syscall"
+)
+
+type DiskStatus struct {
+ All uint64 `json:"all"`
+ Used uint64 `json:"used"`
+ Free uint64 `json:"free"`
+}
+
+func DiskUsage(path string) (disk *DiskStatus) {
+ disk = &DiskStatus{}
+ fs := syscall.Statfs_t{}
+ err := syscall.Statfs(path, &fs)
+ if err != nil {
+ return
+ }
+ disk.All = fs.Blocks * uint64(fs.Bsize)
+ disk.Free = fs.Bfree * uint64(fs.Bsize)
+ disk.Used = disk.All - disk.Free
+ return
+}
diff --git a/go/stats/disk_windows.go b/go/stats/disk_windows.go
new file mode 100644
index 000000000..7db7668d6
--- /dev/null
+++ b/go/stats/disk_windows.go
@@ -0,0 +1,17 @@
+// +build windows
+
+package stats
+
+import (
+ "syscall"
+)
+
+type DiskStatus struct {
+ All uint64 `json:"all"`
+ Used uint64 `json:"used"`
+ Free uint64 `json:"free"`
+}
+
+func DiskUsage(path string) (disk *DiskStatus) {
+ return
+}
diff --git a/go/stats/duration_counter.go b/go/stats/duration_counter.go
new file mode 100644
index 000000000..254a95fc7
--- /dev/null
+++ b/go/stats/duration_counter.go
@@ -0,0 +1,83 @@
+package stats
+
+import (
+ "time"
+)
+
+type TimedValue struct {
+ t time.Time
+ val int64
+}
+
+func NewTimedValue(t time.Time, val int64) *TimedValue {
+ return &TimedValue{t: t, val: val}
+}
+
+type RoundRobinCounter struct {
+ LastIndex int
+ Values []int64
+ Counts []int64
+}
+
+func NewRoundRobinCounter(slots int) *RoundRobinCounter {
+ return &RoundRobinCounter{LastIndex: -1, Values: make([]int64, slots), Counts: make([]int64, slots)}
+}
+func (rrc *RoundRobinCounter) Add(index int, val int64) {
+ for rrc.LastIndex != index {
+ rrc.LastIndex++
+ if rrc.LastIndex >= len(rrc.Values) {
+ if index >= len(rrc.Values) {
+ break //just avoid endless loop
+ }
+ rrc.LastIndex = 0
+ }
+ rrc.Values[rrc.LastIndex] = 0
+ rrc.Counts[rrc.LastIndex] = 0
+ }
+ rrc.Values[index] += val
+ rrc.Counts[index]++
+}
+func (rrc *RoundRobinCounter) Max() (max int64) {
+ for _, val := range rrc.Values {
+ if max < val {
+ max = val
+ }
+ }
+ return
+}
+func (rrc *RoundRobinCounter) Count() (cnt int64) {
+ for _, c := range rrc.Counts {
+ cnt += c
+ }
+ return
+}
+func (rrc *RoundRobinCounter) Sum() (sum int64) {
+ for _, val := range rrc.Values {
+ sum += val
+ }
+ return
+}
+
+type DurationCounter struct {
+ MinuteCounter *RoundRobinCounter
+ HourCounter *RoundRobinCounter
+ DayCounter *RoundRobinCounter
+ WeekCounter *RoundRobinCounter
+}
+
+func NewDurationCounter() *DurationCounter {
+ return &DurationCounter{
+ MinuteCounter: NewRoundRobinCounter(60),
+ HourCounter: NewRoundRobinCounter(60),
+ DayCounter: NewRoundRobinCounter(24),
+ WeekCounter: NewRoundRobinCounter(7),
+ }
+}
+
+// Add is for cumulative counts
+func (sc *DurationCounter) Add(tv *TimedValue) {
+ sc.MinuteCounter.Add(tv.t.Second(), tv.val)
+ sc.HourCounter.Add(tv.t.Minute(), tv.val)
+ sc.DayCounter.Add(tv.t.Hour(), tv.val)
+ sc.WeekCounter.Add(int(tv.t.Weekday()), tv.val)
+}
diff --git a/go/stats/stats.go b/go/stats/stats.go
new file mode 100644
index 000000000..09826152f
--- /dev/null
+++ b/go/stats/stats.go
@@ -0,0 +1,113 @@
+package stats
+
+import (
+ "time"
+)
+
+type ServerStats struct {
+ Requests *DurationCounter
+ Connections *DurationCounter
+ AssignRequests *DurationCounter
+ ReadRequests *DurationCounter
+ WriteRequests *DurationCounter
+ DeleteRequests *DurationCounter
+ BytesIn *DurationCounter
+ BytesOut *DurationCounter
+}
+
+type Channels struct {
+ Connections chan *TimedValue
+ Requests chan *TimedValue
+ AssignRequests chan *TimedValue
+ ReadRequests chan *TimedValue
+ WriteRequests chan *TimedValue
+ DeleteRequests chan *TimedValue
+ BytesIn chan *TimedValue
+ BytesOut chan *TimedValue
+}
+
+var (
+ Chan *Channels
+)
+
+func init() {
+ Chan = &Channels{
+ Connections: make(chan *TimedValue, 100),
+ Requests: make(chan *TimedValue, 100),
+ AssignRequests: make(chan *TimedValue, 100),
+ ReadRequests: make(chan *TimedValue, 100),
+ WriteRequests: make(chan *TimedValue, 100),
+ DeleteRequests: make(chan *TimedValue, 100),
+ BytesIn: make(chan *TimedValue, 100),
+ BytesOut: make(chan *TimedValue, 100),
+ }
+}
+
+func NewServerStats() *ServerStats {
+ return &ServerStats{
+ Requests: NewDurationCounter(),
+ Connections: NewDurationCounter(),
+ AssignRequests: NewDurationCounter(),
+ ReadRequests: NewDurationCounter(),
+ WriteRequests: NewDurationCounter(),
+ DeleteRequests: NewDurationCounter(),
+ BytesIn: NewDurationCounter(),
+ BytesOut: NewDurationCounter(),
+ }
+}
+
+func ConnectionOpen() {
+ Chan.Connections <- NewTimedValue(time.Now(), 1)
+}
+func ConnectionClose() {
+ Chan.Connections <- NewTimedValue(time.Now(), -1)
+}
+func RequestOpen() {
+ Chan.Requests <- NewTimedValue(time.Now(), 1)
+}
+func RequestClose() {
+ Chan.Requests <- NewTimedValue(time.Now(), -1)
+}
+func AssignRequest() {
+ Chan.AssignRequests <- NewTimedValue(time.Now(), 1)
+}
+func ReadRequest() {
+ Chan.ReadRequests <- NewTimedValue(time.Now(), 1)
+}
+func WriteRequest() {
+ Chan.WriteRequests <- NewTimedValue(time.Now(), 1)
+}
+func DeleteRequest() {
+ Chan.DeleteRequests <- NewTimedValue(time.Now(), 1)
+}
+func BytesIn(val int64) {
+ Chan.BytesIn <- NewTimedValue(time.Now(), val)
+}
+func BytesOut(val int64) {
+ Chan.BytesOut <- NewTimedValue(time.Now(), val)
+}
+
+func (ss *ServerStats) Start() {
+ for {
+ select {
+ case tv := <-Chan.Connections:
+ ss.Connections.Add(tv)
+ case tv := <-Chan.Requests:
+ ss.Requests.Add(tv)
+ case tv := <-Chan.AssignRequests:
+ ss.AssignRequests.Add(tv)
+ case tv := <-Chan.ReadRequests:
+ ss.ReadRequests.Add(tv)
+ case tv := <-Chan.WriteRequests:
+ ss.WriteRequests.Add(tv)
+ case tv := <-Chan.ReadRequests:
+ ss.ReadRequests.Add(tv)
+ case tv := <-Chan.DeleteRequests:
+ ss.DeleteRequests.Add(tv)
+ case tv := <-Chan.BytesIn:
+ ss.BytesIn.Add(tv)
+ case tv := <-Chan.BytesOut:
+ ss.BytesOut.Add(tv)
+ }
+ }
+}