Skip to content

Commit 4d2d85e

Browse files
authored
Merge pull request #42 from nathanejohnson/feature/modular_logging
Remove hard dependency on logrus for logging
2 parents 87609ae + 8c6aae6 commit 4d2d85e

File tree

5 files changed

+191
-8
lines changed

5 files changed

+191
-8
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ require (
44
github.com/golang/protobuf v1.3.1
55
github.com/segmentio/fasthash v1.0.3
66
github.com/sirupsen/logrus v1.6.0
7+
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
78
)
89

910
go 1.15

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJ
66
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
77
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
88
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9+
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
10+
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
911
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
1012
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
1113
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
1214
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
1315
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
1416
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
15-
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
16-
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
17+
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
18+
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

groupcache.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,15 @@ import (
3838
"github.com/sirupsen/logrus"
3939
)
4040

41-
var logger *logrus.Entry
41+
var logger Logger
4242

43+
// SetLogger - this is legacy to provide backwards compatibility with logrus.
4344
func SetLogger(log *logrus.Entry) {
45+
logger = LogrusLogger{Entry: log}
46+
}
47+
48+
// SetLoggerFromLogger - set the logger to an implementation of the Logger interface
49+
func SetLoggerFromLogger(log Logger) {
4450
logger = log
4551
}
4652

@@ -392,11 +398,12 @@ func (g *Group) load(ctx context.Context, key string, dest Sink) (value ByteView
392398
}
393399

394400
if logger != nil {
395-
logger.WithFields(logrus.Fields{
396-
"err": err,
397-
"key": key,
398-
"category": "groupcache",
399-
}).Errorf("error retrieving key from peer '%s'", peer.GetURL())
401+
logger.Error().
402+
WithFields(map[string]interface{}{
403+
"err": err,
404+
"key": key,
405+
"category": "groupcache",
406+
}).Printf("error retrieving key from peer '%s'", peer.GetURL())
400407
}
401408

402409
g.Stats.PeerErrors.Add(1)

logger.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package groupcache
2+
3+
import (
4+
"github.com/sirupsen/logrus"
5+
)
6+
7+
// Logger is a minimal interface that will allow us to use structured loggers,
8+
// including (but not limited to) logrus.
9+
type Logger interface {
10+
// Error logging level
11+
Error() Logger
12+
13+
// Warn logging level
14+
Warn() Logger
15+
16+
// Info logging level
17+
Info() Logger
18+
19+
// Debug logging level
20+
Debug() Logger
21+
22+
// ErrorField is a field with an error value
23+
ErrorField(label string, err error) Logger
24+
25+
// StringField is a field with a string value
26+
StringField(label string, val string) Logger
27+
28+
// WithFields is willy-nilly key value pairs.
29+
WithFields(fields map[string]interface{}) Logger
30+
31+
// Printf is called last to emit the log at the given
32+
// level.
33+
Printf(format string, args ...interface{})
34+
}
35+
36+
// LogrusLogger is an implementation of Logger that wraps logrus... who knew?
37+
type LogrusLogger struct {
38+
Entry *logrus.Entry
39+
level logrus.Level
40+
}
41+
42+
func (l LogrusLogger) Info() Logger {
43+
return LogrusLogger{
44+
Entry: l.Entry,
45+
level: logrus.InfoLevel,
46+
}
47+
}
48+
49+
func (l LogrusLogger) Debug() Logger {
50+
return LogrusLogger{
51+
Entry: l.Entry,
52+
level: logrus.DebugLevel,
53+
}
54+
}
55+
56+
func (l LogrusLogger) Warn() Logger {
57+
return LogrusLogger{
58+
Entry: l.Entry,
59+
level: logrus.WarnLevel,
60+
}
61+
}
62+
63+
func (l LogrusLogger) Error() Logger {
64+
return LogrusLogger{
65+
Entry: l.Entry,
66+
level: logrus.ErrorLevel,
67+
}
68+
}
69+
70+
func (l LogrusLogger) WithFields(fields map[string]interface{}) Logger {
71+
return LogrusLogger{
72+
Entry: l.Entry.WithFields(fields),
73+
level: l.level,
74+
}
75+
}
76+
77+
// ErrorField - create a field for an error
78+
func (l LogrusLogger) ErrorField(label string, err error) Logger {
79+
return LogrusLogger{
80+
Entry: l.Entry.WithField(label, err),
81+
level: l.level,
82+
}
83+
84+
}
85+
86+
// StringField - create a field for a string.
87+
func (l LogrusLogger) StringField(label string, val string) Logger {
88+
return LogrusLogger{
89+
Entry: l.Entry.WithField(label, val),
90+
level: l.level,
91+
}
92+
}
93+
94+
func (l LogrusLogger) Printf(format string, args ...interface{}) {
95+
l.Entry.Logf(l.level, format, args...)
96+
}

logger_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package groupcache
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"github.com/sirupsen/logrus"
7+
"testing"
8+
)
9+
10+
// This tests the compatibility of the LogrusLogger with the previous behavior.
11+
func TestLogrusLogger(t *testing.T) {
12+
var buf bytes.Buffer
13+
l := logrus.New()
14+
l.SetFormatter(&logrus.TextFormatter{
15+
DisableTimestamp: true,
16+
})
17+
l.Out = &buf
18+
e := logrus.NewEntry(l)
19+
e = e.WithField("ContextKey", "ContextVal")
20+
SetLogger(e)
21+
logger.Error().
22+
WithFields(map[string]interface{}{
23+
"err": errors.New("test error"),
24+
"key": "keyValue",
25+
"category": "groupcache",
26+
}).Printf("error retrieving key from peer %s", "http://127.0.0.1:8080")
27+
28+
interfaceOut := buf.String()
29+
buf.Reset()
30+
e.WithFields(logrus.Fields{
31+
"err": errors.New("test error"),
32+
"key": "keyValue",
33+
"category": "groupcache",
34+
}).Errorf("error retrieving key from peer %s", "http://127.0.0.1:8080")
35+
logrusOut := buf.String()
36+
if interfaceOut != logrusOut {
37+
t.Errorf("output is not the same.\ngot:\n%s\nwant:\n%s", interfaceOut, logrusOut)
38+
}
39+
}
40+
41+
func BenchmarkLogrusLogger(b *testing.B) {
42+
var buf bytes.Buffer
43+
l := logrus.New()
44+
l.SetFormatter(&logrus.TextFormatter{
45+
DisableTimestamp: true,
46+
})
47+
l.Out = &buf
48+
e := logrus.NewEntry(l)
49+
SetLogger(e)
50+
for i := 0; i < b.N; i++ {
51+
logger.Error().
52+
WithFields(map[string]interface{}{
53+
"err": errors.New("test error"),
54+
"key": "keyValue",
55+
"category": "groupcache",
56+
}).Printf("error retrieving key from peer %s", "http://127.0.0.1:8080")
57+
buf.Reset()
58+
}
59+
}
60+
61+
func BenchmarkLogrus(b *testing.B) {
62+
var buf bytes.Buffer
63+
l := logrus.New()
64+
l.SetFormatter(&logrus.TextFormatter{
65+
DisableTimestamp: true,
66+
})
67+
l.Out = &buf
68+
e := logrus.NewEntry(l)
69+
for i := 0; i < b.N; i++ {
70+
e.WithFields(logrus.Fields{
71+
"err": errors.New("test error"),
72+
"key": "keyValue",
73+
"category": "groupcache",
74+
}).Errorf("error retrieving key from peer %s", "http://127.0.0.1:8080")
75+
buf.Reset()
76+
}
77+
}

0 commit comments

Comments
 (0)