-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger.go
132 lines (112 loc) · 3.08 KB
/
logger.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
package logging
import (
"encoding"
"encoding/json"
"errors"
"fmt"
"io"
"reflect"
"github.com/sirupsen/logrus"
)
type Logger interface {
Info(message string, keyvals ...interface{})
Debug(message string, keyvals ...interface{})
Error(err error, message string, keyvals ...interface{})
Warn(message string, keyvals ...interface{})
With(keyvals ...interface{}) Logger
IsDebugEnabled() bool
}
type logrusLogger struct {
entry *logrus.Entry
}
func (l logrusLogger) Info(message string, keyvals ...interface{}) {
l.entry.WithFields(toFields(keyvals...)).Info(message)
}
func (l logrusLogger) Debug(message string, keyvals ...interface{}) {
l.entry.WithFields(toFields(keyvals...)).Debug(message)
}
func (l logrusLogger) Error(err error, message string, keyvals ...interface{}) {
l.entry.WithFields(toFields(keyvals...)).WithError(err).Error(message)
}
func (l logrusLogger) Warn(message string, keyvals ...interface{}) {
l.entry.WithFields(toFields(keyvals...)).Warn(message)
}
func (l logrusLogger) With(keyvals ...interface{}) Logger {
return logrusLogger{l.entry.WithFields(toFields(keyvals...))}
}
func (l logrusLogger) IsDebugEnabled() bool {
return l.entry.Logger.IsLevelEnabled(logrus.DebugLevel)
}
func NewLogger(l *logrus.Logger) logrusLogger { //nolint:revive
return logrusLogger{logrus.NewEntry(l)}
}
func NewNopLogger() logrusLogger { //nolint:revive
l := logrus.New()
l.Out = io.Discard
return logrusLogger{logrus.NewEntry(l)}
}
var ErrMissingValue = errors.New("(MISSING)")
// This code is from https://github.com/go-kit/log/blob/main/json_logger.go#L23-L91 which safely handles odd keyvals
// lengths, and safely converting interface{} -> string
func toFields(keyvals ...interface{}) logrus.Fields {
n := (len(keyvals) + 1) / 2 // +1 to handle case when len is odd
m := make(map[string]interface{}, n)
for i := 0; i < len(keyvals); i += 2 {
k := keyvals[i]
var v interface{} = ErrMissingValue
if i+1 < len(keyvals) {
v = keyvals[i+1]
}
merge(m, k, v)
}
return m
}
func merge(dst map[string]interface{}, k, v interface{}) {
var key string
switch x := k.(type) {
case string:
key = x
case fmt.Stringer:
key = safeString(x)
default:
key = fmt.Sprint(x)
}
// We want json.Marshaler and encoding.TextMarshaller to take priority over
// err.Error() and v.String(). But json.Marshall (called later) does that by
// default so we force a no-op if it's one of those 2 case.
switch x := v.(type) {
case json.Marshaler:
case encoding.TextMarshaler:
case error:
v = safeError(x)
case fmt.Stringer:
v = safeString(x)
}
dst[key] = v
}
func safeString(str fmt.Stringer) (s string) {
defer func() {
if panicVal := recover(); panicVal != nil {
if v := reflect.ValueOf(str); v.Kind() == reflect.Ptr && v.IsNil() {
s = "NULL"
} else {
panic(panicVal)
}
}
}()
s = str.String()
return
}
func safeError(err error) (s interface{}) {
defer func() {
if panicVal := recover(); panicVal != nil {
if v := reflect.ValueOf(err); v.Kind() == reflect.Ptr && v.IsNil() {
s = nil
} else {
panic(panicVal)
}
}
}()
s = err.Error()
return
}