-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathglobal_logger_test.go
235 lines (207 loc) · 7.14 KB
/
global_logger_test.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
package logger
import (
"bytes"
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestGlobalLoggerLogLevels(t *testing.T) {
type testCase struct {
logFunc func(args ...interface{})
expectedLogLevel string
}
buf := &bytes.Buffer{}
oldOutput := globalLogger.output
oldLevel := globalLogger.level
oldExitFunc := globalLogger.logrusLogger.ExitFunc
defer func() {
// bring global logger to original state after tests
ConfigureGlobalLogger(WithOutput(oldOutput), WithLevel(oldLevel))
globalLogger.logrusLogger.ExitFunc = oldExitFunc
}()
ConfigureGlobalLogger(WithOutput(buf), WithLevel(LevelDebug))
globalLogger.logrusLogger.ExitFunc = func(int) {}
testCases := map[string]testCase{
"Info() should log with level info": {
logFunc: Info,
expectedLogLevel: "info",
},
"Error() should log with level error": {
logFunc: Error,
expectedLogLevel: "error",
},
"Debug() should log with level debug": {
logFunc: Debug,
expectedLogLevel: "debug",
},
"Warn() should log with level warning": {
logFunc: Warn,
expectedLogLevel: "warning",
},
"Fatal() should log with level fatal": {
logFunc: Fatal,
expectedLogLevel: "fatal",
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
tc.logFunc("foobar")
assertLogEntryContains(t, buf, "level", tc.expectedLogLevel)
})
}
}
func TestGlobalLoggerLogLevelsInFormatFuncs(t *testing.T) {
type testCase struct {
logFunc func(format string, args ...interface{})
expectedLogLevel string
}
buf := &bytes.Buffer{}
oldOutput := globalLogger.output
oldLevel := globalLogger.level
oldExitFunc := globalLogger.logrusLogger.ExitFunc
defer func() {
// bring global logger to original state after tests
ConfigureGlobalLogger(WithOutput(oldOutput), WithLevel(oldLevel))
globalLogger.logrusLogger.ExitFunc = oldExitFunc
}()
ConfigureGlobalLogger(WithOutput(buf), WithLevel(LevelDebug))
globalLogger.logrusLogger.ExitFunc = func(int) {}
testCases := map[string]testCase{
"Info() should log with level info": {
logFunc: Infof,
expectedLogLevel: "info",
},
"Error() should log with level error": {
logFunc: Errorf,
expectedLogLevel: "error",
},
"Debug() should log with level debug": {
logFunc: Debugf,
expectedLogLevel: "debug",
},
"Warn() should log with level warning": {
logFunc: Warnf,
expectedLogLevel: "warning",
},
"Fatal() should log with level fatal": {
logFunc: Fatalf,
expectedLogLevel: "fatal",
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
tc.logFunc("foobar")
assertLogEntryContains(t, buf, "level", tc.expectedLogLevel)
})
}
}
func TestGlobalLoggerConvenienveFunctions(t *testing.T) {
buf := &bytes.Buffer{}
oldOutput := globalLogger.output
oldNowFunc := globalLogger.now
defer func() {
SetOutput(oldOutput)
SetNowFunc(oldNowFunc)
SetReportCaller(true)
SetLevel(globalLogger.level)
}()
{
SetOutput(buf)
SetNowFunc(mockNowFunc)
SetReportCaller(false)
}
Warn("foobar")
assertLogEntryContains(t, buf, "msg", "foobar")
Info("I won't be logged because the default log level is higher than info")
SetLevel(LevelInfo)
Info("but now I will")
assertLogEntryContains(t, buf, "msg", "but now I will")
}
func TestChainingSetup(t *testing.T) {
buf := &bytes.Buffer{}
oldOutput := globalLogger.output
oldLevel := globalLogger.level
oldNowFunc := globalLogger.now
defer func() {
// bring global logger to original state after tests
ConfigureGlobalLogger(WithOutput(oldOutput), WithLevel(oldLevel), WithNowFunc(oldNowFunc))
}()
ConfigureGlobalLogger(WithOutput(buf), WithLevel(LevelDebug), WithNowFunc(mockNowFunc), WithHookFunc(testHook))
ctx := context.WithValue(context.Background(), myCtxKey{}, "my-custom-ctx-value")
err := fmt.Errorf("some error")
{
// Start with global WithField
WithField("foo", "bar").WithContext(ctx).WithFields(Fields{"baz": "quoo", "number": 42}).WithError(err).Infof("hello %s", "world")
b := buf.Bytes() // get bytes for multiple-reads
buf.Reset() // Prepare for next log message
assertLogEntryContains(t, bytes.NewReader(b), "msg", "hello world")
assertLogEntryContains(t, bytes.NewReader(b), "foo", "bar")
assertLogEntryContains(t, bytes.NewReader(b), "my-custom-log-key", "my-custom-ctx-value")
assertLogEntryContains(t, bytes.NewReader(b), "baz", "quoo")
assertLogEntryContains(t, bytes.NewReader(b), "number", float64(42))
}
{
// Start with global WithFields
WithFields(Fields{"baz": "quoo", "number": 42}).WithField("foo", "bar").WithContext(ctx).WithError(err).Infof("hello %s", "world")
b := buf.Bytes() // get bytes for multiple-reads
buf.Reset() // Prepare for next log message
assertLogEntryContains(t, bytes.NewReader(b), "msg", "hello world")
assertLogEntryContains(t, bytes.NewReader(b), "foo", "bar")
assertLogEntryContains(t, bytes.NewReader(b), "my-custom-log-key", "my-custom-ctx-value")
assertLogEntryContains(t, bytes.NewReader(b), "baz", "quoo")
assertLogEntryContains(t, bytes.NewReader(b), "number", float64(42))
}
{
// Start with global WithError
WithError(err).WithFields(Fields{"baz": "quoo", "number": 42}).WithField("foo", "bar").WithContext(ctx).Infof("hello %s", "world")
b := buf.Bytes() // get bytes for multiple-reads
buf.Reset() // Prepare for next log message
assertLogEntryContains(t, bytes.NewReader(b), "msg", "hello world")
assertLogEntryContains(t, bytes.NewReader(b), "foo", "bar")
assertLogEntryContains(t, bytes.NewReader(b), "my-custom-log-key", "my-custom-ctx-value")
assertLogEntryContains(t, bytes.NewReader(b), "baz", "quoo")
assertLogEntryContains(t, bytes.NewReader(b), "number", float64(42))
}
{
// Start with global WithContext
WithContext(ctx).WithError(err).WithFields(Fields{"baz": "quoo", "number": 42}).WithField("foo", "bar").Infof("hello %s", "world")
b := buf.Bytes() // get bytes for multiple-reads
buf.Reset() // Prepare for next log message
assertLogEntryContains(t, bytes.NewReader(b), "msg", "hello world")
assertLogEntryContains(t, bytes.NewReader(b), "foo", "bar")
assertLogEntryContains(t, bytes.NewReader(b), "my-custom-log-key", "my-custom-ctx-value")
assertLogEntryContains(t, bytes.NewReader(b), "baz", "quoo")
assertLogEntryContains(t, bytes.NewReader(b), "number", float64(42))
}
}
func TestGlobalLoggerFromEnv(t *testing.T) {
const (
logmsg = "Some log"
envName = "LOG_LEVEL"
)
buf := &bytes.Buffer{}
oldOutput := globalLogger.output
oldNowFunc := globalLogger.now
defer func() {
SetOutput(oldOutput)
SetNowFunc(oldNowFunc)
SetReportCaller(true)
SetLevel(globalLogger.level)
}()
{
SetOutput(buf)
SetNowFunc(mockNowFunc)
SetReportCaller(false)
}
ConfigureGlobalLogger(WithLevelFromEnv(envName), WithOutput(buf))
Info(logmsg)
decodeLogToMap(t, buf)
assert.NotContains(t, buf.String(), logmsg)
// Test that it reads the var correctly to a Level in the Global Config
buf.Reset() // reset the buffer
t.Setenv(envName, "info")
ConfigureGlobalLogger(WithLevelFromEnv(envName), WithOutput(buf))
Info(logmsg)
assertLogEntryContains(t, buf, "msg", logmsg)
}