diff --git a/service.go b/service.go index 297d9fd..9fa9bc0 100644 --- a/service.go +++ b/service.go @@ -6,8 +6,10 @@ import ( "strconv" "strings" "sync" + "time" "github.com/antonholmquist/jason" + "github.com/pyk/byten" ) // Service represents constantly updating info about single service. @@ -107,6 +109,8 @@ func (s Service) StatusLine() string { } // Value returns current value for the given var of this service. +// +// It also formats value, if kind is specified. func (s Service) Value(name VarName) string { if s.Err != nil { return "N/A" @@ -115,11 +119,20 @@ func (s Service) Value(name VarName) string { if !ok { return "N/A" } - if val.Front() == nil { + + v := val.Front() + if v == nil { return "N/A" } - return fmt.Sprintf("%v", val.Front()) + switch name.Kind() { + case KindMemory: + return fmt.Sprintf("%s", byten.Size(v.(int64))) + case KindDuration: + return fmt.Sprintf("%v", time.Duration(v.(int64))) + default: + return fmt.Sprintf("%v", v) + } } // Values returns slice of ints with recent diff --git a/var.go b/var.go index 3a03ac1..71593e3 100644 --- a/var.go +++ b/var.go @@ -6,16 +6,29 @@ import "strings" // // It has dot-separated format, like "memstats.Alloc", // but can be used in different forms, hence it's own type. +// +// It also can have optional "kind:" modifier, like "mem:" or "duration:" type VarName string +type varKind int + +const ( + KindDefault varKind = iota + KindMemory + KindDuration +) + // ToSlice converts "dot-separated" notation into the "slice of strings". // // "dot-separated" notation is a human-readable format, passed via args. // "slice of strings" is used by Jason library. // // Example: "memstats.Alloc" => []string{"memstats", "Alloc"} +// Example: "mem:memstats.Alloc" => []string{"memstats", "Alloc"} func (v VarName) ToSlice() []string { - return strings.FieldsFunc(string(v), func(r rune) bool { return r == '.' }) + start := strings.IndexRune(string(v), ':') + 1 + slice := strings.FieldsFunc(string(v)[start:], func(r rune) bool { return r == '.' }) + return slice } // Short returns short name, which is typically is the last word in the long names. @@ -27,3 +40,18 @@ func (v VarName) Short() string { slice := v.ToSlice() return slice[len(slice)-1] } + +func (v VarName) Kind() varKind { + start := strings.IndexRune(string(v), ':') + if start == -1 { + return KindDefault + } + + switch string(v)[:start] { + case "mem": + return KindMemory + case "duration": + return KindDuration + } + return KindDefault +} diff --git a/var_test.go b/var_test.go index 343e10e..ddc084d 100644 --- a/var_test.go +++ b/var_test.go @@ -16,4 +16,32 @@ func TestVarName(t *testing.T) { if short != "Alloc" { t.Fatalf("Expecting Short() to be 'Alloc', but got: %s", short) } + + kind := v.Kind() + if kind != KindDefault { + t.Fatalf("Expecting kind to be %v, but got: %v", KindDefault, kind) + } + + v = VarName("mem:memstats.Alloc") + + slice = v.ToSlice() + if len(slice) != 2 || slice[0] != "memstats" || slice[1] != "Alloc" { + t.Fatalf("ToSlice failed: %v", slice) + } + + short = v.Short() + if short != "Alloc" { + t.Fatalf("Expecting Short() to be 'Alloc', but got: %s", short) + } + + kind = v.Kind() + if kind != KindMemory { + t.Fatalf("Expecting kind to be %v, but got: %v", KindMemory, kind) + } + + v = VarName("duration:ResponseTimes.API.Users") + kind = v.Kind() + if kind != KindDuration { + t.Fatalf("Expecting kind to be %v, but got: %v", KindDuration, kind) + } }