forked from dinedal/cirgonus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gollector-graphite.go
119 lines (94 loc) · 2.62 KB
/
gollector-graphite.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
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"reflect"
"regexp"
"strings"
"time"
)
const PLAINTEXT_FORMAT = "servers.%s %f %d\n"
func formatKey(orig_key, key string) string {
new_key := strings.Replace(orig_key+"."+key, " ", "_", -1)
new_key = strings.Replace(new_key, "/", "_", -1)
return regexp.MustCompile("[()]").ReplaceAllString(new_key, "")
}
func writeMetric(conn net.Conn, key string, value interface{}) {
str := fmt.Sprintf(PLAINTEXT_FORMAT, key, value, time.Now().Unix())
conn.Write([]byte(str))
}
func iterateNav(conn net.Conn, value_type reflect.Type, key string, value interface{}) {
if value_type.Kind() == reflect.Bool {
// XXX skip bools
} else if value_type.Kind() == reflect.Map && value_type.String() == "map[string]interface {}" {
navigateJSONMap(conn, key, value.(map[string]interface{}))
} else if value_type.String() == "[]interface {}" {
navigateJSONArray(conn, key, value.([]interface{}))
} else {
writeMetric(conn, key, value)
}
}
func navigateJSONArray(conn net.Conn, key string, array []interface{}) {
for i, value := range array {
value_type := reflect.TypeOf(value)
iterateNav(conn, value_type, key+".index_"+fmt.Sprintf("%d", i), value)
}
}
func navigateJSONMap(conn net.Conn, orig_key string, json_rep map[string]interface{}) {
for key, value := range json_rep {
new_key := formatKey(orig_key, key)
value_type := reflect.TypeOf(value)
iterateNav(conn, value_type, new_key, value)
}
}
func main() {
connect := flag.String("connect", "localhost:2003", "Graphite plaintext protocol to emit to")
interval := flag.Int("interval", 60, "Frequency of poll (in seconds")
flag.Parse()
if len(flag.Args()) < 1 {
os.Stderr.WriteString("Must supply at least one gollector endpoint as a url")
os.Exit(1)
}
conn, err := net.Dial("tcp", *connect)
if err != nil {
panic(err)
}
for _, gollector_url := range flag.Args() {
go func() {
for {
this_url, err := url.Parse(gollector_url)
if err != nil {
panic(err)
}
resp, err := http.Get(gollector_url)
if err != nil {
time.Sleep(1 * time.Second)
continue
}
content, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
time.Sleep(1 * time.Second)
continue
}
json_rep := map[string]interface{}{}
err = json.Unmarshal(content, &json_rep)
if err != nil {
time.Sleep(1 * time.Second)
continue
}
navigateJSONMap(conn, strings.Split(this_url.Host, ".")[0], json_rep)
time.Sleep(time.Duration(*interval) * time.Second)
}
}()
}
for {
time.Sleep(1 * time.Hour)
}
}