8 type LevelFilterHandler struct {
13 // Filters out records which do not match the level
14 // Uses the `log15.FilterHandler` to perform this task
15 func LevelHandler(lvl LogLevel, h LogHandler) LogHandler {
16 return &LevelFilterHandler{lvl, h}
19 // The implementation of the Log
20 func (h LevelFilterHandler) Log(r *Record) error {
21 if r.Level == h.Level {
27 // Filters out records which do not match the level
28 // Uses the `log15.FilterHandler` to perform this task
29 func MinLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
30 return FilterHandler(func(r *Record) (pass bool) {
35 // Filters out records which match the level
36 // Uses the `log15.FilterHandler` to perform this task
37 func NotLevelHandler(lvl LogLevel, h LogHandler) LogHandler {
38 return FilterHandler(func(r *Record) (pass bool) {
43 func CallerFileHandler(h LogHandler) LogHandler {
44 return FuncHandler(func(r *Record) error {
45 r.Context.Add("caller", fmt.Sprint(r.Call))
50 // Adds in a context called `caller` to the record (contains file name and line number like `foo.go:12`)
51 // Uses the `log15.CallerFuncHandler` to perform this task
52 func CallerFuncHandler(h LogHandler) LogHandler {
53 return CallerFuncHandler(h)
56 // Filters out records which match the key value pair
57 // Uses the `log15.MatchFilterHandler` to perform this task
58 func MatchHandler(key string, value interface{}, h LogHandler) LogHandler {
59 return MatchFilterHandler(key, value, h)
62 // MatchFilterHandler returns a Handler that only writes records
63 // to the wrapped Handler if the given key in the logged
64 // context matches the value. For example, to only log records
65 // from your ui package:
67 // log.MatchFilterHandler("pkg", "app/ui", log.StdoutHandler)
69 func MatchFilterHandler(key string, value interface{}, h LogHandler) LogHandler {
70 return FilterHandler(func(r *Record) (pass bool) {
71 return r.Context[key] == value
75 // If match then A handler is called otherwise B handler is called
76 func MatchAbHandler(key string, value interface{}, a, b LogHandler) LogHandler {
77 return FuncHandler(func(r *Record) error {
78 if r.Context[key] == value {
88 // The nil handler is used if logging for a specific request needs to be turned off
89 func NilHandler() LogHandler {
90 return FuncHandler(func(r *Record) error {
95 // Match all values in map to log
96 func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
97 return matchMapHandler(matchMap, false, a)
100 // Match !(Match all values in map to log) The inverse of MatchMapHandler
101 func NotMatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler {
102 return matchMapHandler(matchMap, true, a)
105 // Rather then chaining multiple filter handlers, process all here
106 func matchMapHandler(matchMap map[string]interface{}, inverse bool, a LogHandler) LogHandler {
107 return FuncHandler(func(r *Record) error {
109 for k, v := range matchMap {
110 value, found := r.Context[k]
114 // Test for two failure cases
115 if value == v && inverse || value != v && !inverse {
121 if matchCount != len(matchMap) {
128 // Filters out records which do not match the key value pair
129 // Uses the `log15.FilterHandler` to perform this task
130 func NotMatchHandler(key string, value interface{}, h LogHandler) LogHandler {
131 return FilterHandler(func(r *Record) (pass bool) {
132 return r.Context[key] != value
136 func MultiHandler(hs ...LogHandler) LogHandler {
137 return FuncHandler(func(r *Record) error {
138 for _, h := range hs {
139 // what to do about failures?
146 // StreamHandler writes log records to an io.Writer
147 // with the given format. StreamHandler can be used
148 // to easily begin writing log records to other
151 // StreamHandler wraps itself with LazyHandler and SyncHandler
152 // to evaluate Lazy objects and perform safe concurrent writes.
153 func StreamHandler(wr io.Writer, fmtr LogFormat) LogHandler {
154 h := FuncHandler(func(r *Record) error {
155 _, err := wr.Write(fmtr.Format(r))
158 return LazyHandler(SyncHandler(h))
162 func FilterHandler(fn func(r *Record) bool, h LogHandler) LogHandler {
163 return FuncHandler(func(r *Record) error {
171 // List log handler handles a list of LogHandlers
172 type ListLogHandler struct {
173 handlers []LogHandler
176 // Create a new list of log handlers
177 func NewListLogHandler(h1, h2 LogHandler) *ListLogHandler {
178 ll := &ListLogHandler{handlers: []LogHandler{h1, h2}}
183 func (ll *ListLogHandler) Log(r *Record) (err error) {
184 for _, handler := range ll.handlers {
194 // Add another log handler
195 func (ll *ListLogHandler) Add(h LogHandler) {
197 ll.handlers = append(ll.handlers, h)
201 // Remove a log handler
202 func (ll *ListLogHandler) Del(h LogHandler) {
204 for i, handler := range ll.handlers {
206 ll.handlers = append(ll.handlers[:i], ll.handlers[i+1:]...)