1
0
mirror of https://github.com/divan/expvarmon.git synced 2025-04-25 13:48:54 +08:00

Added support for arrays (print average)

This commit is contained in:
Ivan Daniluk 2015-08-20 21:38:04 -04:00
parent f30a848d40
commit 3ebcfb6e26
4 changed files with 80 additions and 0 deletions

41
average.go Normal file
View File

@ -0,0 +1,41 @@
package main
import (
"github.com/antonholmquist/jason"
)
func averageJason(array []*jason.Value) float64 {
var arr []float64
for _, v := range array {
val, _ := v.Float64()
arr = append(arr, val)
}
return average(arr)
}
// average calculates average (mean) value for int/float array
// trimming zero values from the right.
//
// The whole array/average thing was added to support memstats.PauseNs
// array, which may be filled with zeroes on very beginning.
// Probably it would be better to use Weighted Moving Average and
// add some advanced arrays avarages support, but it's probably wouldn't
// be used much, but PauseNs will be for sure.
func average(arr []float64) float64 {
// find rightmost non-zero and trim
right := len(arr)
for i := right; i > 0; i-- {
if arr[i-1] != 0.0 {
right = i
break
}
}
trimmed := arr[:right]
// calculate mean
var sum float64
for _, v := range trimmed {
sum += v
}
return sum / float64(len(trimmed))
}

15
average_test.go Normal file
View File

@ -0,0 +1,15 @@
package main
import (
"testing"
)
func TestAverage(t *testing.T) {
avg := average(samplesPartial)
want := 621090.75
if avg != want {
t.Fatalf("Average must be %v, but got %v", want, avg)
}
}
var samplesPartial = []float64{507472, 433979, 610916, 931996, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

View File

@ -37,6 +37,14 @@ func TestExpvars(t *testing.T) {
if alloc == 0 {
t.Fatalf("Alloc should be greater than 0")
}
pauses, err := expvar.GetInt64Array(VarName("memstats.PauseNs").ToSlice()...)
if err != nil {
t.Fatal(err)
}
if len(pauses) == 0 {
t.Fatalf("Pauses length should be greater than 0")
}
}
func TestExpvarsAdvanced(t *testing.T) {

View File

@ -101,6 +101,22 @@ func guessValue(value *jason.Value) interface{} {
return v
} else if v, err := value.String(); err == nil {
return v
} else if v, err := value.Array(); err == nil {
// if we get an array, calculate average
// empty array, treat as zero
if len(v) == 0 {
return 0
}
avg := averageJason(v)
// cast to int64 for Int64 values
if _, err := v[0].Int64(); err == nil {
return int64(avg)
}
return avg
}
return nil