2013-05-06 13:03:52 +04:00
|
|
|
package stats
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2013-05-23 19:53:58 +04:00
|
|
|
"goposm/logging"
|
2013-05-06 13:03:52 +04:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2013-05-10 15:55:14 +04:00
|
|
|
type RpsCounter struct {
|
|
|
|
counter int64
|
|
|
|
lastAdd int64
|
|
|
|
start time.Time
|
|
|
|
stop time.Time
|
|
|
|
updated bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RpsCounter) Add(n int) {
|
|
|
|
r.counter += int64(n)
|
|
|
|
r.lastAdd += int64(n)
|
|
|
|
if n > 0 {
|
|
|
|
if r.start.IsZero() {
|
|
|
|
r.start = time.Now()
|
|
|
|
}
|
|
|
|
r.updated = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RpsCounter) Value() int64 {
|
|
|
|
return r.counter
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RpsCounter) Rps(round int) int32 {
|
|
|
|
rps := float64(r.counter) / float64(r.stop.Sub(r.start).Seconds())
|
|
|
|
return int32(rps/float64(round)) * int32(round)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RpsCounter) LastRps(round int32) int32 {
|
|
|
|
rps := float64(r.lastAdd) / float64(time.Since(r.stop).Seconds())
|
|
|
|
return int32(rps/float64(round)) * int32(round)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RpsCounter) Tick() {
|
|
|
|
if r.updated {
|
|
|
|
r.stop = time.Now()
|
|
|
|
r.updated = false
|
|
|
|
}
|
|
|
|
r.lastAdd = 0
|
|
|
|
}
|
|
|
|
|
2013-05-06 13:03:52 +04:00
|
|
|
type counter struct {
|
2013-05-10 15:55:14 +04:00
|
|
|
start time.Time
|
|
|
|
coords RpsCounter
|
|
|
|
nodes RpsCounter
|
|
|
|
ways RpsCounter
|
|
|
|
relations RpsCounter
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *counter) Tick() {
|
|
|
|
c.coords.Tick()
|
|
|
|
c.nodes.Tick()
|
|
|
|
c.ways.Tick()
|
|
|
|
c.relations.Tick()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Duration returns the duration since start with seconds precission.
|
|
|
|
func (c *counter) Duration() time.Duration {
|
|
|
|
return time.Duration(int64(time.Since(c.start).Seconds()) * 1000 * 1000 * 1000)
|
2013-05-06 13:03:52 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
type Statistics struct {
|
|
|
|
coords chan int
|
|
|
|
nodes chan int
|
|
|
|
ways chan int
|
|
|
|
relations chan int
|
2013-05-28 16:07:06 +04:00
|
|
|
status chan int
|
2013-05-06 16:20:00 +04:00
|
|
|
messages chan string
|
2013-05-06 13:03:52 +04:00
|
|
|
}
|
|
|
|
|
2013-05-28 16:07:06 +04:00
|
|
|
const (
|
|
|
|
RESET = iota
|
|
|
|
START
|
|
|
|
STOP
|
|
|
|
QUIT
|
|
|
|
)
|
|
|
|
|
2013-05-06 13:03:52 +04:00
|
|
|
func (s *Statistics) AddCoords(n int) { s.coords <- n }
|
|
|
|
func (s *Statistics) AddNodes(n int) { s.nodes <- n }
|
|
|
|
func (s *Statistics) AddWays(n int) { s.ways <- n }
|
|
|
|
func (s *Statistics) AddRelations(n int) { s.relations <- n }
|
2013-05-28 16:07:06 +04:00
|
|
|
func (s *Statistics) Reset() { s.status <- RESET }
|
|
|
|
func (s *Statistics) Stop() { s.status <- STOP }
|
|
|
|
func (s *Statistics) Start() { s.status <- START }
|
|
|
|
func (s *Statistics) Quit() { s.status <- QUIT }
|
2013-05-06 16:20:00 +04:00
|
|
|
func (s *Statistics) Message(msg string) { s.messages <- msg }
|
2013-05-06 13:03:52 +04:00
|
|
|
|
|
|
|
func StatsReporter() *Statistics {
|
|
|
|
c := counter{}
|
2013-05-10 15:55:14 +04:00
|
|
|
c.start = time.Now()
|
2013-05-06 13:03:52 +04:00
|
|
|
s := Statistics{}
|
|
|
|
s.coords = make(chan int)
|
|
|
|
s.nodes = make(chan int)
|
|
|
|
s.ways = make(chan int)
|
|
|
|
s.relations = make(chan int)
|
2013-05-28 16:07:06 +04:00
|
|
|
s.status = make(chan int)
|
2013-05-06 16:20:00 +04:00
|
|
|
s.messages = make(chan string)
|
2013-05-06 13:03:52 +04:00
|
|
|
|
|
|
|
go func() {
|
2013-05-28 16:07:06 +04:00
|
|
|
var tick, tock <-chan time.Time
|
2013-05-06 13:03:52 +04:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case n := <-s.coords:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.coords.Add(n)
|
2013-05-06 13:03:52 +04:00
|
|
|
case n := <-s.nodes:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.nodes.Add(n)
|
2013-05-06 13:03:52 +04:00
|
|
|
case n := <-s.ways:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.ways.Add(n)
|
2013-05-06 13:03:52 +04:00
|
|
|
case n := <-s.relations:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.relations.Add(n)
|
2013-05-28 16:07:06 +04:00
|
|
|
case v := <-s.status:
|
|
|
|
switch v {
|
|
|
|
case RESET:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.PrintStats()
|
|
|
|
c = counter{}
|
|
|
|
c.start = time.Now()
|
2013-05-28 16:07:06 +04:00
|
|
|
case QUIT:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.PrintStats()
|
|
|
|
return
|
2013-05-28 16:07:06 +04:00
|
|
|
case STOP:
|
|
|
|
tick = nil
|
|
|
|
tock = nil
|
|
|
|
c.PrintStats()
|
2013-05-28 16:42:14 +04:00
|
|
|
case START:
|
2013-05-28 16:07:06 +04:00
|
|
|
c = counter{}
|
|
|
|
c.start = time.Now()
|
|
|
|
tick = time.Tick(500 * time.Millisecond)
|
|
|
|
tock = time.Tick(time.Minute)
|
2013-05-10 15:55:14 +04:00
|
|
|
}
|
2013-05-06 16:20:00 +04:00
|
|
|
case msg := <-s.messages:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.PrintTick()
|
2013-05-06 16:20:00 +04:00
|
|
|
fmt.Println("\n", msg)
|
2013-05-10 15:55:14 +04:00
|
|
|
case <-tock:
|
|
|
|
c.PrintStats()
|
2013-05-06 13:03:52 +04:00
|
|
|
case <-tick:
|
2013-05-10 15:55:14 +04:00
|
|
|
c.PrintTick()
|
|
|
|
c.Tick()
|
2013-05-06 13:03:52 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
return &s
|
|
|
|
}
|
|
|
|
|
2013-05-10 15:55:14 +04:00
|
|
|
func (c *counter) PrintTick() {
|
2013-05-23 19:53:58 +04:00
|
|
|
logging.Progress(
|
2013-05-28 16:07:06 +04:00
|
|
|
fmt.Sprintf("[%6s] C: %7d/s %7d/s (%10d) N: %7d/s %7d/s (%9d) W: %7d/s %7d/s (%8d) R: %6d/s %6d/s (%7d)",
|
2013-05-23 19:53:58 +04:00
|
|
|
c.Duration(),
|
|
|
|
c.coords.Rps(1000),
|
|
|
|
c.coords.LastRps(1000),
|
|
|
|
c.coords.Value(),
|
|
|
|
c.nodes.Rps(100),
|
|
|
|
c.nodes.LastRps(100),
|
|
|
|
c.nodes.Value(),
|
|
|
|
c.ways.Rps(100),
|
|
|
|
c.ways.LastRps(100),
|
|
|
|
c.ways.Value(),
|
|
|
|
c.relations.Rps(10),
|
|
|
|
c.relations.LastRps(10),
|
|
|
|
c.relations.Value(),
|
|
|
|
))
|
2013-05-10 15:55:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *counter) PrintStats() {
|
2013-05-23 19:53:58 +04:00
|
|
|
logging.Infof("[%6s] C: %7d/s (%10d) N: %7d/s (%9d) W: %7d/s (%8d) R: %6d/s (%7d)",
|
2013-05-10 15:55:14 +04:00
|
|
|
c.Duration(),
|
|
|
|
c.coords.Rps(1000),
|
|
|
|
c.coords.Value(),
|
|
|
|
c.nodes.Rps(100),
|
|
|
|
c.nodes.Value(),
|
|
|
|
c.ways.Rps(100),
|
|
|
|
c.ways.Value(),
|
|
|
|
c.relations.Rps(10),
|
|
|
|
c.relations.Value(),
|
2013-05-06 13:03:52 +04:00
|
|
|
)
|
|
|
|
}
|