directory structure change to work with glide
glide has its own requirements. My previous workaround caused me some code checkin errors. Need to fix this.
This commit is contained in:
14
weed/stats/disk.go
Normal file
14
weed/stats/disk.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package stats
|
||||
|
||||
type DiskStatus struct {
|
||||
Dir string
|
||||
All uint64
|
||||
Used uint64
|
||||
Free uint64
|
||||
}
|
||||
|
||||
func NewDiskStatus(path string) (disk *DiskStatus) {
|
||||
disk = &DiskStatus{Dir: path}
|
||||
disk.fillInStatus()
|
||||
return
|
||||
}
|
||||
7
weed/stats/disk_notsupported.go
Normal file
7
weed/stats/disk_notsupported.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// +build windows openbsd netbsd plan9 solaris
|
||||
|
||||
package stats
|
||||
|
||||
func (disk *DiskStatus) fillInStatus() {
|
||||
return
|
||||
}
|
||||
19
weed/stats/disk_supported.go
Normal file
19
weed/stats/disk_supported.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// +build !windows,!openbsd,!netbsd,!plan9,!solaris
|
||||
|
||||
package stats
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (disk *DiskStatus) fillInStatus() {
|
||||
fs := syscall.Statfs_t{}
|
||||
err := syscall.Statfs(disk.Dir, &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
|
||||
}
|
||||
94
weed/stats/duration_counter.go
Normal file
94
weed/stats/duration_counter.go
Normal file
@@ -0,0 +1,94 @@
|
||||
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) {
|
||||
if index >= len(rrc.Values) {
|
||||
return
|
||||
}
|
||||
for rrc.LastIndex != index {
|
||||
rrc.LastIndex = (rrc.LastIndex + 1) % len(rrc.Values)
|
||||
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
|
||||
}
|
||||
|
||||
func (rrc *RoundRobinCounter) ToList() (ret []int64) {
|
||||
index := rrc.LastIndex
|
||||
step := len(rrc.Values)
|
||||
for step > 0 {
|
||||
step--
|
||||
index++
|
||||
if index >= len(rrc.Values) {
|
||||
index = 0
|
||||
}
|
||||
ret = append(ret, rrc.Values[index])
|
||||
}
|
||||
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)
|
||||
}
|
||||
19
weed/stats/duration_counter_test.go
Normal file
19
weed/stats/duration_counter_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package stats
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestRobinCounter(t *testing.T) {
|
||||
rrc := NewRoundRobinCounter(60)
|
||||
rrc.Add(0, 1)
|
||||
rrc.Add(50, 2)
|
||||
if rrc.Count() != 2 {
|
||||
t.Fatal()
|
||||
}
|
||||
if rrc.Sum() != 3 {
|
||||
t.Fatal()
|
||||
}
|
||||
/*
|
||||
index out of range
|
||||
*/
|
||||
rrc.Add(61, 1)
|
||||
}
|
||||
28
weed/stats/memory.go
Normal file
28
weed/stats/memory.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package stats
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type MemStatus struct {
|
||||
Goroutines int
|
||||
All uint64
|
||||
Used uint64
|
||||
Free uint64
|
||||
Self uint64
|
||||
Heap uint64
|
||||
Stack uint64
|
||||
}
|
||||
|
||||
func MemStat() MemStatus {
|
||||
mem := MemStatus{}
|
||||
mem.Goroutines = runtime.NumGoroutine()
|
||||
memStat := new(runtime.MemStats)
|
||||
runtime.ReadMemStats(memStat)
|
||||
mem.Self = memStat.Alloc
|
||||
mem.Heap = memStat.HeapAlloc
|
||||
mem.Stack = memStat.StackInuse
|
||||
|
||||
mem.fillInStatus()
|
||||
return mem
|
||||
}
|
||||
7
weed/stats/memory_notsupported.go
Normal file
7
weed/stats/memory_notsupported.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// +build !linux
|
||||
|
||||
package stats
|
||||
|
||||
func (mem *MemStatus) fillInStatus() {
|
||||
return
|
||||
}
|
||||
18
weed/stats/memory_supported.go
Normal file
18
weed/stats/memory_supported.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// +build linux
|
||||
|
||||
package stats
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (mem *MemStatus) fillInStatus() {
|
||||
//system memory usage
|
||||
sysInfo := new(syscall.Sysinfo_t)
|
||||
err := syscall.Sysinfo(sysInfo)
|
||||
if err == nil {
|
||||
mem.All = uint64(sysInfo.Totalram) //* uint64(syscall.Getpagesize())
|
||||
mem.Free = uint64(sysInfo.Freeram) //* uint64(syscall.Getpagesize())
|
||||
mem.Used = mem.All - mem.Free
|
||||
}
|
||||
}
|
||||
113
weed/stats/stats.go
Normal file
113
weed/stats/stats.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user