Extract flatjson package

This commit is contained in:
Justin Li 2014-07-24 20:41:12 -04:00
parent d3bb52f204
commit b4757e5aa8
2 changed files with 4 additions and 104 deletions

View file

@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/chihaya/chihaya/config" "github.com/chihaya/chihaya/config"
"github.com/pushrax/flatjson"
) )
const ( const (
@ -93,7 +94,7 @@ type Stats struct {
responseTimeEvents chan time.Duration responseTimeEvents chan time.Duration
recordMemStats <-chan time.Time recordMemStats <-chan time.Time
flattened FlatMap flattened flatjson.FlatMap
} }
func New(cfg config.StatsConfig) *Stats { func New(cfg config.StatsConfig) *Stats {
@ -117,12 +118,12 @@ func New(cfg config.StatsConfig) *Stats {
s.recordMemStats = time.NewTicker(cfg.MemUpdateInterval.Duration).C s.recordMemStats = time.NewTicker(cfg.MemUpdateInterval.Duration).C
} }
s.flattened = Flatten(s) s.flattened = flatjson.Flatten(s)
go s.handleEvents() go s.handleEvents()
return s return s
} }
func (s *Stats) Flattened() FlatMap { func (s *Stats) Flattened() flatjson.FlatMap {
return s.flattened return s.flattened
} }

View file

@ -1,101 +0,0 @@
package stats
import (
"reflect"
"strings"
)
type FlatMap map[string]interface{}
func isEmptyValue(v reflect.Value) bool {
return v.Interface() == reflect.Zero(v.Type()).Interface()
}
func keyForField(field reflect.StructField, v reflect.Value) (string, bool) {
if tag := field.Tag.Get("json"); tag != "" {
tokens := strings.SplitN(tag, ",", 2)
name := tokens[0]
opts := ""
if len(tokens) > 1 {
opts = tokens[1]
}
if name == "-" || strings.Contains(opts, "omitempty") && isEmptyValue(v) {
return "", false
} else if name != "" {
return name, false
}
}
if field.Anonymous {
return "", true
}
return field.Name, false
}
func extractValue(val, fallback reflect.Value) reflect.Value {
switch val.Kind() {
case reflect.Struct:
return val
case reflect.Ptr:
return extractValue(val.Elem(), fallback)
case reflect.Interface:
return extractValue(val.Elem(), fallback)
default:
return fallback
}
}
func recursiveFlatten(val reflect.Value, prefix string, output FlatMap) int {
valType := val.Type()
added := 0
for i := 0; i < val.NumField(); i++ {
child := val.Field(i)
childType := valType.Field(i)
childPrefix := ""
key, anonymous := keyForField(childType, child)
if childType.PkgPath != "" || (key == "" && !anonymous) {
continue
}
child = extractValue(child, child)
if !anonymous {
childPrefix = prefix + key + "."
}
if child.Kind() == reflect.Struct {
childAdded := recursiveFlatten(child, childPrefix, output)
if childAdded != 0 {
added += childAdded
continue
}
}
output[prefix+key] = child.Addr().Interface()
added++
}
return added
}
func flattenValue(val reflect.Value) FlatMap {
if val.Kind() == reflect.Ptr {
return flattenValue(val.Elem())
}
if val.Kind() != reflect.Struct {
panic("must be called with a struct type")
}
m := FlatMap{}
recursiveFlatten(val, "", m)
return m
}
func Flatten(val interface{}) FlatMap {
return flattenValue(reflect.ValueOf(val))
}