github.com/wiselike/revel-cmd@v1.2.1/logger/revel_logger.go (about)

     1  package logger
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  
     8  	"github.com/revel/log15"
     9  )
    10  
    11  // This type implements the MultiLogger.
    12  type RevelLogger struct {
    13  	log15.Logger
    14  }
    15  
    16  // Set the systems default logger
    17  // Default logs will be captured and handled by revel at level info.
    18  func SetDefaultLog(fromLog MultiLogger) {
    19  	log.SetOutput(loggerRewrite{Logger: fromLog, Level: log15.LvlInfo, hideDeprecated: true})
    20  	// No need to show date and time, that will be logged with revel
    21  	log.SetFlags(0)
    22  }
    23  
    24  func (rl *RevelLogger) Debugf(msg string, param ...interface{}) {
    25  	rl.Debug(fmt.Sprintf(msg, param...))
    26  }
    27  
    28  // Print a formatted info message.
    29  func (rl *RevelLogger) Infof(msg string, param ...interface{}) {
    30  	rl.Info(fmt.Sprintf(msg, param...))
    31  }
    32  
    33  // Print a formatted warn message.
    34  func (rl *RevelLogger) Warnf(msg string, param ...interface{}) {
    35  	rl.Warn(fmt.Sprintf(msg, param...))
    36  }
    37  
    38  // Print a formatted error message.
    39  func (rl *RevelLogger) Errorf(msg string, param ...interface{}) {
    40  	rl.Error(fmt.Sprintf(msg, param...))
    41  }
    42  
    43  // Print a formatted critical message.
    44  func (rl *RevelLogger) Critf(msg string, param ...interface{}) {
    45  	rl.Crit(fmt.Sprintf(msg, param...))
    46  }
    47  
    48  // Print a formatted fatal message.
    49  func (rl *RevelLogger) Fatalf(msg string, param ...interface{}) {
    50  	rl.Fatal(fmt.Sprintf(msg, param...))
    51  }
    52  
    53  // Print a formatted panic message.
    54  func (rl *RevelLogger) Panicf(msg string, param ...interface{}) {
    55  	rl.Panic(fmt.Sprintf(msg, param...))
    56  }
    57  
    58  // Print a critical message and call os.Exit(1).
    59  func (rl *RevelLogger) Fatal(msg string, ctx ...interface{}) {
    60  	rl.Crit(msg, ctx...)
    61  	os.Exit(1)
    62  }
    63  
    64  // Print a critical message and panic.
    65  func (rl *RevelLogger) Panic(msg string, ctx ...interface{}) {
    66  	rl.Crit(msg, ctx...)
    67  	panic(msg)
    68  }
    69  
    70  // Override log15 method.
    71  func (rl *RevelLogger) New(ctx ...interface{}) MultiLogger {
    72  	old := &RevelLogger{Logger: rl.Logger.New(ctx...)}
    73  	return old
    74  }
    75  
    76  // Set the stack level to check for the caller.
    77  func (rl *RevelLogger) SetStackDepth(amount int) MultiLogger {
    78  	rl.Logger.SetStackDepth(amount) // Ignore the logger returned
    79  	return rl
    80  }
    81  
    82  // Create a new logger.
    83  func New(ctx ...interface{}) MultiLogger {
    84  	r := &RevelLogger{Logger: log15.New(ctx...)}
    85  	r.SetStackDepth(0)
    86  	return r
    87  }
    88  
    89  // Set the handler in the Logger.
    90  func (rl *RevelLogger) SetHandler(h LogHandler) {
    91  	rl.Logger.SetHandler(callHandler(h.Log))
    92  }
    93  
    94  // The function wrapper to implement the callback.
    95  type callHandler func(r *Record) error
    96  
    97  // Log implementation, reads the record and extracts the details from the log record
    98  // Hiding the implementation.
    99  func (c callHandler) Log(log *log15.Record) error {
   100  	ctx := log.Ctx
   101  	var ctxMap ContextMap
   102  	if len(ctx) > 0 {
   103  		ctxMap = make(ContextMap, len(ctx)/2)
   104  
   105  		for i := 0; i < len(ctx); i += 2 {
   106  			v := ctx[i]
   107  			key, ok := v.(string)
   108  			if !ok {
   109  				key = fmt.Sprintf("LOGGER_INVALID_KEY %v", v)
   110  			}
   111  			var value interface{}
   112  			if len(ctx) > i+1 {
   113  				value = ctx[i+1]
   114  			} else {
   115  				value = "LOGGER_VALUE_MISSING"
   116  			}
   117  			ctxMap[key] = value
   118  		}
   119  	} else {
   120  		ctxMap = make(ContextMap)
   121  	}
   122  	r := &Record{Message: log.Msg, Context: ctxMap, Time: log.Time, Level: LogLevel(log.Lvl), Call: CallStack(log.Call)}
   123  	return c(r)
   124  }
   125  
   126  // Internally used contextMap, allows conversion of map to map[string]string.
   127  type ContextMap map[string]interface{}
   128  
   129  // Convert the context map to be string only values, any non string values are ignored.
   130  func (m ContextMap) StringMap() (newMap map[string]string) {
   131  	if m != nil {
   132  		newMap = map[string]string{}
   133  		for key, value := range m {
   134  			if svalue, isstring := value.(string); isstring {
   135  				newMap[key] = svalue
   136  			}
   137  		}
   138  	}
   139  	return
   140  }
   141  
   142  func (m ContextMap) Add(key string, value interface{}) {
   143  	m[key] = value
   144  }