--- /dev/null
+package logger
+
+import (
+ "fmt"
+ "github.com/revel/config"
+ "time"
+)
+
+// The LogHandler defines the interface to handle the log records
+type (
+ // The Multilogger reduces the number of exposed defined logging variables,
+ // and allows the output to be easily refined
+ MultiLogger interface {
+ // New returns a new Logger that has this logger's context plus the given context
+ New(ctx ...interface{}) MultiLogger
+
+ // SetHandler updates the logger to write records to the specified handler.
+ SetHandler(h LogHandler)
+
+ // Set the stack depth for the logger
+ SetStackDepth(int) MultiLogger
+
+ // Log a message at the given level with context key/value pairs
+ Debug(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters
+ Debugf(msg string, params ...interface{})
+
+ // Log a message at the given level with context key/value pairs
+ Info(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters
+ Infof(msg string, params ...interface{})
+
+ // Log a message at the given level with context key/value pairs
+ Warn(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters
+ Warnf(msg string, params ...interface{})
+
+ // Log a message at the given level with context key/value pairs
+ Error(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters
+ Errorf(msg string, params ...interface{})
+
+ // Log a message at the given level with context key/value pairs
+ Crit(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters
+ Critf(msg string, params ...interface{})
+
+ // Log a message at the given level with context key/value pairs and exits
+ Fatal(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters and exits
+ Fatalf(msg string, params ...interface{})
+
+ // Log a message at the given level with context key/value pairs and panics
+ Panic(msg string, ctx ...interface{})
+
+ // Log a message at the given level formatting message with the parameters and panics
+ Panicf(msg string, params ...interface{})
+ }
+
+ // The log handler interface
+ LogHandler interface {
+ Log(*Record) error
+ //log15.Handler
+ }
+
+ // The log stack handler interface
+ LogStackHandler interface {
+ LogHandler
+ GetStack() int
+ }
+
+ // The log handler interface which has child logs
+ ParentLogHandler interface {
+ SetChild(handler LogHandler) LogHandler
+ }
+
+ // The log format interface
+ LogFormat interface {
+ Format(r *Record) []byte
+ }
+
+ // The log level type
+ LogLevel int
+
+ // Used for the callback to LogFunctionMap
+ LogOptions struct {
+ Ctx *config.Context
+ ReplaceExistingHandler bool
+ HandlerWrap ParentLogHandler
+ Levels []LogLevel
+ ExtendedOptions map[string]interface{}
+ }
+
+ // The log record
+ Record struct {
+ Message string // The message
+ Time time.Time // The time
+ Level LogLevel //The level
+ Call CallStack // The call stack if built
+ Context ContextMap // The context
+ }
+
+ // The lazy structure to implement a function to be invoked only if needed
+ Lazy struct {
+ Fn interface{} // the function
+ }
+
+ // Currently the only requirement for the callstack is to support the Formatter method
+ // which stack.Call does so we use that
+ CallStack interface {
+ fmt.Formatter // Requirement
+ }
+)
+
+// FormatFunc returns a new Format object which uses
+// the given function to perform record formatting.
+func FormatFunc(f func(*Record) []byte) LogFormat {
+ return formatFunc(f)
+}
+
+type formatFunc func(*Record) []byte
+
+func (f formatFunc) Format(r *Record) []byte {
+ return f(r)
+}
+func NewRecord(message string, level LogLevel) *Record {
+ return &Record{Message: message, Context: ContextMap{}, Level: level}
+}
+
+const (
+ LvlCrit LogLevel = iota // Critical
+ LvlError // Error
+ LvlWarn // Warning
+ LvlInfo // Information
+ LvlDebug // Debug
+)
+
+// A list of all the log levels
+var LvlAllList = []LogLevel{LvlDebug, LvlInfo, LvlWarn, LvlError, LvlCrit}
+
+// Implements the ParentLogHandler
+type parentLogHandler struct {
+ setChild func(handler LogHandler) LogHandler
+}
+
+// Create a new parent log handler
+func NewParentLogHandler(callBack func(child LogHandler) LogHandler) ParentLogHandler {
+ return &parentLogHandler{callBack}
+}
+
+// Sets the child of the log handler
+func (p *parentLogHandler) SetChild(child LogHandler) LogHandler {
+ return p.setChild(child)
+}
+
+// Create a new log options
+func NewLogOptions(cfg *config.Context, replaceHandler bool, phandler ParentLogHandler, lvl ...LogLevel) (logOptions *LogOptions) {
+ logOptions = &LogOptions{
+ Ctx: cfg,
+ ReplaceExistingHandler: replaceHandler,
+ HandlerWrap: phandler,
+ Levels: lvl,
+ ExtendedOptions: map[string]interface{}{},
+ }
+ return
+}
+
+// Assumes options will be an even number and have a string, value syntax
+func (l *LogOptions) SetExtendedOptions(options ...interface{}) {
+ for x := 0; x < len(options); x += 2 {
+ l.ExtendedOptions[options[x].(string)] = options[x+1]
+ }
+}
+
+// Gets a string option with default
+func (l *LogOptions) GetStringDefault(option, value string) string {
+ if v, found := l.ExtendedOptions[option]; found {
+ return v.(string)
+ }
+ return value
+}
+
+// Gets an int option with default
+func (l *LogOptions) GetIntDefault(option string, value int) int {
+ if v, found := l.ExtendedOptions[option]; found {
+ return v.(int)
+ }
+ return value
+}
+
+// Gets a boolean option with default
+func (l *LogOptions) GetBoolDefault(option string, value bool) bool {
+ if v, found := l.ExtendedOptions[option]; found {
+ return v.(bool)
+ }
+ return value
+}