-
Notifications
You must be signed in to change notification settings - Fork 8
/
conf.go
144 lines (123 loc) · 3.23 KB
/
conf.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
144
package main
import (
"fmt"
"log"
"os"
"regexp"
"strings"
"github.com/BurntSushi/toml"
flag "github.com/spf13/pflag"
)
type conf struct {
Address string
Match []matchCriterion
Raw bool
Format string
formatFunc func(map[string]interface{}) string
Pattern string
}
var defaultConf = conf{
"",
nil,
false,
"",
nil,
"{{._appID}}> {{.short_message}}",
}
var operatorRegexp = regexp.MustCompile(`(.+?)\.(not\.)?(` + strings.Join(supportedMatchOperators, "|") + `)`)
// Build details
var buildVersion = "dev"
var buildCommit = "unknown"
var buildDate = "unknown"
func init() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s (Version %s):\n", os.Args[0], buildVersion)
flag.PrintDefaults()
}
}
func getConf() conf {
configFile := flag.String("config", "", "Configuration file")
address := flag.String("address", defaultConf.Address, "URI of the websocket")
match := flag.StringArray("match", nil, "Fields to match")
raw := flag.Bool("raw", defaultConf.Raw, "Display raw message instead of parsing it")
format := flag.String("format", defaultConf.Format, fmt.Sprintf("Display messages using a pre-defined format. Valid values: (%s)", strings.Join(supportedFormat, ", ")))
pattern := flag.String("pattern", defaultConf.Pattern, "Template to apply on each message to display it")
flag.Parse()
c := defaultConf
// Load Override default config with file
if *configFile != "" {
_, err := toml.DecodeFile(*configFile, &c)
if err != nil {
log.Fatal(err)
}
}
// Override configuration with flags
if *address != defaultConf.Address {
c.Address = *address
}
if *raw != defaultConf.Raw {
c.Raw = *raw
}
if *format != defaultConf.Format {
c.Format = *format
}
if *pattern != defaultConf.Pattern {
c.Pattern = *pattern
}
// Match Criteria
for _, m := range *match {
v := strings.SplitN(m, "=", 2)
var key, operator, value string
var not bool
// Check if key match an operator
if subMatch := operatorRegexp.FindStringSubmatch(v[0]); subMatch != nil {
key = subMatch[1]
not = subMatch[2] != ""
operator = subMatch[3]
} else {
// Default operator
key = v[0]
operator = "eq"
}
if operator != "present" && operator != "missing" {
if len(v) != 2 {
log.Fatal(fmt.Errorf("Match should be in the form 'key(.operator)?=value', found %s", v))
} else {
value = v[1]
}
}
c.Match = append(c.Match, matchCriterion{Key: key, Operator: operator, Not: not, Value: value})
}
if ok, err := isValidMatchCriteria(c.Match); !ok {
log.Fatal(err)
}
if flag.NArg() > 0 {
if flag.Arg(0) == "version" {
fmt.Fprintf(os.Stderr, "ldp-tail version %s (%s - %s)\n", buildVersion, buildCommit, buildDate)
os.Exit(0)
} else if flag.Arg(0) == "help" {
flag.Usage()
os.Exit(0)
} else {
fmt.Printf("Invalid command %q\n", flag.Arg(0))
flag.Usage()
os.Exit(-1)
}
}
// Check format helper
if c.Format != "" {
f, ok := supportedFormatMap[c.Format]
if !ok {
fmt.Fprintf(os.Stderr, "Invalid `format`: %q\n", c.Format)
flag.Usage()
os.Exit(-1)
}
c.formatFunc = f
}
if c.Address == "" {
fmt.Fprintf(os.Stderr, "No `address` specified. Please specify it with --address or thru a config file\n")
flag.Usage()
os.Exit(-1)
}
return c
}