18
18
package main
19
19
20
20
import (
21
+ "bytes"
21
22
"fmt"
22
23
"log"
23
24
"os"
@@ -26,6 +27,7 @@ import (
26
27
27
28
"go.opentelemetry.io/collector/component"
28
29
"go.opentelemetry.io/collector/service"
30
+ "go.opentelemetry.io/collector/service/parserprovider"
29
31
"go.uber.org/zap"
30
32
31
33
"github.com/signalfx/splunk-otel-collector/internal/components"
@@ -37,6 +39,7 @@ import (
37
39
const (
38
40
ballastEnvVarName = "SPLUNK_BALLAST_SIZE_MIB"
39
41
configEnvVarName = "SPLUNK_CONFIG"
42
+ configYamlEnvVarName = "SPLUNK_CONFIG_YAML"
40
43
configServerEnabledEnvVar = "SPLUNK_DEBUG_CONFIG_SERVER"
41
44
memLimitMiBEnvVarName = "SPLUNK_MEMORY_LIMIT_MIB"
42
45
memTotalEnvVarName = "SPLUNK_MEMORY_TOTAL_MIB"
@@ -57,8 +60,7 @@ func main() {
57
60
// TODO: Use same format as the collector
58
61
log .SetFlags (log .Ldate | log .Ltime | log .Lshortfile )
59
62
60
- args := os .Args [1 :]
61
- if ! contains (args , "-h" ) && ! contains (args , "--help" ) {
63
+ if ! contains (os .Args [1 :], "-h" ) && ! contains (os .Args [1 :], "--help" ) {
62
64
checkRuntimeParams ()
63
65
}
64
66
@@ -77,6 +79,7 @@ func main() {
77
79
}
78
80
79
81
parserProvider := configprovider .NewConfigSourceParserProvider (
82
+ newBaseParserProvider (),
80
83
zap .NewNop (), // The service logger is not available yet, setting it to NoP.
81
84
info ,
82
85
configsources .Get ()... ,
@@ -109,44 +112,29 @@ func contains(arr []string, str string) bool {
109
112
110
113
// Get the value of a key in an array
111
114
// Support key/value with and with an equal sign
112
- func getKeyValue (args []string , argName string ) string {
113
- val := " "
114
- for i , arg := range args {
115
+ func getKeyValue (args []string , arg string ) ( exists bool , value string ) {
116
+ argEq := arg + "= "
117
+ for i := range args {
115
118
switch {
116
- case strings .HasPrefix (arg , argName + "=" ):
117
- s := strings .Split (arg , "=" )
118
- val = s [1 ]
119
- case arg == argName :
120
- i ++
121
- val = args [i ]
119
+ case strings .HasPrefix (args [i ], argEq ):
120
+ return true , strings .SplitN (args [i ], "=" , 2 )[1 ]
121
+ case args [i ] == arg :
122
+ exists = true
123
+ if i < (len (args ) - 1 ) {
124
+ value = args [i + 1 ]
125
+ }
126
+ return
122
127
}
123
128
}
124
- return val
129
+ return
125
130
}
126
131
127
132
// Check runtime parameters
128
133
// Runtime parameters take priority over environment variables
129
134
// Config and ballast flags are checked
130
135
// Config and all memory env vars are checked
131
136
func checkRuntimeParams () {
132
- args := os .Args [1 :]
133
- config := ""
134
-
135
- // Check if config flag was passed and its value differs from config env var.
136
- // If so, log that it will be used instead of env var value and set env var with that value.
137
- // This allows users to set `--config` and have it take priority when running from most contexts.
138
- cliConfig := getKeyValue (args , "--config" )
139
- if cliConfig != "" {
140
- config = os .Getenv (configEnvVarName )
141
- if config != "" && config != cliConfig {
142
- log .Printf (
143
- "Both %v and '--config' were specified. Overriding %q environment variable value with %q for this session" ,
144
- configEnvVarName , config , cliConfig ,
145
- )
146
- }
147
- os .Setenv (configEnvVarName , cliConfig )
148
- }
149
- setConfig ()
137
+ checkConfig ()
150
138
151
139
// Set default total memory
152
140
memTotalSizeMiB := defaultMemoryTotalMiB
@@ -169,66 +157,103 @@ func checkRuntimeParams() {
169
157
// Check if memory ballast flag was passed
170
158
// If so, ensure memory ballast env var is not set
171
159
// Then set memory ballast and limit properly
172
- ballastSize := getKeyValue (args , "--mem-ballast-size-mib" )
160
+ _ , ballastSize := getKeyValue (os . Args [ 1 :] , "--mem-ballast-size-mib" )
173
161
if ballastSize != "" {
174
- config = os .Getenv (ballastEnvVarName )
175
- if config != "" {
176
- log .Fatalf ("Both %v and '--config' were specified, but only one is allowed" , ballastEnvVarName )
162
+ if os .Getenv (ballastEnvVarName ) != "" {
163
+ log .Fatalf ("Both %v and '--mem-ballast-size-mib' were specified, but only one is allowed" , ballastEnvVarName )
177
164
}
178
165
os .Setenv (ballastEnvVarName , ballastSize )
179
166
}
180
167
setMemoryBallast (memTotalSizeMiB )
181
168
setMemoryLimit (memTotalSizeMiB )
182
169
}
183
170
184
- // Validate and set the configuration
185
- func setConfig () {
186
- // Check if the config is specified via the env var.
187
- config := os .Getenv (configEnvVarName )
188
- // If not attempt to use a default config; supports Docker and local
189
- if config == "" {
190
- _ , err := os .Stat (defaultDockerSAPMConfig )
191
- if err == nil {
192
- config = defaultDockerSAPMConfig
171
+ // Sets flag '--config' to specified env var SPLUNK_CONFIG, if the flag not specified.
172
+ // Logs a message and returns if env var SPLUNK_CONFIG_YAML specified, and '--config' and SPLUNK_CONFIG no specified.
173
+ // Sets '--config' to default config file path if '--config', SPLUNK_CONFIG and SPLUNK_CONFIG_YAML not specified.
174
+ func checkConfig () {
175
+ configPathFlagExists , configPathFlag := getKeyValue (os .Args [1 :], "--config" )
176
+ configPathVar := os .Getenv (configEnvVarName )
177
+ configYaml := os .Getenv (configYamlEnvVarName )
178
+
179
+ if configPathFlagExists && configPathFlag == "" {
180
+ log .Fatal ("Command line flag --config specified but empty" )
181
+ }
182
+
183
+ if configPathFlag != "" {
184
+ if _ , err := os .Stat (configPathFlag ); err != nil {
185
+ log .Fatalf ("Unable to find the configuration file (%s) ensure flag '--config' is set properly" , configPathFlag )
193
186
}
194
- _ , err = os . Stat ( defaultLocalSAPMConfig )
195
- if err == nil {
196
- config = defaultLocalSAPMConfig
187
+
188
+ if configPathVar != "" && configPathVar != configPathFlag {
189
+ log . Printf ( "Both environment variable %v and flag '-- config' were specified. Using the flag value %s and ignoring the environment variable value %s in this session" , configEnvVarName , configPathFlag , configPathVar )
197
190
}
198
- if config == "" {
199
- log .Fatalf ("Unable to find the default configuration file, ensure %s environment variable is set properly" , configEnvVarName )
191
+
192
+ if configYaml != "" {
193
+ log .Printf ("Both environment variable %s and flag '--config' were specified. Using the flag value %s and ignoring the environment variable in this session" , configYamlEnvVarName , configPathFlag )
200
194
}
201
- } else {
202
- // Check if file exists.
203
- _ , err := os .Stat (config )
204
- if err != nil {
205
- log .Fatalf ("Unable to find the configuration file (%s) ensure %s environment variable is set properly" , config , configEnvVarName )
195
+
196
+ checkRequiredEnvVars (configPathFlag )
197
+
198
+ log .Printf ("Set config to %v" , configPathFlag )
199
+ return
200
+ }
201
+
202
+ if configPathVar != "" {
203
+ if _ , err := os .Stat (configPathVar ); err != nil {
204
+ log .Fatalf ("Unable to find the configuration file (%s) ensure %s environment variable is set properly" , configPathVar , configEnvVarName )
205
+ }
206
+
207
+ os .Args = append (os .Args , "--config=" + configPathVar )
208
+
209
+ if configYaml != "" {
210
+ log .Printf ("Both %s and %s were specified. Using %s environment variable value %s for this session" , configEnvVarName , configYamlEnvVarName , configEnvVarName , configPathVar )
206
211
}
212
+
213
+ checkRequiredEnvVars (configPathVar )
214
+
215
+ log .Printf ("Set config to %v" , configPathVar )
216
+ return
217
+ }
218
+
219
+ if configYaml != "" {
220
+ log .Printf ("Using environment variable %s for configuration" , configYamlEnvVarName )
221
+ return
222
+ }
223
+
224
+ defaultConfigPath := getExistingDefaultConfigPath ()
225
+ checkRequiredEnvVars (defaultConfigPath )
226
+ os .Args = append (os .Args , "--config=" + defaultConfigPath )
227
+ log .Printf ("Set config to %v" , defaultConfigPath )
228
+ }
229
+
230
+ func getExistingDefaultConfigPath () (path string ) {
231
+ if _ , err := os .Stat (defaultLocalSAPMConfig ); err == nil {
232
+ return defaultLocalSAPMConfig
233
+ }
234
+ if _ , err := os .Stat (defaultDockerSAPMConfig ); err == nil {
235
+ return defaultDockerSAPMConfig
207
236
}
237
+ log .Fatalf ("Unable to find the default configuration file (%s) or (%s)" , defaultLocalSAPMConfig , defaultDockerSAPMConfig )
238
+ return
239
+ }
208
240
209
- switch config {
241
+ func checkRequiredEnvVars (path string ) {
242
+ // Check environment variables required by default configuration.
243
+ switch path {
210
244
case
211
245
defaultDockerSAPMConfig ,
212
246
defaultDockerOTLPConfig ,
213
247
defaultLocalSAPMConfig ,
214
248
defaultLocalOTLPConfig :
215
- // The following environment variables are required.
216
- // If any are missing stop here.
217
249
requiredEnvVars := []string {realmEnvVarName , tokenEnvVarName }
218
250
for _ , v := range requiredEnvVars {
219
251
if len (os .Getenv (v )) == 0 {
220
252
log .Printf ("Usage: %s=12345 %s=us0 %s" , tokenEnvVarName , realmEnvVarName , os .Args [0 ])
221
- log .Fatalf ("ERROR: Missing required environment variable %s with default config path %s" , v , config )
253
+ log .Fatalf ("ERROR: Missing required environment variable %s with default config path %s" , v , path )
222
254
}
223
255
}
224
256
}
225
-
226
- args := os .Args [1 :]
227
- if ! contains (args , "--config" ) {
228
- // Inject the command line flag that controls the configuration.
229
- os .Args = append (os .Args , "--config=" + config )
230
- }
231
- log .Printf ("Set config to %v" , config )
232
257
}
233
258
234
259
// Validate and set the memory ballast
@@ -277,7 +302,7 @@ func setMemoryLimit(memTotalSizeMiB int) {
277
302
278
303
// Validate memoryLimit is sane
279
304
args := os .Args [1 :]
280
- b := getKeyValue (args , "--mem-ballast-size-mib" )
305
+ _ , b := getKeyValue (args , "--mem-ballast-size-mib" )
281
306
ballastSize , _ := strconv .Atoi (b )
282
307
if (ballastSize * 2 ) > memLimit {
283
308
log .Fatalf ("Memory limit (%v) is less than 2x ballast (%v). Increase memory limit or decrease ballast size." , memLimit , ballastSize )
@@ -287,6 +312,19 @@ func setMemoryLimit(memTotalSizeMiB int) {
287
312
log .Printf ("Set memory limit to %d MiB" , memLimit )
288
313
}
289
314
315
+ // Returns a ParserProvider that reads configuration YAML from an environment variable when applicable.
316
+ func newBaseParserProvider () parserprovider.ParserProvider {
317
+ _ , configPathFlag := getKeyValue (os .Args [1 :], "--config" )
318
+ configPathVar := os .Getenv (configEnvVarName )
319
+ configYaml := os .Getenv (configYamlEnvVarName )
320
+
321
+ if configPathFlag == "" && configPathVar == "" && configYaml != "" {
322
+ return parserprovider .NewInMemory (bytes .NewBufferString (configYaml ))
323
+ }
324
+
325
+ return parserprovider .Default ()
326
+ }
327
+
290
328
func runInteractive (params service.CollectorSettings ) error {
291
329
app , err := service .New (params )
292
330
if err != nil {
0 commit comments