Skip to content

Commit 41578ca

Browse files
authoredJun 30, 2020
Be more like a library to support mobile (slackhq#247)
1 parent 1ea8847 commit 41578ca

21 files changed

+477
-69
lines changed
 

‎bits_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,10 @@ func TestBitsLostCounter(t *testing.T) {
212212
func BenchmarkBits(b *testing.B) {
213213
z := NewBits(10)
214214
for n := 0; n < b.N; n++ {
215-
for i, _ := range z.bits {
215+
for i := range z.bits {
216216
z.bits[i] = true
217217
}
218-
for i, _ := range z.bits {
218+
for i := range z.bits {
219219
z.bits[i] = false
220220
}
221221

‎cmd/nebula-service/main.go

+23-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ package main
33
import (
44
"flag"
55
"fmt"
6-
"os"
7-
6+
"github.com/sirupsen/logrus"
87
"github.com/slackhq/nebula"
8+
"os"
99
)
1010

1111
// A version string that can be set with
@@ -45,5 +45,25 @@ func main() {
4545
os.Exit(1)
4646
}
4747

48-
nebula.Main(*configPath, *configTest, Build)
48+
config := nebula.NewConfig()
49+
err := config.Load(*configPath)
50+
if err != nil {
51+
fmt.Printf("failed to load config: %s", err)
52+
os.Exit(1)
53+
}
54+
55+
l := logrus.New()
56+
l.Out = os.Stdout
57+
err = nebula.Main(config, *configTest, true, Build, l, nil, nil)
58+
59+
switch v := err.(type) {
60+
case nebula.ContextualError:
61+
v.Log(l)
62+
os.Exit(1)
63+
case error:
64+
l.WithError(err).Error("Failed to start")
65+
os.Exit(1)
66+
}
67+
68+
os.Exit(0)
4969
}

‎cmd/nebula-service/service.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package main
22

33
import (
4+
"fmt"
5+
"github.com/sirupsen/logrus"
46
"log"
57
"os"
68
"path/filepath"
@@ -27,8 +29,15 @@ func (p *program) Start(s service.Service) error {
2729
}
2830

2931
func (p *program) run() error {
30-
nebula.Main(*p.configPath, *p.configTest, Build)
31-
return nil
32+
config := nebula.NewConfig()
33+
err := config.Load(*p.configPath)
34+
if err != nil {
35+
return fmt.Errorf("failed to load config: %s", err)
36+
}
37+
38+
l := logrus.New()
39+
l.Out = os.Stdout
40+
return nebula.Main(config, *p.configTest, true, Build, l, nil, nil)
3241
}
3342

3443
func (p *program) Stop(s service.Service) error {

‎cmd/nebula/main.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"github.com/sirupsen/logrus"
67
"os"
78

89
"github.com/slackhq/nebula"
@@ -39,5 +40,25 @@ func main() {
3940
os.Exit(1)
4041
}
4142

42-
nebula.Main(*configPath, *configTest, Build)
43+
config := nebula.NewConfig()
44+
err := config.Load(*configPath)
45+
if err != nil {
46+
fmt.Printf("failed to load config: %s", err)
47+
os.Exit(1)
48+
}
49+
50+
l := logrus.New()
51+
l.Out = os.Stdout
52+
err = nebula.Main(config, *configTest, true, Build, l, nil, nil)
53+
54+
switch v := err.(type) {
55+
case nebula.ContextualError:
56+
v.Log(l)
57+
os.Exit(1)
58+
case error:
59+
l.WithError(err).Error("Failed to start")
60+
os.Exit(1)
61+
}
62+
63+
os.Exit(0)
4364
}

‎config.go

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package nebula
22

33
import (
4+
"errors"
45
"fmt"
56
"github.com/imdario/mergo"
67
"github.com/sirupsen/logrus"
@@ -56,6 +57,13 @@ func (c *Config) Load(path string) error {
5657
return nil
5758
}
5859

60+
func (c *Config) LoadString(raw string) error {
61+
if raw == "" {
62+
return errors.New("Empty configuration")
63+
}
64+
return c.parseRaw([]byte(raw))
65+
}
66+
5967
// RegisterReloadCallback stores a function to be called when a config reload is triggered. The functions registered
6068
// here should decide if they need to make a change to the current process before making the change. HasChanged can be
6169
// used to help decide if a change is necessary.
@@ -407,6 +415,18 @@ func (c *Config) addFile(path string, direct bool) error {
407415
return nil
408416
}
409417

418+
func (c *Config) parseRaw(b []byte) error {
419+
var m map[interface{}]interface{}
420+
421+
err := yaml.Unmarshal(b, &m)
422+
if err != nil {
423+
return err
424+
}
425+
426+
c.Settings = m
427+
return nil
428+
}
429+
410430
func (c *Config) parse() error {
411431
var m map[interface{}]interface{}
412432

‎logger.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package nebula
2+
3+
import (
4+
"github.com/sirupsen/logrus"
5+
)
6+
7+
type ContextualError struct {
8+
RealError error
9+
Fields map[string]interface{}
10+
Context string
11+
}
12+
13+
func NewContextualError(msg string, fields map[string]interface{}, realError error) ContextualError {
14+
return ContextualError{Context: msg, Fields: fields, RealError: realError}
15+
}
16+
17+
func (ce ContextualError) Error() string {
18+
return ce.RealError.Error()
19+
}
20+
21+
func (ce ContextualError) Unwrap() error {
22+
return ce.RealError
23+
}
24+
25+
func (ce *ContextualError) Log(lr *logrus.Logger) {
26+
if ce.RealError != nil {
27+
lr.WithFields(ce.Fields).WithError(ce.RealError).Error(ce.Context)
28+
} else {
29+
lr.WithFields(ce.Fields).Error(ce.Context)
30+
}
31+
}

‎logger_test.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package nebula
2+
3+
import (
4+
"errors"
5+
"github.com/sirupsen/logrus"
6+
"github.com/stretchr/testify/assert"
7+
"testing"
8+
)
9+
10+
type TestLogWriter struct {
11+
Logs []string
12+
}
13+
14+
func NewTestLogWriter() *TestLogWriter {
15+
return &TestLogWriter{Logs: make([]string, 0)}
16+
}
17+
18+
func (tl *TestLogWriter) Write(p []byte) (n int, err error) {
19+
tl.Logs = append(tl.Logs, string(p))
20+
return len(p), nil
21+
}
22+
23+
func (tl *TestLogWriter) Reset() {
24+
tl.Logs = tl.Logs[:0]
25+
}
26+
27+
func TestContextualError_Log(t *testing.T) {
28+
l := logrus.New()
29+
l.Formatter = &logrus.TextFormatter{
30+
DisableTimestamp: true,
31+
DisableColors: true,
32+
}
33+
34+
tl := NewTestLogWriter()
35+
l.Out = tl
36+
37+
// Test a full context line
38+
tl.Reset()
39+
e := NewContextualError("test message", m{"field": "1"}, errors.New("error"))
40+
e.Log(l)
41+
assert.Equal(t, []string{"level=error msg=\"test message\" error=error field=1\n"}, tl.Logs)
42+
43+
// Test a line with an error and msg but no fields
44+
tl.Reset()
45+
e = NewContextualError("test message", nil, errors.New("error"))
46+
e.Log(l)
47+
assert.Equal(t, []string{"level=error msg=\"test message\" error=error\n"}, tl.Logs)
48+
49+
// Test just a context and fields
50+
tl.Reset()
51+
e = NewContextualError("test message", m{"field": "1"}, nil)
52+
e.Log(l)
53+
assert.Equal(t, []string{"level=error msg=\"test message\" field=1\n"}, tl.Logs)
54+
55+
// Test just a context
56+
tl.Reset()
57+
e = NewContextualError("test message", nil, nil)
58+
e.Log(l)
59+
assert.Equal(t, []string{"level=error msg=\"test message\"\n"}, tl.Logs)
60+
61+
// Test just an error
62+
tl.Reset()
63+
e = NewContextualError("", nil, errors.New("error"))
64+
e.Log(l)
65+
assert.Equal(t, []string{"level=error error=error\n"}, tl.Logs)
66+
}

0 commit comments

Comments
 (0)