Initial QSfera import
This commit is contained in:
+189
@@ -0,0 +1,189 @@
|
||||
package kafka
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SummaryStats is a data structure that carries a summary of observed values.
|
||||
type SummaryStats struct {
|
||||
Avg int64 `metric:"avg" type:"gauge"`
|
||||
Min int64 `metric:"min" type:"gauge"`
|
||||
Max int64 `metric:"max" type:"gauge"`
|
||||
Count int64 `metric:"count" type:"counter"`
|
||||
Sum int64 `metric:"sum" type:"counter"`
|
||||
}
|
||||
|
||||
// DurationStats is a data structure that carries a summary of observed duration values.
|
||||
type DurationStats struct {
|
||||
Avg time.Duration `metric:"avg" type:"gauge"`
|
||||
Min time.Duration `metric:"min" type:"gauge"`
|
||||
Max time.Duration `metric:"max" type:"gauge"`
|
||||
Count int64 `metric:"count" type:"counter"`
|
||||
Sum time.Duration `metric:"sum" type:"counter"`
|
||||
}
|
||||
|
||||
// counter is an atomic incrementing counter which gets reset on snapshot.
|
||||
//
|
||||
// Since atomic is used to mutate the statistic the value must be 64-bit aligned.
|
||||
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
type counter int64
|
||||
|
||||
func (c *counter) ptr() *int64 {
|
||||
return (*int64)(c)
|
||||
}
|
||||
|
||||
func (c *counter) observe(v int64) {
|
||||
atomic.AddInt64(c.ptr(), v)
|
||||
}
|
||||
|
||||
func (c *counter) snapshot() int64 {
|
||||
return atomic.SwapInt64(c.ptr(), 0)
|
||||
}
|
||||
|
||||
// gauge is an atomic integer that may be set to any arbitrary value, the value
|
||||
// does not change after a snapshot.
|
||||
//
|
||||
// Since atomic is used to mutate the statistic the value must be 64-bit aligned.
|
||||
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
type gauge int64
|
||||
|
||||
func (g *gauge) ptr() *int64 {
|
||||
return (*int64)(g)
|
||||
}
|
||||
|
||||
func (g *gauge) observe(v int64) {
|
||||
atomic.StoreInt64(g.ptr(), v)
|
||||
}
|
||||
|
||||
func (g *gauge) snapshot() int64 {
|
||||
return atomic.LoadInt64(g.ptr())
|
||||
}
|
||||
|
||||
// minimum is an atomic integral type that keeps track of the minimum of all
|
||||
// values that it observed between snapshots.
|
||||
//
|
||||
// Since atomic is used to mutate the statistic the value must be 64-bit aligned.
|
||||
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
type minimum int64
|
||||
|
||||
func (m *minimum) ptr() *int64 {
|
||||
return (*int64)(m)
|
||||
}
|
||||
|
||||
func (m *minimum) observe(v int64) {
|
||||
for {
|
||||
ptr := m.ptr()
|
||||
min := atomic.LoadInt64(ptr)
|
||||
|
||||
if min >= 0 && min <= v {
|
||||
break
|
||||
}
|
||||
|
||||
if atomic.CompareAndSwapInt64(ptr, min, v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *minimum) snapshot() int64 {
|
||||
p := m.ptr()
|
||||
v := atomic.LoadInt64(p)
|
||||
atomic.CompareAndSwapInt64(p, v, -1)
|
||||
if v < 0 {
|
||||
v = 0
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// maximum is an atomic integral type that keeps track of the maximum of all
|
||||
// values that it observed between snapshots.
|
||||
//
|
||||
// Since atomic is used to mutate the statistic the value must be 64-bit aligned.
|
||||
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG
|
||||
type maximum int64
|
||||
|
||||
func (m *maximum) ptr() *int64 {
|
||||
return (*int64)(m)
|
||||
}
|
||||
|
||||
func (m *maximum) observe(v int64) {
|
||||
for {
|
||||
ptr := m.ptr()
|
||||
max := atomic.LoadInt64(ptr)
|
||||
|
||||
if max >= 0 && max >= v {
|
||||
break
|
||||
}
|
||||
|
||||
if atomic.CompareAndSwapInt64(ptr, max, v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *maximum) snapshot() int64 {
|
||||
p := m.ptr()
|
||||
v := atomic.LoadInt64(p)
|
||||
atomic.CompareAndSwapInt64(p, v, -1)
|
||||
if v < 0 {
|
||||
v = 0
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
type summary struct {
|
||||
min minimum
|
||||
max maximum
|
||||
sum counter
|
||||
count counter
|
||||
}
|
||||
|
||||
func makeSummary() summary {
|
||||
return summary{
|
||||
min: -1,
|
||||
max: -1,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *summary) observe(v int64) {
|
||||
s.min.observe(v)
|
||||
s.max.observe(v)
|
||||
s.sum.observe(v)
|
||||
s.count.observe(1)
|
||||
}
|
||||
|
||||
func (s *summary) observeDuration(v time.Duration) {
|
||||
s.observe(int64(v))
|
||||
}
|
||||
|
||||
func (s *summary) snapshot() SummaryStats {
|
||||
avg := int64(0)
|
||||
min := s.min.snapshot()
|
||||
max := s.max.snapshot()
|
||||
sum := s.sum.snapshot()
|
||||
count := s.count.snapshot()
|
||||
|
||||
if count != 0 {
|
||||
avg = int64(float64(sum) / float64(count))
|
||||
}
|
||||
|
||||
return SummaryStats{
|
||||
Avg: avg,
|
||||
Min: min,
|
||||
Max: max,
|
||||
Count: count,
|
||||
Sum: sum,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *summary) snapshotDuration() DurationStats {
|
||||
summary := s.snapshot()
|
||||
return DurationStats{
|
||||
Avg: time.Duration(summary.Avg),
|
||||
Min: time.Duration(summary.Min),
|
||||
Max: time.Duration(summary.Max),
|
||||
Count: summary.Count,
|
||||
Sum: time.Duration(summary.Sum),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user