Add API Framework Revel Source Files
[iec.git] / src / foundation / api / revel / logger / handlers.go
diff --git a/src/foundation/api/revel/logger/handlers.go b/src/foundation/api/revel/logger/handlers.go
new file mode 100644 (file)
index 0000000..dee850e
--- /dev/null
@@ -0,0 +1,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:]...)
+                       }
+               }
+       }
+}