1 package logrus_test
2
3 import (
4 "bytes"
5 "encoding/json"
6 "sync"
7 "testing"
8
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11
12 . "github.com/sirupsen/logrus"
13 . "github.com/sirupsen/logrus/internal/testutils"
14 )
15
16 type TestHook struct {
17 Fired bool
18 }
19
20 func (hook *TestHook) Fire(entry *Entry) error {
21 hook.Fired = true
22 return nil
23 }
24
25 func (hook *TestHook) Levels() []Level {
26 return []Level{
27 TraceLevel,
28 DebugLevel,
29 InfoLevel,
30 WarnLevel,
31 ErrorLevel,
32 FatalLevel,
33 PanicLevel,
34 }
35 }
36
37 func TestHookFires(t *testing.T) {
38 hook := new(TestHook)
39
40 LogAndAssertJSON(t, func(log *Logger) {
41 log.Hooks.Add(hook)
42 assert.Equal(t, hook.Fired, false)
43
44 log.Print("test")
45 }, func(fields Fields) {
46 assert.Equal(t, hook.Fired, true)
47 })
48 }
49
50 type ModifyHook struct {
51 }
52
53 func (hook *ModifyHook) Fire(entry *Entry) error {
54 entry.Data["wow"] = "whale"
55 return nil
56 }
57
58 func (hook *ModifyHook) Levels() []Level {
59 return []Level{
60 TraceLevel,
61 DebugLevel,
62 InfoLevel,
63 WarnLevel,
64 ErrorLevel,
65 FatalLevel,
66 PanicLevel,
67 }
68 }
69
70 func TestHookCanModifyEntry(t *testing.T) {
71 hook := new(ModifyHook)
72
73 LogAndAssertJSON(t, func(log *Logger) {
74 log.Hooks.Add(hook)
75 log.WithField("wow", "elephant").Print("test")
76 }, func(fields Fields) {
77 assert.Equal(t, fields["wow"], "whale")
78 })
79 }
80
81 func TestCanFireMultipleHooks(t *testing.T) {
82 hook1 := new(ModifyHook)
83 hook2 := new(TestHook)
84
85 LogAndAssertJSON(t, func(log *Logger) {
86 log.Hooks.Add(hook1)
87 log.Hooks.Add(hook2)
88
89 log.WithField("wow", "elephant").Print("test")
90 }, func(fields Fields) {
91 assert.Equal(t, fields["wow"], "whale")
92 assert.Equal(t, hook2.Fired, true)
93 })
94 }
95
96 type SingleLevelModifyHook struct {
97 ModifyHook
98 }
99
100 func (h *SingleLevelModifyHook) Levels() []Level {
101 return []Level{InfoLevel}
102 }
103
104 func TestHookEntryIsPristine(t *testing.T) {
105 l := New()
106 b := &bytes.Buffer{}
107 l.Formatter = &JSONFormatter{}
108 l.Out = b
109 l.AddHook(&SingleLevelModifyHook{})
110
111 l.Error("error message")
112 data := map[string]string{}
113 err := json.Unmarshal(b.Bytes(), &data)
114 require.NoError(t, err)
115 _, ok := data["wow"]
116 require.False(t, ok)
117 b.Reset()
118
119 l.Info("error message")
120 data = map[string]string{}
121 err = json.Unmarshal(b.Bytes(), &data)
122 require.NoError(t, err)
123 _, ok = data["wow"]
124 require.True(t, ok)
125 b.Reset()
126
127 l.Error("error message")
128 data = map[string]string{}
129 err = json.Unmarshal(b.Bytes(), &data)
130 require.NoError(t, err)
131 _, ok = data["wow"]
132 require.False(t, ok)
133 b.Reset()
134 }
135
136 type ErrorHook struct {
137 Fired bool
138 }
139
140 func (hook *ErrorHook) Fire(entry *Entry) error {
141 hook.Fired = true
142 return nil
143 }
144
145 func (hook *ErrorHook) Levels() []Level {
146 return []Level{
147 ErrorLevel,
148 }
149 }
150
151 func TestErrorHookShouldntFireOnInfo(t *testing.T) {
152 hook := new(ErrorHook)
153
154 LogAndAssertJSON(t, func(log *Logger) {
155 log.Hooks.Add(hook)
156 log.Info("test")
157 }, func(fields Fields) {
158 assert.Equal(t, hook.Fired, false)
159 })
160 }
161
162 func TestErrorHookShouldFireOnError(t *testing.T) {
163 hook := new(ErrorHook)
164
165 LogAndAssertJSON(t, func(log *Logger) {
166 log.Hooks.Add(hook)
167 log.Error("test")
168 }, func(fields Fields) {
169 assert.Equal(t, hook.Fired, true)
170 })
171 }
172
173 func TestAddHookRace(t *testing.T) {
174 var wg sync.WaitGroup
175 wg.Add(2)
176 hook := new(ErrorHook)
177 LogAndAssertJSON(t, func(log *Logger) {
178 go func() {
179 defer wg.Done()
180 log.AddHook(hook)
181 }()
182 go func() {
183 defer wg.Done()
184 log.Error("test")
185 }()
186 wg.Wait()
187 }, func(fields Fields) {
188
189
190
191 })
192 }
193
View as plain text