Update oxy dependency
This commit is contained in:
parent
d81c4e6d1a
commit
07be89d6e9
31 changed files with 636 additions and 195 deletions
6
vendor/github.com/vulcand/oxy/memmetrics/anomaly.go
generated
vendored
6
vendor/github.com/vulcand/oxy/memmetrics/anomaly.go
generated
vendored
|
@ -6,7 +6,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// SplitRatios provides simple anomaly detection for requests latencies.
|
||||
// SplitLatencies provides simple anomaly detection for requests latencies.
|
||||
// it splits values into good or bad category based on the threshold and the median value.
|
||||
// If all values are not far from the median, it will return all values in 'good' set.
|
||||
// Precision is the smallest value to consider, e.g. if set to millisecond, microseconds will be ignored.
|
||||
|
@ -23,10 +23,10 @@ func SplitLatencies(values []time.Duration, precision time.Duration) (good map[t
|
|||
good, bad = make(map[time.Duration]bool), make(map[time.Duration]bool)
|
||||
// Note that multiplier makes this function way less sensitive than ratios detector, this is to avoid noise.
|
||||
vgood, vbad := SplitFloat64(2, 0, ratios)
|
||||
for r, _ := range vgood {
|
||||
for r := range vgood {
|
||||
good[v2r[r]] = true
|
||||
}
|
||||
for r, _ := range vbad {
|
||||
for r := range vbad {
|
||||
bad[v2r[r]] = true
|
||||
}
|
||||
return good, bad
|
||||
|
|
12
vendor/github.com/vulcand/oxy/memmetrics/counter.go
generated
vendored
12
vendor/github.com/vulcand/oxy/memmetrics/counter.go
generated
vendored
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
type rcOptSetter func(*RollingCounter) error
|
||||
|
||||
// CounterClock defines a counter clock
|
||||
func CounterClock(c timetools.TimeProvider) rcOptSetter {
|
||||
return func(r *RollingCounter) error {
|
||||
r.clock = c
|
||||
|
@ -16,7 +17,7 @@ func CounterClock(c timetools.TimeProvider) rcOptSetter {
|
|||
}
|
||||
}
|
||||
|
||||
// Calculates in memory failure rate of an endpoint using rolling window of a predefined size
|
||||
// RollingCounter Calculates in memory failure rate of an endpoint using rolling window of a predefined size
|
||||
type RollingCounter struct {
|
||||
clock timetools.TimeProvider
|
||||
resolution time.Duration
|
||||
|
@ -57,11 +58,13 @@ func NewCounter(buckets int, resolution time.Duration, options ...rcOptSetter) (
|
|||
return rc, nil
|
||||
}
|
||||
|
||||
// Append append a counter
|
||||
func (c *RollingCounter) Append(o *RollingCounter) error {
|
||||
c.Inc(int(o.Count()))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clone clone a counter
|
||||
func (c *RollingCounter) Clone() *RollingCounter {
|
||||
c.cleanup()
|
||||
other := &RollingCounter{
|
||||
|
@ -75,6 +78,7 @@ func (c *RollingCounter) Clone() *RollingCounter {
|
|||
return other
|
||||
}
|
||||
|
||||
// Reset reset a counter
|
||||
func (c *RollingCounter) Reset() {
|
||||
c.lastBucket = -1
|
||||
c.countedBuckets = 0
|
||||
|
@ -84,27 +88,33 @@ func (c *RollingCounter) Reset() {
|
|||
}
|
||||
}
|
||||
|
||||
// CountedBuckets gets counted buckets
|
||||
func (c *RollingCounter) CountedBuckets() int {
|
||||
return c.countedBuckets
|
||||
}
|
||||
|
||||
// Count counts
|
||||
func (c *RollingCounter) Count() int64 {
|
||||
c.cleanup()
|
||||
return c.sum()
|
||||
}
|
||||
|
||||
// Resolution gets resolution
|
||||
func (c *RollingCounter) Resolution() time.Duration {
|
||||
return c.resolution
|
||||
}
|
||||
|
||||
// Buckets gets buckets
|
||||
func (c *RollingCounter) Buckets() int {
|
||||
return len(c.values)
|
||||
}
|
||||
|
||||
// WindowSize gets windows size
|
||||
func (c *RollingCounter) WindowSize() time.Duration {
|
||||
return time.Duration(len(c.values)) * c.resolution
|
||||
}
|
||||
|
||||
// Inc increment counter
|
||||
func (c *RollingCounter) Inc(v int) {
|
||||
c.cleanup()
|
||||
c.incBucketValue(v)
|
||||
|
|
30
vendor/github.com/vulcand/oxy/memmetrics/histogram.go
generated
vendored
30
vendor/github.com/vulcand/oxy/memmetrics/histogram.go
generated
vendored
|
@ -20,6 +20,7 @@ type HDRHistogram struct {
|
|||
h *hdrhistogram.Histogram
|
||||
}
|
||||
|
||||
// NewHDRHistogram creates a new HDRHistogram
|
||||
func NewHDRHistogram(low, high int64, sigfigs int) (h *HDRHistogram, err error) {
|
||||
defer func() {
|
||||
if msg := recover(); msg != nil {
|
||||
|
@ -34,37 +35,42 @@ func NewHDRHistogram(low, high int64, sigfigs int) (h *HDRHistogram, err error)
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (r *HDRHistogram) Export() *HDRHistogram {
|
||||
var hist *hdrhistogram.Histogram = nil
|
||||
if r.h != nil {
|
||||
snapshot := r.h.Export()
|
||||
// Export export a HDRHistogram
|
||||
func (h *HDRHistogram) Export() *HDRHistogram {
|
||||
var hist *hdrhistogram.Histogram
|
||||
if h.h != nil {
|
||||
snapshot := h.h.Export()
|
||||
hist = hdrhistogram.Import(snapshot)
|
||||
}
|
||||
return &HDRHistogram{low: r.low, high: r.high, sigfigs: r.sigfigs, h: hist}
|
||||
return &HDRHistogram{low: h.low, high: h.high, sigfigs: h.sigfigs, h: hist}
|
||||
}
|
||||
|
||||
// Returns latency at quantile with microsecond precision
|
||||
// LatencyAtQuantile sets latency at quantile with microsecond precision
|
||||
func (h *HDRHistogram) LatencyAtQuantile(q float64) time.Duration {
|
||||
return time.Duration(h.ValueAtQuantile(q)) * time.Microsecond
|
||||
}
|
||||
|
||||
// Records latencies with microsecond precision
|
||||
// RecordLatencies Records latencies with microsecond precision
|
||||
func (h *HDRHistogram) RecordLatencies(d time.Duration, n int64) error {
|
||||
return h.RecordValues(int64(d/time.Microsecond), n)
|
||||
}
|
||||
|
||||
// Reset reset a HDRHistogram
|
||||
func (h *HDRHistogram) Reset() {
|
||||
h.h.Reset()
|
||||
}
|
||||
|
||||
// ValueAtQuantile sets value at quantile
|
||||
func (h *HDRHistogram) ValueAtQuantile(q float64) int64 {
|
||||
return h.h.ValueAtQuantile(q)
|
||||
}
|
||||
|
||||
// RecordValues sets record values
|
||||
func (h *HDRHistogram) RecordValues(v, n int64) error {
|
||||
return h.h.RecordValues(v, n)
|
||||
}
|
||||
|
||||
// Merge merge a HDRHistogram
|
||||
func (h *HDRHistogram) Merge(other *HDRHistogram) error {
|
||||
if other == nil {
|
||||
return fmt.Errorf("other is nil")
|
||||
|
@ -75,6 +81,7 @@ func (h *HDRHistogram) Merge(other *HDRHistogram) error {
|
|||
|
||||
type rhOptSetter func(r *RollingHDRHistogram) error
|
||||
|
||||
// RollingClock sets a clock
|
||||
func RollingClock(clock timetools.TimeProvider) rhOptSetter {
|
||||
return func(r *RollingHDRHistogram) error {
|
||||
r.clock = clock
|
||||
|
@ -82,7 +89,7 @@ func RollingClock(clock timetools.TimeProvider) rhOptSetter {
|
|||
}
|
||||
}
|
||||
|
||||
// RollingHistogram holds multiple histograms and rotates every period.
|
||||
// RollingHDRHistogram holds multiple histograms and rotates every period.
|
||||
// It provides resulting histogram as a result of a call of 'Merged' function.
|
||||
type RollingHDRHistogram struct {
|
||||
idx int
|
||||
|
@ -96,6 +103,7 @@ type RollingHDRHistogram struct {
|
|||
clock timetools.TimeProvider
|
||||
}
|
||||
|
||||
// NewRollingHDRHistogram created a new RollingHDRHistogram
|
||||
func NewRollingHDRHistogram(low, high int64, sigfigs int, period time.Duration, bucketCount int, options ...rhOptSetter) (*RollingHDRHistogram, error) {
|
||||
rh := &RollingHDRHistogram{
|
||||
bucketCount: bucketCount,
|
||||
|
@ -127,6 +135,7 @@ func NewRollingHDRHistogram(low, high int64, sigfigs int, period time.Duration,
|
|||
return rh, nil
|
||||
}
|
||||
|
||||
// Export export a RollingHDRHistogram
|
||||
func (r *RollingHDRHistogram) Export() *RollingHDRHistogram {
|
||||
export := &RollingHDRHistogram{}
|
||||
export.idx = r.idx
|
||||
|
@ -147,6 +156,7 @@ func (r *RollingHDRHistogram) Export() *RollingHDRHistogram {
|
|||
return export
|
||||
}
|
||||
|
||||
// Append append a RollingHDRHistogram
|
||||
func (r *RollingHDRHistogram) Append(o *RollingHDRHistogram) error {
|
||||
if r.bucketCount != o.bucketCount || r.period != o.period || r.low != o.low || r.high != o.high || r.sigfigs != o.sigfigs {
|
||||
return fmt.Errorf("can't merge")
|
||||
|
@ -160,6 +170,7 @@ func (r *RollingHDRHistogram) Append(o *RollingHDRHistogram) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Reset reset a RollingHDRHistogram
|
||||
func (r *RollingHDRHistogram) Reset() {
|
||||
r.idx = 0
|
||||
r.lastRoll = r.clock.UtcNow()
|
||||
|
@ -173,6 +184,7 @@ func (r *RollingHDRHistogram) rotate() {
|
|||
r.buckets[r.idx].Reset()
|
||||
}
|
||||
|
||||
// Merged gets merged histogram
|
||||
func (r *RollingHDRHistogram) Merged() (*HDRHistogram, error) {
|
||||
m, err := NewHDRHistogram(r.low, r.high, r.sigfigs)
|
||||
if err != nil {
|
||||
|
@ -194,10 +206,12 @@ func (r *RollingHDRHistogram) getHist() *HDRHistogram {
|
|||
return r.buckets[r.idx]
|
||||
}
|
||||
|
||||
// RecordLatencies sets records latencies
|
||||
func (r *RollingHDRHistogram) RecordLatencies(v time.Duration, n int64) error {
|
||||
return r.getHist().RecordLatencies(v, n)
|
||||
}
|
||||
|
||||
// RecordValues set record values
|
||||
func (r *RollingHDRHistogram) RecordValues(v, n int64) error {
|
||||
return r.getHist().RecordValues(v, n)
|
||||
}
|
||||
|
|
17
vendor/github.com/vulcand/oxy/memmetrics/ratio.go
generated
vendored
17
vendor/github.com/vulcand/oxy/memmetrics/ratio.go
generated
vendored
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
type ratioOptSetter func(r *RatioCounter) error
|
||||
|
||||
// RatioClock sets a clock
|
||||
func RatioClock(clock timetools.TimeProvider) ratioOptSetter {
|
||||
return func(r *RatioCounter) error {
|
||||
r.clock = clock
|
||||
|
@ -22,6 +23,7 @@ type RatioCounter struct {
|
|||
b *RollingCounter
|
||||
}
|
||||
|
||||
// NewRatioCounter creates a new RatioCounter
|
||||
func NewRatioCounter(buckets int, resolution time.Duration, options ...ratioOptSetter) (*RatioCounter, error) {
|
||||
rc := &RatioCounter{}
|
||||
|
||||
|
@ -50,39 +52,48 @@ func NewRatioCounter(buckets int, resolution time.Duration, options ...ratioOptS
|
|||
return rc, nil
|
||||
}
|
||||
|
||||
// Reset reset the counter
|
||||
func (r *RatioCounter) Reset() {
|
||||
r.a.Reset()
|
||||
r.b.Reset()
|
||||
}
|
||||
|
||||
// IsReady returns true if the counter is ready
|
||||
func (r *RatioCounter) IsReady() bool {
|
||||
return r.a.countedBuckets+r.b.countedBuckets >= len(r.a.values)
|
||||
}
|
||||
|
||||
// CountA gets count A
|
||||
func (r *RatioCounter) CountA() int64 {
|
||||
return r.a.Count()
|
||||
}
|
||||
|
||||
// CountB gets count B
|
||||
func (r *RatioCounter) CountB() int64 {
|
||||
return r.b.Count()
|
||||
}
|
||||
|
||||
// Resolution gets resolution
|
||||
func (r *RatioCounter) Resolution() time.Duration {
|
||||
return r.a.Resolution()
|
||||
}
|
||||
|
||||
// Buckets gets buckets
|
||||
func (r *RatioCounter) Buckets() int {
|
||||
return r.a.Buckets()
|
||||
}
|
||||
|
||||
// WindowSize gets windows size
|
||||
func (r *RatioCounter) WindowSize() time.Duration {
|
||||
return r.a.WindowSize()
|
||||
}
|
||||
|
||||
// ProcessedCount gets processed count
|
||||
func (r *RatioCounter) ProcessedCount() int64 {
|
||||
return r.CountA() + r.CountB()
|
||||
}
|
||||
|
||||
// Ratio gets ratio
|
||||
func (r *RatioCounter) Ratio() float64 {
|
||||
a := r.a.Count()
|
||||
b := r.b.Count()
|
||||
|
@ -93,28 +104,34 @@ func (r *RatioCounter) Ratio() float64 {
|
|||
return float64(a) / float64(a+b)
|
||||
}
|
||||
|
||||
// IncA increment counter A
|
||||
func (r *RatioCounter) IncA(v int) {
|
||||
r.a.Inc(v)
|
||||
}
|
||||
|
||||
// IncB increment counter B
|
||||
func (r *RatioCounter) IncB(v int) {
|
||||
r.b.Inc(v)
|
||||
}
|
||||
|
||||
// TestMeter a test meter
|
||||
type TestMeter struct {
|
||||
Rate float64
|
||||
NotReady bool
|
||||
WindowSize time.Duration
|
||||
}
|
||||
|
||||
// GetWindowSize gets windows size
|
||||
func (tm *TestMeter) GetWindowSize() time.Duration {
|
||||
return tm.WindowSize
|
||||
}
|
||||
|
||||
// IsReady returns true if the meter is ready
|
||||
func (tm *TestMeter) IsReady() bool {
|
||||
return !tm.NotReady
|
||||
}
|
||||
|
||||
// GetRate gets rate
|
||||
func (tm *TestMeter) GetRate() float64 {
|
||||
return tm.Rate
|
||||
}
|
||||
|
|
32
vendor/github.com/vulcand/oxy/memmetrics/roundtrip.go
generated
vendored
32
vendor/github.com/vulcand/oxy/memmetrics/roundtrip.go
generated
vendored
|
@ -29,10 +29,16 @@ type RTMetrics struct {
|
|||
|
||||
type rrOptSetter func(r *RTMetrics) error
|
||||
|
||||
// NewRTMetricsFn builder function type
|
||||
type NewRTMetricsFn func() (*RTMetrics, error)
|
||||
|
||||
// NewCounterFn builder function type
|
||||
type NewCounterFn func() (*RollingCounter, error)
|
||||
|
||||
// NewRollingHistogramFn builder function type
|
||||
type NewRollingHistogramFn func() (*RollingHDRHistogram, error)
|
||||
|
||||
// RTCounter set a builder function for Counter
|
||||
func RTCounter(new NewCounterFn) rrOptSetter {
|
||||
return func(r *RTMetrics) error {
|
||||
r.newCounter = new
|
||||
|
@ -40,13 +46,15 @@ func RTCounter(new NewCounterFn) rrOptSetter {
|
|||
}
|
||||
}
|
||||
|
||||
func RTHistogram(new NewRollingHistogramFn) rrOptSetter {
|
||||
// RTHistogram set a builder function for RollingHistogram
|
||||
func RTHistogram(fn NewRollingHistogramFn) rrOptSetter {
|
||||
return func(r *RTMetrics) error {
|
||||
r.newHist = new
|
||||
r.newHist = fn
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// RTClock sets a clock
|
||||
func RTClock(clock timetools.TimeProvider) rrOptSetter {
|
||||
return func(r *RTMetrics) error {
|
||||
r.clock = clock
|
||||
|
@ -103,7 +111,7 @@ func NewRTMetrics(settings ...rrOptSetter) (*RTMetrics, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
// Returns a new RTMetrics which is a copy of the current one
|
||||
// Export Returns a new RTMetrics which is a copy of the current one
|
||||
func (m *RTMetrics) Export() *RTMetrics {
|
||||
m.statusCodesLock.RLock()
|
||||
defer m.statusCodesLock.RUnlock()
|
||||
|
@ -130,11 +138,12 @@ func (m *RTMetrics) Export() *RTMetrics {
|
|||
return export
|
||||
}
|
||||
|
||||
// CounterWindowSize gets total windows size
|
||||
func (m *RTMetrics) CounterWindowSize() time.Duration {
|
||||
return m.total.WindowSize()
|
||||
}
|
||||
|
||||
// GetNetworkErrorRatio calculates the amont of network errors such as time outs and dropped connection
|
||||
// NetworkErrorRatio calculates the amont of network errors such as time outs and dropped connection
|
||||
// that occurred in the given time window compared to the total requests count.
|
||||
func (m *RTMetrics) NetworkErrorRatio() float64 {
|
||||
if m.total.Count() == 0 {
|
||||
|
@ -143,7 +152,7 @@ func (m *RTMetrics) NetworkErrorRatio() float64 {
|
|||
return float64(m.netErrors.Count()) / float64(m.total.Count())
|
||||
}
|
||||
|
||||
// GetResponseCodeRatio calculates ratio of count(startA to endA) / count(startB to endB)
|
||||
// ResponseCodeRatio calculates ratio of count(startA to endA) / count(startB to endB)
|
||||
func (m *RTMetrics) ResponseCodeRatio(startA, endA, startB, endB int) float64 {
|
||||
a := int64(0)
|
||||
b := int64(0)
|
||||
|
@ -163,6 +172,7 @@ func (m *RTMetrics) ResponseCodeRatio(startA, endA, startB, endB int) float64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Append append a metric
|
||||
func (m *RTMetrics) Append(other *RTMetrics) error {
|
||||
if m == other {
|
||||
return errors.New("RTMetrics cannot append to self")
|
||||
|
@ -196,6 +206,7 @@ func (m *RTMetrics) Append(other *RTMetrics) error {
|
|||
return m.histogram.Append(copied.histogram)
|
||||
}
|
||||
|
||||
// Record records a metric
|
||||
func (m *RTMetrics) Record(code int, duration time.Duration) {
|
||||
m.total.Inc(1)
|
||||
if code == http.StatusGatewayTimeout || code == http.StatusBadGateway {
|
||||
|
@ -205,17 +216,17 @@ func (m *RTMetrics) Record(code int, duration time.Duration) {
|
|||
m.recordLatency(duration)
|
||||
}
|
||||
|
||||
// GetTotalCount returns total count of processed requests collected.
|
||||
// TotalCount returns total count of processed requests collected.
|
||||
func (m *RTMetrics) TotalCount() int64 {
|
||||
return m.total.Count()
|
||||
}
|
||||
|
||||
// GetNetworkErrorCount returns total count of processed requests observed
|
||||
// NetworkErrorCount returns total count of processed requests observed
|
||||
func (m *RTMetrics) NetworkErrorCount() int64 {
|
||||
return m.netErrors.Count()
|
||||
}
|
||||
|
||||
// GetStatusCodesCounts returns map with counts of the response codes
|
||||
// StatusCodesCounts returns map with counts of the response codes
|
||||
func (m *RTMetrics) StatusCodesCounts() map[int]int64 {
|
||||
sc := make(map[int]int64)
|
||||
m.statusCodesLock.RLock()
|
||||
|
@ -228,13 +239,14 @@ func (m *RTMetrics) StatusCodesCounts() map[int]int64 {
|
|||
return sc
|
||||
}
|
||||
|
||||
// GetLatencyHistogram computes and returns resulting histogram with latencies observed.
|
||||
// LatencyHistogram computes and returns resulting histogram with latencies observed.
|
||||
func (m *RTMetrics) LatencyHistogram() (*HDRHistogram, error) {
|
||||
m.histogramLock.Lock()
|
||||
defer m.histogramLock.Unlock()
|
||||
return m.histogram.Merged()
|
||||
}
|
||||
|
||||
// Reset reset metrics
|
||||
func (m *RTMetrics) Reset() {
|
||||
m.statusCodesLock.Lock()
|
||||
defer m.statusCodesLock.Unlock()
|
||||
|
@ -284,7 +296,7 @@ const (
|
|||
counterResolution = time.Second
|
||||
histMin = 1
|
||||
histMax = 3600000000 // 1 hour in microseconds
|
||||
histSignificantFigures = 2 // signigicant figures (1% precision)
|
||||
histSignificantFigures = 2 // significant figures (1% precision)
|
||||
histBuckets = 6 // number of sub-histograms in a rolling histogram
|
||||
histPeriod = 10 * time.Second // roll time
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue