This repository has been archived by the owner on Oct 27, 2022. It is now read-only.
forked from revel/revel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlers.go
210 lines (185 loc) · 5.32 KB
/
handlers.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
package logger
import (
"fmt"
"io"
)
type LevelFilterHandler struct {
Level LogLevel
h LogHandler
}
// Filters out records which do not match the level
// Uses the `log15.FilterHandler` to perform this task
func LevelHandler(lvl LogLevel, h LogHandler) LogHandler {
return &LevelFilterHandler{lvl, h}
}
// The implementation of the Log
func (h LevelFilterHandler) Log(r *Record) error {
if r.Level == h.Level {
return h.h.Log(r)
}
return nil
}
// Filters out records which do not match the level
// Uses the `log15.FilterHandler` to perform this task
func MinLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Level <= lvl
}, h)
}
// Filters out records which match the level
// Uses the `log15.FilterHandler` to perform this task
func NotLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Level != lvl
}, h)
}
func CallerFileHandler(h LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
r.Context.Add("caller", fmt.Sprint(r.Call))
return h.Log(r)
})
}
// Adds in a context called `caller` to the record (contains file name and line number like `foo.go:12`)
// Uses the `log15.CallerFuncHandler` to perform this task
func CallerFuncHandler(h LogHandler) LogHandler {
return CallerFuncHandler(h)
}
// Filters out records which match the key value pair
// Uses the `log15.MatchFilterHandler` to perform this task
func MatchHandler(key string, value interface{}, h LogHandler) LogHandler {
return MatchFilterHandler(key, value, h)
}
// MatchFilterHandler returns a Handler that only writes records
// to the wrapped Handler if the given key in the logged
// context matches the value. For example, to only log records
// from your ui package:
//
// log.MatchFilterHandler("pkg", "app/ui", log.StdoutHandler)
//
func MatchFilterHandler(key string, value interface{}, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Context[key] == value
}, h)
}
// If match then A handler is called otherwise B handler is called
func MatchAbHandler(key string, value interface{}, a, b LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
if r.Context[key] == value {
return a.Log(r)
} else if b != nil {
return b.Log(r)
}
return nil
})
}
// The nil handler is used if logging for a specific request needs to be turned off
func NilHandler() LogHandler {
return FuncHandler(func(r *Record) error {
return nil
})
}
// Match all values in map to log
func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
return matchMapHandler(matchMap, false, a)
}
// Match !(Match all values in map to log) The inverse of MatchMapHandler
func NotMatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
return matchMapHandler(matchMap, true, a)
}
// Rather then chaining multiple filter handlers, process all here
func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
matchCount := 0
for k, v := range matchMap {
value, found := r.Context[k]
if !found {
return nil
}
// Test for two failure cases
if value == v && inverse || value != v && !inverse {
return nil
} else {
matchCount++
}
}
if matchCount != len(matchMap) {
return nil
}
return a.Log(r)
})
}
// Filters out records which do not match the key value pair
// Uses the `log15.FilterHandler` to perform this task
func NotMatchHandler(key string, value interface{}, h LogHandler) LogHandler {
return FilterHandler(func(r *Record) (pass bool) {
return r.Context[key] != value
}, h)
}
func MultiHandler(hs ...LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
for _, h := range hs {
// what to do about failures?
h.Log(r)
}
return nil
})
}
// StreamHandler writes log records to an io.Writer
// with the given format. StreamHandler can be used
// to easily begin writing log records to other
// outputs.
//
// StreamHandler wraps itself with LazyHandler and SyncHandler
// to evaluate Lazy objects and perform safe concurrent writes.
func StreamHandler(wr io.Writer, fmtr LogFormat) LogHandler {
h := FuncHandler(func(r *Record) error {
_, err := wr.Write(fmtr.Format(r))
return err
})
return LazyHandler(SyncHandler(h))
}
// Filter handler
func FilterHandler(fn func(r *Record) bool, h LogHandler) LogHandler {
return FuncHandler(func(r *Record) error {
if fn(r) {
return h.Log(r)
}
return nil
})
}
// List log handler handles a list of LogHandlers
type ListLogHandler struct {
handlers []LogHandler
}
// Create a new list of log handlers
func NewListLogHandler(h1, h2 LogHandler) *ListLogHandler {
ll := &ListLogHandler{handlers: []LogHandler{h1, h2}}
return ll
}
// Log the record
func (ll *ListLogHandler) Log(r *Record) (err error) {
for _, handler := range ll.handlers {
if err == nil {
err = handler.Log(r)
} else {
handler.Log(r)
}
}
return
}
// Add another log handler
func (ll *ListLogHandler) Add(h LogHandler) {
if h != nil {
ll.handlers = append(ll.handlers, h)
}
}
// Remove a log handler
func (ll *ListLogHandler) Del(h LogHandler) {
if h != nil {
for i, handler := range ll.handlers {
if handler == h {
ll.handlers = append(ll.handlers[:i], ll.handlers[i+1:]...)
}
}
}
}