Skip to content

Commit 5b12655

Browse files
authored
Allow configuring airbrake via environment variable (#147)
Allow setting the airbrake api key via the AIRBRAKE_API_KEY environment variable. If this variable is set, it will override the field in the airbrake section of config file.
1 parent c4dbc6a commit 5b12655

File tree

5 files changed

+78
-12
lines changed

5 files changed

+78
-12
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ Data is encapsulated into protobuf messages of different types. Protos can be re
172172
```sh
173173
make generate-protos
174174
```
175+
## Airbrake
176+
Fleet telemetry allows you to monitor errors using [airbrake](https://www.airbrake.io/error-monitoring). The integration test runs fleet telemetry with [errbit](https://github.com/errbit/errbit), which is an airbrake compliant self-hosted error catcher. You can set a project key for airbrake using either the config file or via an environment variable `AIRBRAKE_PROJECT_KEY`.
175177

176178
# Testing
177179

cmd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func startServer(config *config.Config, logger *logrus.Logger) (err error) {
4141
logger.ActivityLog("starting_server", nil)
4242
registry := streaming.NewSocketRegistry()
4343

44-
airbrakeNotifier, err := config.CreateAirbrakeNotifier()
44+
airbrakeNotifier, _, err := config.CreateAirbrakeNotifier(logger)
4545
if err != nil {
4646
return err
4747
}

config/config.go

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ import (
2929
"github.com/teslamotors/fleet-telemetry/telemetry"
3030
)
3131

32+
const (
33+
airbrakeProjectKeyEnv = "AIRBRAKE_PROJECT_KEY"
34+
)
35+
3236
// Config object for server
3337
type Config struct {
3438
// Host is the telemetry server hostname
@@ -149,7 +153,7 @@ type TLS struct {
149153
ServerKey string `json:"server_key"`
150154
}
151155

152-
// ExtractServiceTLSConfig return the TLS config needed for connecting with airbrake server
156+
// AirbrakeTlsConfig return the TLS config needed for connecting with airbrake server
153157
func (c *Config) AirbrakeTlsConfig() (*tls.Config, error) {
154158
if c.Airbrake.TLS == nil {
155159
return nil, nil
@@ -348,13 +352,13 @@ func (c *Config) CreateKinesisStreamMapping(recordNames []string) map[string]str
348352
}
349353

350354
// CreateAirbrakeNotifier intializes an airbrake notifier with standard configs
351-
func (c *Config) CreateAirbrakeNotifier() (*githubairbrake.Notifier, error) {
355+
func (c *Config) CreateAirbrakeNotifier(logger *logrus.Logger) (*githubairbrake.Notifier, *githubairbrake.NotifierOptions, error) {
352356
if c.Airbrake == nil {
353-
return nil, nil
357+
return nil, nil, nil
354358
}
355359
tlsConfig, err := c.AirbrakeTlsConfig()
356360
if err != nil {
357-
return nil, err
361+
return nil, nil, err
358362
}
359363
transport := &http.Transport{
360364
TLSClientConfig: tlsConfig,
@@ -364,8 +368,18 @@ func (c *Config) CreateAirbrakeNotifier() (*githubairbrake.Notifier, error) {
364368
Timeout: 10 * time.Second,
365369
}
366370
errbitHost := c.Airbrake.Host
367-
projectKey := c.Airbrake.ProjectKey
368-
return githubairbrake.NewNotifierWithOptions(&githubairbrake.NotifierOptions{
371+
projectKey, ok := os.LookupEnv(airbrakeProjectKeyEnv)
372+
logInfo := logrus.LogInfo{}
373+
if ok {
374+
logInfo["source"] = "environment_variable"
375+
logInfo["env_key"] = airbrakeProjectKeyEnv
376+
377+
} else {
378+
projectKey = c.Airbrake.ProjectKey
379+
logInfo["source"] = "config_file"
380+
}
381+
logger.ActivityLog("airbrake_configured", logInfo)
382+
options := &githubairbrake.NotifierOptions{
369383
Host: errbitHost,
370384
RemoteConfigHost: errbitHost,
371385
DisableRemoteConfig: true,
@@ -375,5 +389,6 @@ func (c *Config) CreateAirbrakeNotifier() (*githubairbrake.Notifier, error) {
375389
ProjectKey: projectKey,
376390
Environment: c.Airbrake.Environment,
377391
HTTPClient: httpClient,
378-
}), nil
392+
}
393+
return githubairbrake.NewNotifierWithOptions(options), options, nil
379394
}

config/config_test.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,29 @@ var _ = Describe("Test full application config", func() {
145145
})
146146
})
147147

148+
Context("configure airbrake", func() {
149+
It("gets config from file", func() {
150+
config, err := loadTestApplicationConfig(TestAirbrakeConfig)
151+
Expect(err).NotTo(HaveOccurred())
152+
153+
_, options, err := config.CreateAirbrakeNotifier(log)
154+
Expect(err).NotTo(HaveOccurred())
155+
Expect(options.ProjectKey).To(Equal("test1"))
156+
})
157+
158+
It("gets config from env variable", func() {
159+
projectKey := "environmentProjectKey"
160+
err := os.Setenv("AIRBRAKE_PROJECT_KEY", projectKey)
161+
Expect(err).NotTo(HaveOccurred())
162+
config, err := loadTestApplicationConfig(TestAirbrakeConfig)
163+
Expect(err).NotTo(HaveOccurred())
164+
165+
_, options, err := config.CreateAirbrakeNotifier(log)
166+
Expect(err).NotTo(HaveOccurred())
167+
Expect(options.ProjectKey).To(Equal(projectKey))
168+
})
169+
})
170+
148171
Context("configure kinesis", func() {
149172
It("returns an error if kinesis isn't included", func() {
150173
log, _ := logrus.NoOpLogger()
@@ -181,10 +204,6 @@ var _ = Describe("Test full application config", func() {
181204
Expect(err).NotTo(HaveOccurred())
182205
})
183206

184-
AfterEach(func() {
185-
os.Clearenv()
186-
})
187-
188207
It("pubsub does not work when both the environment variables are set", func() {
189208
log, _ := logrus.NoOpLogger()
190209
_ = os.Setenv("PUBSUB_EMULATOR_HOST", "some_url")

config/test_configs_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,33 @@ const TestTransmitDecodedRecords = `
107107
}
108108
}
109109
`
110+
111+
const TestAirbrakeConfig = `
112+
{
113+
"host": "127.0.0.1",
114+
"port": 443,
115+
"status_port": 8080,
116+
"namespace": "tesla_telemetry",
117+
"kafka": {
118+
"bootstrap.servers": "some.broker1:9093,some.broker1:9093",
119+
"ssl.ca.location": "kafka.ca",
120+
"ssl.certificate.location": "kafka.crt",
121+
"ssl.key.location": "kafka.key",
122+
"queue.buffering.max.messages": 1000000
123+
},
124+
"records": {
125+
"FS": ["kafka"]
126+
},
127+
"tls": {
128+
"ca_file": "tesla.ca",
129+
"server_cert": "your_own_cert.crt",
130+
"server_key": "your_own_key.key"
131+
},
132+
"airbrake": {
133+
"project_id": 1,
134+
"project_key": "test1",
135+
"environment": "integration",
136+
"host": "http://errbit-test.example.com"
137+
}
138+
}
139+
`

0 commit comments

Comments
 (0)