mirror of https://github.com/divan/expvarmon.git
allow escaping the dot character in paths using a backslash
Occasionally expvar output contains keys that are hostnames, IP addresses, or filenames that contain the "." character. For example: { "bleve": { "bootDuration": 16559, "indexes": { "bench.bleve": { "index": { "analysis_time": 10889841135, "batches": 145, "deletes": 0, "errors": 0, "index_time": 21277401883, "lookup_queue_len": 0, "updates": 14500 }, "search_time": 0, "searches": 0 } } } ... } I can now chart the lookup_queue_len value using the var: bleve.indexes.bench\.bleve.index.lookup_queue_len This partially addresses #11 (still does not escape colon character).
This commit is contained in:
parent
383ee494c1
commit
e7f60e5a45
46
var.go
46
var.go
|
@ -38,7 +38,7 @@ const (
|
|||
// Example: "mem:memstats.Alloc" => []string{"memstats", "Alloc"}
|
||||
func (v VarName) ToSlice() []string {
|
||||
start := strings.IndexRune(string(v), ':') + 1
|
||||
slice := strings.FieldsFunc(string(v)[start:], func(r rune) bool { return r == '.' })
|
||||
slice := DottedFieldsToSliceEscaped(string(v)[start:])
|
||||
return slice
|
||||
}
|
||||
|
||||
|
@ -128,3 +128,47 @@ func roundDuration(d time.Duration) time.Duration {
|
|||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func DottedFieldsToSliceEscaped(s string) []string {
|
||||
rv := make([]string, 0)
|
||||
lastSlash := false
|
||||
curr := ""
|
||||
for _, r := range s {
|
||||
// base case, dot not after slash
|
||||
if !lastSlash && r == '.' {
|
||||
if len(curr) > 0 {
|
||||
rv = append(rv, curr)
|
||||
curr = ""
|
||||
}
|
||||
continue
|
||||
} else if !lastSlash {
|
||||
// any character not after slash
|
||||
curr += string(r)
|
||||
if r == '\\' {
|
||||
lastSlash = true
|
||||
} else {
|
||||
lastSlash = false
|
||||
}
|
||||
continue
|
||||
} else if r == '\\' {
|
||||
// last was slash, and so is this
|
||||
lastSlash = false // 2 slashes = 0
|
||||
// we already appended a single slash on first
|
||||
continue
|
||||
} else if r == '.' {
|
||||
// we see \. but already appended \ last time
|
||||
// replace it with .
|
||||
curr = curr[:len(curr)-1] + "."
|
||||
lastSlash = false
|
||||
} else {
|
||||
// \ and any other character, ignore
|
||||
curr += string(r)
|
||||
lastSlash = false
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(curr) > 0 {
|
||||
rv = append(rv, curr)
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
|
45
var_test.go
45
var_test.go
|
@ -44,4 +44,49 @@ func TestVarName(t *testing.T) {
|
|||
if kind != KindDuration {
|
||||
t.Fatalf("Expecting kind to be %v, but got: %v", KindDuration, kind)
|
||||
}
|
||||
|
||||
// single \. escapes the dot
|
||||
v = VarName(`bleve.indexes.bench\.bleve.index.lookup_queue_len`)
|
||||
|
||||
slice = v.ToSlice()
|
||||
if len(slice) != 5 || slice[0] != "bleve" || slice[1] != "indexes" || slice[2] != "bench.bleve" ||
|
||||
slice[3] != "index" || slice[4] != "lookup_queue_len" {
|
||||
t.Fatalf("ToSlice failed: %v", slice)
|
||||
}
|
||||
|
||||
// double \\. escapes backslash, not dot
|
||||
v = VarName(`bleve.indexes.bench\\.bleve.index.lookup_queue_len`)
|
||||
|
||||
slice = v.ToSlice()
|
||||
if len(slice) != 6 || slice[0] != "bleve" || slice[1] != "indexes" || slice[2] != "bench\\" ||
|
||||
slice[3] != "bleve" || slice[4] != "index" || slice[5] != "lookup_queue_len" {
|
||||
t.Fatalf("ToSlice failed: %v", slice)
|
||||
}
|
||||
|
||||
// triple \\\. escapes backslash then dot
|
||||
v = VarName(`bleve.indexes.bench\\\.bleve.index.lookup_queue_len`)
|
||||
|
||||
slice = v.ToSlice()
|
||||
if len(slice) != 5 || slice[0] != "bleve" || slice[1] != "indexes" || slice[2] != "bench\\.bleve" ||
|
||||
slice[3] != "index" || slice[4] != "lookup_queue_len" {
|
||||
t.Fatalf("ToSlice failed: %v", slice)
|
||||
}
|
||||
|
||||
// quadruple \\\\. escapes two backslashes, not dot
|
||||
v = VarName(`bleve.indexes.bench\\\\.bleve.index.lookup_queue_len`)
|
||||
|
||||
slice = v.ToSlice()
|
||||
if len(slice) != 6 || slice[0] != "bleve" || slice[1] != "indexes" || slice[2] != "bench\\\\" ||
|
||||
slice[3] != "bleve" || slice[4] != "index" || slice[5] != "lookup_queue_len" {
|
||||
t.Fatalf("ToSlice failed: %v", slice)
|
||||
}
|
||||
|
||||
// unsupported \x passes through unaltered
|
||||
v = VarName(`bleve.indexes.bench\xbleve.index.lookup_queue_len`)
|
||||
|
||||
slice = v.ToSlice()
|
||||
if len(slice) != 5 || slice[0] != "bleve" || slice[1] != "indexes" || slice[2] != "bench\\xbleve" ||
|
||||
slice[3] != "index" || slice[4] != "lookup_queue_len" {
|
||||
t.Fatalf("ToSlice failed: %v", slice)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue