forked from bosun-monitor/scollector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
143 lines (133 loc) · 3.69 KB
/
main.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"flag"
"net/url"
"runtime"
"strings"
"time"
"github.com/StackExchange/scollector/collect"
"github.com/StackExchange/scollector/collectors"
"github.com/StackExchange/scollector/opentsdb"
"github.com/StackExchange/slog"
)
var (
flagFilter = flag.String("f", "", "Filters collectors matching this term. Works with all other arguments.")
flagTest = flag.Bool("t", false, "Test - run collectors once, print, and exit.")
flagList = flag.Bool("l", false, "List")
flagPrint = flag.Bool("p", false, "Print to screen instead of sending to a host")
host = flag.String("h", "tsaf", `OpenTSDB host. Ex: "tsdb.example.com". Can optionally specify port: "tsdb.example.com:4000", but will default to 4242 otherwise`)
colDir = flag.String("c", "", `Passthrough collector directory. It should contain numbered directories like the OpenTSDB scollector expects. Any executable file in those directories is run every N seconds, where N is the name of the directory. Use 0 for a program that should be run continuously and simply pass data through to OpenTSDB (the program will be restarted if it exits. Data output format is: "metric timestamp value tag1=val1 tag2=val2 ...". Timestamp is in Unix format (seconds since epoch). Tags are optional. A host tag is automatically added, but overridden if specified.`)
batchSize = flag.Int("b", 0, "OpenTSDB batch size. Used for debugging bad data.")
snmp = flag.String("s", "", "SNMP host to poll of the format: \"community@host[,community@host...]\".")
fake = flag.Int("fake", 0, "Generates X fake data points on the test.fake metric per second.")
mains []func()
)
func main() {
flag.Parse()
for _, m := range mains {
m()
}
if *colDir != "" {
collectors.InitPrograms(*colDir)
}
if *snmp != "" {
for _, s := range strings.Split(*snmp, ",") {
sp := strings.Split(s, "@")
if len(sp) != 2 {
slog.Fatal("invalid snmp string:", *snmp)
}
collectors.SNMPIfaces(sp[0], sp[1])
collectors.SNMPCisco(sp[0], sp[1])
}
}
if *fake > 0 {
collectors.InitFake(*fake)
}
c := collectors.Search(*flagFilter)
for _, col := range c {
col.Init()
}
u := parseHost()
if *flagTest {
test(c)
return
} else if *flagList {
list(c)
return
} else if *host != "" {
if u == nil {
slog.Fatal("invalid host:", *host)
}
}
if *flagPrint {
collectors.DefaultFreq = time.Second * 3
slog.Infoln("Set default frequency to", collectors.DefaultFreq)
}
cdp := collectors.Run(c)
if u != nil && !*flagPrint {
slog.Infoln("OpenTSDB host:", u)
if err := collect.InitChan(u.Host, "scollector", cdp); err != nil {
slog.Fatal(err)
}
if *batchSize > 0 {
collect.BatchSize = *batchSize
}
go func() {
const maxMem = 500 * 1024 * 1024 // 500MB
var m runtime.MemStats
for _ = range time.Tick(time.Minute) {
runtime.ReadMemStats(&m)
if m.Alloc > maxMem {
panic("memory max reached")
}
}
}()
} else {
slog.Infoln("Outputting to screen")
printPut(cdp)
}
select {}
}
func test(cs []collectors.Collector) {
dpchan := make(chan *opentsdb.DataPoint)
for _, c := range cs {
go c.Run(dpchan)
slog.Infoln("run", c.Name())
}
dur := time.Second * 10
slog.Infoln("running for", dur)
next := time.After(dur)
Loop:
for {
select {
case dp := <-dpchan:
slog.Info(dp.Telnet())
case <-next:
break Loop
}
}
}
func list(cs []collectors.Collector) {
for _, c := range cs {
slog.Infoln(c.Name())
}
}
func parseHost() *url.URL {
if *host == "" {
return nil
}
u := url.URL{
Scheme: "http",
Path: "/api/put",
}
if !strings.Contains(*host, ":") {
*host += ":4242"
}
u.Host = *host
return &u
}
func printPut(c chan *opentsdb.DataPoint) {
for dp := range c {
slog.Info(dp.Telnet())
}
}