forked from stripe/veneur
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config_parse.go
185 lines (165 loc) · 5.06 KB
/
config_parse.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
package veneur
import (
"io"
"io/ioutil"
"os"
"time"
"github.com/kelseyhightower/envconfig"
"gopkg.in/yaml.v2"
)
var defaultConfig = Config{
Aggregates: []string{"min", "max", "count"},
DatadogFlushMaxPerBody: 25000,
Interval: "10s",
MetricMaxLength: 4096,
ReadBufferSizeBytes: 1048576 * 2, // 2 MiB
}
// ReadProxyConfig unmarshals the proxy config file and slurps in its data.
func ReadProxyConfig(path string) (c ProxyConfig, err error) {
f, err := os.Open(path)
if err != nil {
return c, err
}
defer f.Close()
return readProxyConfig(f)
}
func readProxyConfig(r io.Reader) (ProxyConfig, error) {
var c ProxyConfig
bts, err := ioutil.ReadAll(r)
if err != nil {
return c, err
}
unmarshalErr := unmarshalSemiStrictly(bts, &c)
if unmarshalErr != nil {
if _, ok := err.(*UnknownConfigKeys); !ok {
return c, unmarshalErr
}
}
err = envconfig.Process("veneur", &c)
if err != nil {
return c, err
}
return c, unmarshalErr
}
// UnknownConfigKeys represents a failure to strictly parse a
// configuration YAML file has failed, indicating that the file
// contains unknown keys.
type UnknownConfigKeys struct {
err error
}
func (e *UnknownConfigKeys) Error() string {
return e.err.Error()
}
// ReadConfig unmarshals the config file and slurps in its
// data. ReadConfig can return an error of type *UnknownConfigKeys,
// which means that the file is usable, but contains unknown fields.
func ReadConfig(path string) (c Config, err error) {
f, err := os.Open(path)
if err != nil {
return c, err
}
defer f.Close()
c, err = readConfig(f)
c.applyDefaults()
return
}
func unmarshalSemiStrictly(bts []byte, into interface{}) error {
strictErr := yaml.UnmarshalStrict(bts, into)
if strictErr == nil {
return nil
}
looseErr := yaml.Unmarshal(bts, into)
if looseErr != nil {
return looseErr
}
return &UnknownConfigKeys{strictErr}
}
func readConfig(r io.Reader) (Config, error) {
var c Config
// Unfortunately the YAML package does not
// support reader inputs
// TODO(aditya) convert this when the
// upstream PR lands
bts, err := ioutil.ReadAll(r)
if err != nil {
return c, err
}
unmarshalErr := unmarshalSemiStrictly(bts, &c)
if unmarshalErr != nil {
if _, ok := err.(*UnknownConfigKeys); !ok {
return c, unmarshalErr
}
}
err = envconfig.Process("veneur", &c)
if err != nil {
return c, err
}
// pass back an error about any unknown fields:
return c, unmarshalErr
}
func (c *Config) applyDefaults() {
if len(c.Aggregates) == 0 {
c.Aggregates = defaultConfig.Aggregates
}
if c.Hostname == "" && !c.OmitEmptyHostname {
c.Hostname, _ = os.Hostname()
}
if c.Interval == "" {
c.Interval = defaultConfig.Interval
}
if c.MetricMaxLength == 0 {
c.MetricMaxLength = defaultConfig.MetricMaxLength
}
if c.ReadBufferSizeBytes == 0 {
c.ReadBufferSizeBytes = defaultConfig.ReadBufferSizeBytes
}
if c.SsfBufferSize != 0 {
log.Warn("ssf_buffer_size configuration option has been replaced by datadog_span_buffer_size and will be removed in the next version")
if c.DatadogSpanBufferSize == 0 {
c.DatadogSpanBufferSize = c.SsfBufferSize
}
}
if c.FlushMaxPerBody != 0 {
log.Warn("flush_max_per_body configuration option has been replaced by datadog_flush_max_per_body and will be removed in the next version")
if c.DatadogFlushMaxPerBody == 0 {
c.DatadogFlushMaxPerBody = c.FlushMaxPerBody
}
}
if c.TraceLightstepNumClients != 0 {
log.Warn("trace_lightstep_num_clients configuration option has been replaced by lightstep_num_clients and will be removed in the next version")
if c.LightstepNumClients == 0 {
c.LightstepNumClients = c.TraceLightstepNumClients
}
}
if c.TraceLightstepCollectorHost != "" {
log.Warn("trace_lightstep_collector_host configuration option has been replaced by lightstep_collector_host and will be removed in the next version")
if c.LightstepCollectorHost == "" {
c.LightstepCollectorHost = c.TraceLightstepCollectorHost
}
}
if c.TraceLightstepAccessToken != "" {
log.Warn("trace_lightstep_access_token configuration option has been replaced by lightstep_access_token and will be removed in the next version")
if c.LightstepAccessToken == "" {
c.LightstepAccessToken = c.TraceLightstepAccessToken
}
}
if c.TraceLightstepMaximumSpans != 0 {
log.Warn("trace_lightstep_maximum_spans configuration option has been replaced by lightstep_maximum_spans and will be removed in the next version")
if c.LightstepMaximumSpans == 0 {
c.LightstepMaximumSpans = c.TraceLightstepMaximumSpans
}
}
if c.TraceLightstepReconnectPeriod != "" {
log.Warn("trace_lightstep_reconnect_period configuration option has been replaced by lightstep_reconnect_period and will be removed in the next version")
if c.LightstepReconnectPeriod == "" {
c.LightstepReconnectPeriod = c.TraceLightstepReconnectPeriod
}
}
if c.DatadogFlushMaxPerBody == 0 {
c.DatadogFlushMaxPerBody = defaultConfig.DatadogFlushMaxPerBody
}
}
// ParseInterval handles parsing the flush interval as a time.Duration
func (c Config) ParseInterval() (time.Duration, error) {
return time.ParseDuration(c.Interval)
}