rclone/vendor/github.com/spacemonkeygo/monkit/v3/val.go
2020-05-12 15:56:50 +00:00

204 lines
4.7 KiB
Go

// Copyright (C) 2015 Space Monkey, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package monkit
import (
"sync"
"sync/atomic"
)
// IntVal is a convenience wrapper around an IntDist. Constructed using
// NewIntVal, though its expected usage is like:
//
// var mon = monkit.Package()
//
// func MyFunc() {
// ...
// mon.IntVal("size").Observe(val)
// ...
// }
//
type IntVal struct {
mtx sync.Mutex
dist IntDist
}
// NewIntVal creates an IntVal
func NewIntVal(key SeriesKey) (v *IntVal) {
v = &IntVal{}
initIntDist(&v.dist, key)
return v
}
// Observe observes an integer value
func (v *IntVal) Observe(val int64) {
v.mtx.Lock()
v.dist.Insert(val)
v.mtx.Unlock()
}
// Stats implements the StatSource interface.
func (v *IntVal) Stats(cb func(key SeriesKey, field string, val float64)) {
v.mtx.Lock()
vd := v.dist.Copy()
v.mtx.Unlock()
vd.Stats(cb)
}
// Quantile returns an estimate of the requested quantile of observed values.
// 0 <= quantile <= 1
func (v *IntVal) Quantile(quantile float64) (rv int64) {
v.mtx.Lock()
rv = v.dist.Query(quantile)
v.mtx.Unlock()
return rv
}
// FloatVal is a convenience wrapper around an FloatDist. Constructed using
// NewFloatVal, though its expected usage is like:
//
// var mon = monkit.Package()
//
// func MyFunc() {
// ...
// mon.FloatVal("size").Observe(val)
// ...
// }
//
type FloatVal struct {
mtx sync.Mutex
dist FloatDist
}
// NewFloatVal creates a FloatVal
func NewFloatVal(key SeriesKey) (v *FloatVal) {
v = &FloatVal{}
initFloatDist(&v.dist, key)
return v
}
// Observe observes an floating point value
func (v *FloatVal) Observe(val float64) {
v.mtx.Lock()
v.dist.Insert(val)
v.mtx.Unlock()
}
// Stats implements the StatSource interface.
func (v *FloatVal) Stats(cb func(key SeriesKey, field string, val float64)) {
v.mtx.Lock()
vd := v.dist.Copy()
v.mtx.Unlock()
vd.Stats(cb)
}
// Quantile returns an estimate of the requested quantile of observed values.
// 0 <= quantile <= 1
func (v *FloatVal) Quantile(quantile float64) (rv float64) {
v.mtx.Lock()
rv = v.dist.Query(quantile)
v.mtx.Unlock()
return rv
}
// BoolVal keeps statistics about boolean values. It keeps the number of trues,
// number of falses, and the disposition (number of trues minus number of
// falses). Constructed using NewBoolVal, though its expected usage is like:
//
// var mon = monkit.Package()
//
// func MyFunc() {
// ...
// mon.BoolVal("flipped").Observe(bool)
// ...
// }
//
type BoolVal struct {
trues int64
falses int64
recent int32
key SeriesKey
}
// NewBoolVal creates a BoolVal
func NewBoolVal(key SeriesKey) *BoolVal {
return &BoolVal{key: key}
}
// Observe observes a boolean value
func (v *BoolVal) Observe(val bool) {
if val {
atomic.AddInt64(&v.trues, 1)
atomic.StoreInt32(&v.recent, 1)
} else {
atomic.AddInt64(&v.falses, 1)
atomic.StoreInt32(&v.recent, 0)
}
}
// Stats implements the StatSource interface.
func (v *BoolVal) Stats(cb func(key SeriesKey, field string, val float64)) {
trues := atomic.LoadInt64(&v.trues)
falses := atomic.LoadInt64(&v.falses)
recent := atomic.LoadInt32(&v.recent)
cb(v.key, "disposition", float64(trues-falses))
cb(v.key, "false", float64(falses))
cb(v.key, "recent", float64(recent))
cb(v.key, "true", float64(trues))
}
// StructVal keeps track of a structure of data. Constructed using
// NewStructVal, though its expected usage is like:
//
// var mon = monkit.Package()
//
// func MyFunc() {
// ...
// mon.StructVal("stats").Observe(stats)
// ...
// }
//
type StructVal struct {
mtx sync.Mutex
recent interface{}
key SeriesKey
}
// NewStructVal creates a StructVal
func NewStructVal(key SeriesKey) *StructVal {
return &StructVal{key: key}
}
// Observe observes a struct value. Only the fields convertable to float64 will
// be monitored. A reference to the most recently called Observe value is kept
// for reading when Stats is called.
func (v *StructVal) Observe(val interface{}) {
v.mtx.Lock()
v.recent = val
v.mtx.Unlock()
}
// Stats implements the StatSource interface.
func (v *StructVal) Stats(cb func(key SeriesKey, field string, val float64)) {
v.mtx.Lock()
recent := v.recent
v.mtx.Unlock()
if recent != nil {
StatSourceFromStruct(v.key, recent).Stats(cb)
}
}