github.com/jd-ly/cmd@v1.0.10/logger/revel_logger.go (about)

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