github.com/jd-ly/cmd@v1.0.10/logger/handlers.go (about) 1 package logger 2 3 import ( 4 "fmt" 5 "io" 6 ) 7 8 type LevelFilterHandler struct { 9 Level LogLevel 10 h LogHandler 11 } 12 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} 17 } 18 19 // The implementation of the Log 20 func (h LevelFilterHandler) Log(r *Record) error { 21 if r.Level == h.Level { 22 return h.h.Log(r) 23 } 24 return nil 25 } 26 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) { 31 return r.Level <= lvl 32 }, h) 33 } 34 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) { 39 return r.Level != lvl 40 }, h) 41 } 42 43 func CallerFileHandler(h LogHandler) LogHandler { 44 return FuncHandler(func(r *Record) error { 45 r.Context.Add("caller", fmt.Sprint(r.Call)) 46 return h.Log(r) 47 }) 48 } 49 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) 54 } 55 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) 60 } 61 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: 66 // 67 // log.MatchFilterHandler("pkg", "app/ui", log.StdoutHandler) 68 // 69 func MatchFilterHandler(key string, value interface{}, h LogHandler) LogHandler { 70 return FilterHandler(func(r *Record) (pass bool) { 71 return r.Context[key] == value 72 }, h) 73 } 74 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 { 79 return a.Log(r) 80 } else if b != nil { 81 return b.Log(r) 82 } 83 84 return nil 85 }) 86 } 87 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 { 91 return nil 92 }) 93 } 94 95 // Match all values in map to log 96 func MatchMapHandler(matchMap map[string]interface{}, a LogHandler) LogHandler { 97 return matchMapHandler(matchMap, false, a) 98 } 99 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) 103 } 104 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 { 108 matchCount := 0 109 for k, v := range matchMap { 110 value, found := r.Context[k] 111 if !found { 112 return nil 113 } 114 // Test for two failure cases 115 if value == v && inverse || value != v && !inverse { 116 return nil 117 } else { 118 matchCount++ 119 } 120 } 121 if matchCount != len(matchMap) { 122 return nil 123 } 124 return a.Log(r) 125 }) 126 } 127 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 133 }, h) 134 } 135 136 func MultiHandler(hs ...LogHandler) LogHandler { 137 return FuncHandler(func(r *Record) error { 138 for _, h := range hs { 139 // what to do about failures? 140 h.Log(r) 141 } 142 return nil 143 }) 144 } 145 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 149 // outputs. 150 // 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)) 156 return err 157 }) 158 return LazyHandler(SyncHandler(h)) 159 } 160 161 // Filter handler 162 func FilterHandler(fn func(r *Record) bool, h LogHandler) LogHandler { 163 return FuncHandler(func(r *Record) error { 164 if fn(r) { 165 return h.Log(r) 166 } 167 return nil 168 }) 169 } 170 171 // List log handler handles a list of LogHandlers 172 type ListLogHandler struct { 173 handlers []LogHandler 174 } 175 176 // Create a new list of log handlers 177 func NewListLogHandler(h1, h2 LogHandler) *ListLogHandler { 178 ll := &ListLogHandler{handlers: []LogHandler{h1, h2}} 179 return ll 180 } 181 182 // Log the record 183 func (ll *ListLogHandler) Log(r *Record) (err error) { 184 for _, handler := range ll.handlers { 185 if err == nil { 186 err = handler.Log(r) 187 } else { 188 handler.Log(r) 189 } 190 } 191 return 192 } 193 194 // Add another log handler 195 func (ll *ListLogHandler) Add(h LogHandler) { 196 if h != nil { 197 ll.handlers = append(ll.handlers, h) 198 } 199 } 200 201 // Remove a log handler 202 func (ll *ListLogHandler) Del(h LogHandler) { 203 if h != nil { 204 for i, handler := range ll.handlers { 205 if handler == h { 206 ll.handlers = append(ll.handlers[:i], ll.handlers[i+1:]...) 207 } 208 } 209 } 210 }