diff options
| author | Chris Lu <chris.lu@gmail.com> | 2014-03-25 13:46:59 -0700 |
|---|---|---|
| committer | Chris Lu <chris.lu@gmail.com> | 2014-03-25 13:46:59 -0700 |
| commit | 39b774a131ac3bc454a516f7b72dcefabc593103 (patch) | |
| tree | 804763e28b55b1e30ebfefced71b552b8e3e34a1 /go/stats | |
| parent | 6e0601a73bf199e7d3ffd3cd2990223e959d3e24 (diff) | |
| download | seaweedfs-39b774a131ac3bc454a516f7b72dcefabc593103.tar.xz seaweedfs-39b774a131ac3bc454a516f7b72dcefabc593103.zip | |
1. adding statistics reporting
2. refactor version to util package
Diffstat (limited to 'go/stats')
| -rw-r--r-- | go/stats/disk.go | 26 | ||||
| -rw-r--r-- | go/stats/disk_windows.go | 17 | ||||
| -rw-r--r-- | go/stats/duration_counter.go | 83 | ||||
| -rw-r--r-- | go/stats/stats.go | 113 |
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) + } + } +} |
