136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
// Copyright (c) 2015 Couchbase, 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 metrics
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"math"
|
|
|
|
"github.com/rcrowley/go-metrics"
|
|
)
|
|
|
|
// NOTE: This is copy & pasted from cbft as otherwise there
|
|
// would be an import cycle.
|
|
|
|
var timerPercentiles = []float64{0.5, 0.75, 0.95, 0.99, 0.999}
|
|
|
|
func TimerMap(timer metrics.Timer) map[string]interface{} {
|
|
|
|
rv := make(map[string]interface{})
|
|
t := timer.Snapshot()
|
|
p := t.Percentiles(timerPercentiles)
|
|
|
|
percentileKeys := []string{"median", "75%", "95%", "99%", "99.9%"}
|
|
percentiles := make(map[string]interface{})
|
|
for i, pi := range p {
|
|
if !isNanOrInf(pi) {
|
|
percentileKey := percentileKeys[i]
|
|
percentiles[percentileKey] = pi
|
|
}
|
|
}
|
|
|
|
rateKeys := []string{"1-min", "5-min", "15-min", "mean"}
|
|
rates := make(map[string]interface{})
|
|
for i, ri := range []float64{t.Rate1(), t.Rate5(), t.Rate15(), t.RateMean()} {
|
|
if !isNanOrInf(ri) {
|
|
rateKey := rateKeys[i]
|
|
rates[rateKey] = ri
|
|
}
|
|
}
|
|
|
|
rv["count"] = t.Count()
|
|
rv["min"] = t.Min()
|
|
rv["max"] = t.Max()
|
|
mean := t.Mean()
|
|
if !isNanOrInf(mean) {
|
|
rv["mean"] = mean
|
|
}
|
|
stddev := t.StdDev()
|
|
if !isNanOrInf(stddev) {
|
|
rv["stddev"] = stddev
|
|
}
|
|
rv["percentiles"] = percentiles
|
|
rv["rates"] = rates
|
|
|
|
return rv
|
|
}
|
|
|
|
func isNanOrInf(v float64) bool {
|
|
if math.IsNaN(v) || math.IsInf(v, 0) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func WriteTimerJSON(w io.Writer, timer metrics.Timer) {
|
|
t := timer.Snapshot()
|
|
p := t.Percentiles(timerPercentiles)
|
|
|
|
fmt.Fprintf(w, `{"count":%9d,`, t.Count())
|
|
fmt.Fprintf(w, `"min":%9d,`, t.Min())
|
|
fmt.Fprintf(w, `"max":%9d,`, t.Max())
|
|
fmt.Fprintf(w, `"mean":%12.2f,`, t.Mean())
|
|
fmt.Fprintf(w, `"stddev":%12.2f,`, t.StdDev())
|
|
fmt.Fprintf(w, `"percentiles":{`)
|
|
fmt.Fprintf(w, `"median":%12.2f,`, p[0])
|
|
fmt.Fprintf(w, `"75%%":%12.2f,`, p[1])
|
|
fmt.Fprintf(w, `"95%%":%12.2f,`, p[2])
|
|
fmt.Fprintf(w, `"99%%":%12.2f,`, p[3])
|
|
fmt.Fprintf(w, `"99.9%%":%12.2f},`, p[4])
|
|
fmt.Fprintf(w, `"rates":{`)
|
|
fmt.Fprintf(w, `"1-min":%12.2f,`, t.Rate1())
|
|
fmt.Fprintf(w, `"5-min":%12.2f,`, t.Rate5())
|
|
fmt.Fprintf(w, `"15-min":%12.2f,`, t.Rate15())
|
|
fmt.Fprintf(w, `"mean":%12.2f}}`, t.RateMean())
|
|
}
|
|
|
|
func WriteTimerCSVHeader(w io.Writer, prefix string) {
|
|
fmt.Fprintf(w, "%s-count,", prefix)
|
|
fmt.Fprintf(w, "%s-min,", prefix)
|
|
fmt.Fprintf(w, "%s-max,", prefix)
|
|
fmt.Fprintf(w, "%s-mean,", prefix)
|
|
fmt.Fprintf(w, "%s-stddev,", prefix)
|
|
fmt.Fprintf(w, "%s-percentile-50%%,", prefix)
|
|
fmt.Fprintf(w, "%s-percentile-75%%,", prefix)
|
|
fmt.Fprintf(w, "%s-percentile-95%%,", prefix)
|
|
fmt.Fprintf(w, "%s-percentile-99%%,", prefix)
|
|
fmt.Fprintf(w, "%s-percentile-99.9%%,", prefix)
|
|
fmt.Fprintf(w, "%s-rate-1-min,", prefix)
|
|
fmt.Fprintf(w, "%s-rate-5-min,", prefix)
|
|
fmt.Fprintf(w, "%s-rate-15-min,", prefix)
|
|
fmt.Fprintf(w, "%s-rate-mean", prefix)
|
|
}
|
|
|
|
func WriteTimerCSV(w io.Writer, timer metrics.Timer) {
|
|
t := timer.Snapshot()
|
|
p := t.Percentiles(timerPercentiles)
|
|
|
|
fmt.Fprintf(w, `%d,`, t.Count())
|
|
fmt.Fprintf(w, `%d,`, t.Min())
|
|
fmt.Fprintf(w, `%d,`, t.Max())
|
|
fmt.Fprintf(w, `%f,`, t.Mean())
|
|
fmt.Fprintf(w, `%f,`, t.StdDev())
|
|
fmt.Fprintf(w, `%f,`, p[0])
|
|
fmt.Fprintf(w, `%f,`, p[1])
|
|
fmt.Fprintf(w, `%f,`, p[2])
|
|
fmt.Fprintf(w, `%f,`, p[3])
|
|
fmt.Fprintf(w, `%f,`, p[4])
|
|
fmt.Fprintf(w, `%f,`, t.Rate1())
|
|
fmt.Fprintf(w, `%f,`, t.Rate5())
|
|
fmt.Fprintf(w, `%f,`, t.Rate15())
|
|
fmt.Fprintf(w, `%f`, t.RateMean())
|
|
}
|