Resync oxy with original repository
This commit is contained in:
parent
da5e4a13bf
commit
bee8ebb00b
31 changed files with 650 additions and 808 deletions
2
vendor/github.com/vulcand/oxy/memmetrics/anomaly.go
generated
vendored
2
vendor/github.com/vulcand/oxy/memmetrics/anomaly.go
generated
vendored
|
@ -40,7 +40,7 @@ func SplitRatios(values []float64) (good map[float64]bool, bad map[float64]bool)
|
|||
}
|
||||
|
||||
// SplitFloat64 provides simple anomaly detection for skewed data sets with no particular distribution.
|
||||
// In essense it applies the formula if(v > median(values) + threshold * medianAbsoluteDeviation) -> anomaly
|
||||
// In essence it applies the formula if(v > median(values) + threshold * medianAbsoluteDeviation) -> anomaly
|
||||
// There's a corner case where there are just 2 values, so by definition there's no value that exceeds the threshold.
|
||||
// This case is solved by introducing additional value that we know is good, e.g. 0. That helps to improve the detection results
|
||||
// on such data sets.
|
||||
|
|
4
vendor/github.com/vulcand/oxy/memmetrics/counter.go
generated
vendored
4
vendor/github.com/vulcand/oxy/memmetrics/counter.go
generated
vendored
|
@ -71,9 +71,7 @@ func (c *RollingCounter) Clone() *RollingCounter {
|
|||
lastBucket: c.lastBucket,
|
||||
lastUpdated: c.lastUpdated,
|
||||
}
|
||||
for i, v := range c.values {
|
||||
other.values[i] = v
|
||||
}
|
||||
copy(other.values, c.values)
|
||||
return other
|
||||
}
|
||||
|
||||
|
|
33
vendor/github.com/vulcand/oxy/memmetrics/histogram.go
generated
vendored
33
vendor/github.com/vulcand/oxy/memmetrics/histogram.go
generated
vendored
|
@ -34,6 +34,15 @@ 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()
|
||||
hist = hdrhistogram.Import(snapshot)
|
||||
}
|
||||
return &HDRHistogram{low: r.low, high: r.high, sigfigs: r.sigfigs, h: hist}
|
||||
}
|
||||
|
||||
// Returns latency at quantile with microsecond precision
|
||||
func (h *HDRHistogram) LatencyAtQuantile(q float64) time.Duration {
|
||||
return time.Duration(h.ValueAtQuantile(q)) * time.Microsecond
|
||||
|
@ -118,6 +127,26 @@ func NewRollingHDRHistogram(low, high int64, sigfigs int, period time.Duration,
|
|||
return rh, nil
|
||||
}
|
||||
|
||||
func (r *RollingHDRHistogram) Export() *RollingHDRHistogram {
|
||||
export := &RollingHDRHistogram{}
|
||||
export.idx = r.idx
|
||||
export.lastRoll = r.lastRoll
|
||||
export.period = r.period
|
||||
export.bucketCount = r.bucketCount
|
||||
export.low = r.low
|
||||
export.high = r.high
|
||||
export.sigfigs = r.sigfigs
|
||||
export.clock = r.clock
|
||||
|
||||
exportBuckets := make([]*HDRHistogram, len(r.buckets))
|
||||
for i, hist := range r.buckets {
|
||||
exportBuckets[i] = hist.Export()
|
||||
}
|
||||
export.buckets = exportBuckets
|
||||
|
||||
return export
|
||||
}
|
||||
|
||||
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")
|
||||
|
@ -150,8 +179,8 @@ func (r *RollingHDRHistogram) Merged() (*HDRHistogram, error) {
|
|||
return m, err
|
||||
}
|
||||
for _, h := range r.buckets {
|
||||
if m.Merge(h); err != nil {
|
||||
return nil, err
|
||||
if errMerge := m.Merge(h); errMerge != nil {
|
||||
return nil, errMerge
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
|
|
61
vendor/github.com/vulcand/oxy/memmetrics/roundtrip.go
generated
vendored
61
vendor/github.com/vulcand/oxy/memmetrics/roundtrip.go
generated
vendored
|
@ -20,6 +20,7 @@ type RTMetrics struct {
|
|||
statusCodes map[int]*RollingCounter
|
||||
statusCodesLock sync.RWMutex
|
||||
histogram *RollingHDRHistogram
|
||||
histogramLock sync.RWMutex
|
||||
|
||||
newCounter NewCounterFn
|
||||
newHist NewRollingHistogramFn
|
||||
|
@ -102,12 +103,39 @@ func NewRTMetrics(settings ...rrOptSetter) (*RTMetrics, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
// Returns a new RTMetrics which is a copy of the current one
|
||||
func (m *RTMetrics) Export() *RTMetrics {
|
||||
m.statusCodesLock.RLock()
|
||||
defer m.statusCodesLock.RUnlock()
|
||||
m.histogramLock.RLock()
|
||||
defer m.histogramLock.RUnlock()
|
||||
|
||||
export := &RTMetrics{}
|
||||
export.statusCodesLock = sync.RWMutex{}
|
||||
export.histogramLock = sync.RWMutex{}
|
||||
export.total = m.total.Clone()
|
||||
export.netErrors = m.netErrors.Clone()
|
||||
exportStatusCodes := map[int]*RollingCounter{}
|
||||
for code, rollingCounter := range m.statusCodes {
|
||||
exportStatusCodes[code] = rollingCounter.Clone()
|
||||
}
|
||||
export.statusCodes = exportStatusCodes
|
||||
if m.histogram != nil {
|
||||
export.histogram = m.histogram.Export()
|
||||
}
|
||||
export.newCounter = m.newCounter
|
||||
export.newHist = m.newHist
|
||||
export.clock = m.clock
|
||||
|
||||
return export
|
||||
}
|
||||
|
||||
func (m *RTMetrics) CounterWindowSize() time.Duration {
|
||||
return m.total.WindowSize()
|
||||
}
|
||||
|
||||
// GetNetworkErrorRatio calculates the amont of network errors such as time outs and dropped connection
|
||||
// that occured in the given time window compared to the total requests count.
|
||||
// that occurred in the given time window compared to the total requests count.
|
||||
func (m *RTMetrics) NetworkErrorRatio() float64 {
|
||||
if m.total.Count() == 0 {
|
||||
return 0
|
||||
|
@ -148,11 +176,13 @@ func (m *RTMetrics) Append(other *RTMetrics) error {
|
|||
return err
|
||||
}
|
||||
|
||||
copied := other.Export()
|
||||
|
||||
m.statusCodesLock.Lock()
|
||||
defer m.statusCodesLock.Unlock()
|
||||
other.statusCodesLock.RLock()
|
||||
defer other.statusCodesLock.RUnlock()
|
||||
for code, c := range other.statusCodes {
|
||||
m.histogramLock.Lock()
|
||||
defer m.histogramLock.Unlock()
|
||||
for code, c := range copied.statusCodes {
|
||||
o, ok := m.statusCodes[code]
|
||||
if ok {
|
||||
if err := o.Append(c); err != nil {
|
||||
|
@ -163,7 +193,7 @@ func (m *RTMetrics) Append(other *RTMetrics) error {
|
|||
}
|
||||
}
|
||||
|
||||
return m.histogram.Append(other.histogram)
|
||||
return m.histogram.Append(copied.histogram)
|
||||
}
|
||||
|
||||
func (m *RTMetrics) Record(code int, duration time.Duration) {
|
||||
|
@ -200,35 +230,36 @@ func (m *RTMetrics) StatusCodesCounts() map[int]int64 {
|
|||
|
||||
// GetLatencyHistogram 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()
|
||||
}
|
||||
|
||||
func (m *RTMetrics) Reset() {
|
||||
m.statusCodesLock.Lock()
|
||||
defer m.statusCodesLock.Unlock()
|
||||
m.histogramLock.Lock()
|
||||
defer m.histogramLock.Unlock()
|
||||
m.histogram.Reset()
|
||||
m.total.Reset()
|
||||
m.netErrors.Reset()
|
||||
m.statusCodesLock.Lock()
|
||||
defer m.statusCodesLock.Unlock()
|
||||
m.statusCodes = make(map[int]*RollingCounter)
|
||||
}
|
||||
|
||||
func (m *RTMetrics) recordNetError() error {
|
||||
m.netErrors.Inc(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RTMetrics) recordLatency(d time.Duration) error {
|
||||
m.histogramLock.Lock()
|
||||
defer m.histogramLock.Unlock()
|
||||
return m.histogram.RecordLatencies(d, 1)
|
||||
}
|
||||
|
||||
func (m *RTMetrics) recordStatusCode(statusCode int) error {
|
||||
m.statusCodesLock.RLock()
|
||||
m.statusCodesLock.Lock()
|
||||
if c, ok := m.statusCodes[statusCode]; ok {
|
||||
c.Inc(1)
|
||||
m.statusCodesLock.RUnlock()
|
||||
m.statusCodesLock.Unlock()
|
||||
return nil
|
||||
}
|
||||
m.statusCodesLock.RUnlock()
|
||||
m.statusCodesLock.Unlock()
|
||||
|
||||
m.statusCodesLock.Lock()
|
||||
defer m.statusCodesLock.Unlock()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue