-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathbirdwatcher.go
120 lines (94 loc) · 2.63 KB
/
birdwatcher.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
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"log/syslog"
"net/http"
"os"
"regexp"
"github.com/julienschmidt/httprouter"
yaml "gopkg.in/yaml.v2"
)
var debug int = 0
var slog *syslog.Writer // Our syslog connection
var conf *Config
type Match struct {
Expr string // The regular expression as a string.
Fields []string // The named fields for grouped expressions.
Next string // The next regular expression in the flow.
Action string // What to do with the stored fields: "store" or "send".
}
// Compiled regular expression and it's corresponding match data.
type RE struct {
RE *regexp.Regexp
Match Match
}
// The configuration found in the configuration file.
type FileConfig struct {
Matches map[string]Match // All our regular expressions and related data.
Listen string // Listen to this address:port for HTTP.
FileName string // File to look for patterns
}
type Config struct {
Conf FileConfig
Res map[string]RE
}
// Parse the configuration file. Returns the configuration.
func parseconfig(filename string) (conf *Config, err error) {
conf = new(Config)
contents, err := ioutil.ReadFile(filename)
if err != nil {
return
}
if err = yaml.Unmarshal(contents, &conf.Conf); err != nil {
return
}
conf.Res = make(map[string]RE)
// Build the regexps from the configuration.
for key, match := range conf.Conf.Matches {
var err error
var re RE
re.Match = match
re.RE, err = regexp.Compile(match.Expr)
if err != nil {
slog.Err("Couldn't compile re: " + match.Expr)
os.Exit(-1)
}
// Check that the number of capturing groups matches the number of expected fields.
lengroups := len(re.RE.SubexpNames()) - 1
lenfields := len(re.Match.Fields)
if lengroups != lenfields {
line := fmt.Sprintf("Number of capturing groups (%v) not equal to number of fields (%v): %s", lengroups, lenfields, re.Match.Expr)
slog.Err(line)
os.Exit(-1)
}
conf.Res[key] = re
}
return
}
func main() {
var configfile = flag.String("config", "birdwatcher.yaml", "Path to configuration file")
var flagdebug = flag.Int("debug", 0, "Be more verbose")
flag.Parse()
debug = *flagdebug
slog, err := syslog.New(syslog.LOG_ERR, "birdwatcher")
if err != nil {
fmt.Printf("Couldn't open syslog")
os.Exit(-1)
}
slog.Debug("birdwatcher starting")
config, err := parseconfig(*configfile)
if err != nil {
slog.Err("Couldn't parse configuration file: " + err.Error())
os.Exit(-1)
}
conf = config
fmt.Printf("%v\n", conf)
r := httprouter.New()
r.GET("/status", Status)
r.GET("/routes", Routes)
r.GET("/protocols", Protocols)
log.Fatal(http.ListenAndServe(":8080", r))
}