-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhandler.go
121 lines (105 loc) · 2.36 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package evmn
import (
"errors"
"expvar"
"reflect"
"sort"
"strings"
)
var (
// ErrUnknownCmd is given for an unimplemented command
ErrUnknownCmd = errors.New("Unknown command")
// ErrUnknownSvc is the response when fetching a nonexistent service
ErrUnknownSvc = errors.New("Unknown service")
// AllowedTypes is the list of types that are allowed to be exported to munin
AllowedTypes = []string{"*expvar.Int", "*expvar.Map"}
)
func handler(command string) (r string, err error) {
fields := strings.Fields(command)
if len(fields) == 0 {
return "", ErrUnknownCmd
}
switch fields[0] {
case "list":
keys := []string{}
seen := map[string]bool{}
expvar.Do(func(kv expvar.KeyValue) {
// Doing nothing if not an allowed type
allowed := false
for _, typ := range AllowedTypes {
if reflect.TypeOf(kv.Value).String() == typ {
allowed = true
break
}
}
if !allowed {
return
}
g := strings.Split(kv.Key, ":")[0]
f := strings.Split(g, ".")[0]
if seen[f] {
return
}
keys = append(keys, f)
seen[f] = true
})
sort.Strings(keys)
return strings.Join(keys, " "), nil
case "nodes":
return hostname + "\n.", nil
case "fetch":
if len(fields) < 2 {
return "", ErrUnknownSvc
}
key := fields[1]
lines := []string{}
fetch(key, func(k string, v interface{}) {
switch t := v.(type) {
case *expvar.Int:
lines = append(lines, kk(k)+".value "+t.String())
case *expvar.Map:
t.Do(func(kv expvar.KeyValue) {
lines = append(lines, kk(kv.Key)+".value "+kv.Value.String())
})
}
})
return strings.Join(lines, "\n") + "\n.", nil
case "config":
if len(fields) < 2 {
return "", ErrUnknownSvc
}
key := fields[1]
lines := []string{
"graph_title " + key,
"graph_category expvar",
"graph_args --base 1000 --units=si",
}
fetch(key, func(k0 string, v interface{}) {
switch t := v.(type) {
case *expvar.Int:
k := kk(k0)
lines = append(lines,
k+".label "+k0,
k+".min 0",
k+".type DERIVE",
)
case *expvar.Map:
t.Do(func(kv expvar.KeyValue) {
k := kk(kv.Key)
lines = append(lines,
k+".label "+kv.Key,
k+".min 0",
k+".type DERIVE",
)
})
}
})
return strings.Join(lines, "\n") + "\n.", nil
case "cap":
return "multigraph", nil
case "help", "version":
fallthrough
default:
return "", ErrUnknownCmd
}
}