github.com/15mga/kiwi@v0.0.2-0.20240324021231-b95d5c3ac751/log/std.go (about)

     1  package log
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/15mga/kiwi"
     6  	"io"
     7  	"os"
     8  	"strconv"
     9  	"time"
    10  
    11  	"gopkg.in/natefinch/lumberjack.v2"
    12  
    13  	"github.com/15mga/kiwi/util"
    14  )
    15  
    16  const (
    17  	_SDebug  = "[D]"
    18  	_SInfo   = "[I]"
    19  	_SWarn   = "[W]"
    20  	_SError  = "[E]"
    21  	_SFatal  = "[F]"
    22  	_STrace  = "[TC]"
    23  	_STDebug = "[TD]"
    24  	_STInfo  = "[TI]"
    25  	_STWarn  = "[TW]"
    26  	_STError = "[TE]"
    27  	_STFatal = "[TF]"
    28  )
    29  
    30  const (
    31  	ColorRed      = "\033[31m"
    32  	ColorGreen    = "\033[32m"
    33  	ColorYellow   = "\033[33m"
    34  	ColorBlue     = "\033[34m"
    35  	ColorPurple   = "\033[35m"
    36  	ColorCyan     = "\033[36m"
    37  	ColorWhite    = "\033[37m"
    38  	ColorHiRed    = "\033[91m"
    39  	ColorHiGreen  = "\033[92m"
    40  	ColorHiYellow = "\033[93m"
    41  	ColorHiBlue   = "\033[94m"
    42  	ColorHiPurple = "\033[95m"
    43  	ColorHiCyan   = "\033[96m"
    44  	ColorHiWhite  = "\033[97m"
    45  	ColorReset    = "\033[0m"
    46  )
    47  
    48  func LogLvlToStr(l kiwi.TLevel) string {
    49  	switch l {
    50  	case kiwi.TDebug:
    51  		return _SDebug
    52  	case kiwi.TInfo:
    53  		return _SInfo
    54  	case kiwi.TWarn:
    55  		return _SWarn
    56  	case kiwi.TError:
    57  		return _SError
    58  	case kiwi.TFatal:
    59  		return _SFatal
    60  	default:
    61  		return ""
    62  	}
    63  }
    64  
    65  func TraceLvlToStr(l kiwi.TLevel) string {
    66  	switch l {
    67  	case kiwi.TDebug:
    68  		return _STDebug
    69  	case kiwi.TInfo:
    70  		return _STInfo
    71  	case kiwi.TWarn:
    72  		return _STWarn
    73  	case kiwi.TError:
    74  		return _STError
    75  	case kiwi.TFatal:
    76  		return _STFatal
    77  	default:
    78  		return ""
    79  	}
    80  }
    81  
    82  type (
    83  	stdOption struct {
    84  		logLvl, traceLvl kiwi.TLevel
    85  		timeLayout       string
    86  		color            bool
    87  		writer           io.Writer
    88  	}
    89  	StdOption func(opt *stdOption)
    90  )
    91  
    92  func StdLogLvl(levels ...kiwi.TLevel) StdOption {
    93  	return func(opt *stdOption) {
    94  		opt.logLvl = kiwi.LvlToMask(levels...)
    95  	}
    96  }
    97  
    98  func StdTraceLvl(levels ...kiwi.TLevel) StdOption {
    99  	return func(opt *stdOption) {
   100  		opt.traceLvl = kiwi.LvlToMask(levels...)
   101  	}
   102  }
   103  
   104  func StdLogStrLvl(levels ...string) StdOption {
   105  	return func(opt *stdOption) {
   106  		opt.logLvl = kiwi.StrLvlToMask(levels...)
   107  	}
   108  }
   109  
   110  func StdTraceStrLvl(levels ...string) StdOption {
   111  	return func(opt *stdOption) {
   112  		opt.traceLvl = kiwi.StrLvlToMask(levels...)
   113  	}
   114  }
   115  
   116  func StdTimeLayout(layout string) StdOption {
   117  	return func(opt *stdOption) {
   118  		opt.timeLayout = layout
   119  	}
   120  }
   121  
   122  func StdWriter(writer io.Writer) StdOption {
   123  	return func(opt *stdOption) {
   124  		opt.writer = writer
   125  	}
   126  }
   127  
   128  func StdColor(color bool) StdOption {
   129  	return func(opt *stdOption) {
   130  		opt.color = color
   131  	}
   132  }
   133  
   134  func StdFile(file string) StdOption {
   135  	fmt.Println("log:", file)
   136  	return func(opt *stdOption) {
   137  		opt.writer = &lumberjack.Logger{
   138  			Filename: file,
   139  			MaxAge:   30,   //days
   140  			Compress: true, // disabled by default
   141  		}
   142  	}
   143  }
   144  
   145  func NewStd(opts ...StdOption) *stdLogger {
   146  	opt := &stdOption{
   147  		logLvl:     kiwi.LvlToMask(kiwi.TestLevels...),
   148  		traceLvl:   kiwi.LvlToMask(kiwi.TestLevels...),
   149  		timeLayout: kiwi.DefTimeFormatter,
   150  		color:      true,
   151  		writer:     os.Stdout,
   152  	}
   153  	for _, o := range opts {
   154  		o(opt)
   155  	}
   156  	f := &stdLogger{
   157  		option: opt,
   158  	}
   159  	f.headLogDebug = _SDebug
   160  	f.headLogInfo = _SInfo
   161  	f.headLogWarn = _SWarn
   162  	f.headLogError = _SError
   163  	f.headLogFatal = _SFatal
   164  	f.headSign = _STrace
   165  	f.headTraceDebug = _STDebug
   166  	f.headTraceInfo = _STInfo
   167  	f.headTraceWarn = _STWarn
   168  	f.headTraceError = _STError
   169  	f.headTraceFatal = _STFatal
   170  	f.tail = "\n"
   171  	if opt.color {
   172  		f.headLogDebug = ColorHiWhite + f.headLogDebug
   173  		f.headLogInfo = ColorHiGreen + f.headLogInfo
   174  		f.headLogWarn = ColorHiYellow + f.headLogWarn
   175  		f.headLogError = ColorHiRed + f.headLogError
   176  		f.headLogFatal = ColorHiPurple + f.headLogFatal
   177  		f.headSign = ColorCyan + f.headSign
   178  		f.headTraceDebug = ColorWhite + f.headTraceDebug
   179  		f.headTraceInfo = ColorGreen + f.headTraceInfo
   180  		f.headTraceWarn = ColorYellow + f.headTraceWarn
   181  		f.headTraceError = ColorRed + f.headTraceError
   182  		f.headTraceFatal = ColorPurple + f.headTraceFatal
   183  		f.tail = ColorReset + f.tail
   184  	}
   185  
   186  	return f
   187  }
   188  
   189  type stdLogger struct {
   190  	option         *stdOption
   191  	headLogDebug   string
   192  	headLogInfo    string
   193  	headLogWarn    string
   194  	headLogError   string
   195  	headLogFatal   string
   196  	headSign       string
   197  	headTraceDebug string
   198  	headTraceInfo  string
   199  	headTraceWarn  string
   200  	headTraceError string
   201  	headTraceFatal string
   202  	tail           string
   203  }
   204  
   205  func (l *stdLogger) getTimestamp() string {
   206  	return time.Now().Format(l.option.timeLayout)
   207  }
   208  
   209  func (l *stdLogger) Log(level kiwi.TLevel, msg, caller string, stack []byte, params util.M) {
   210  	if !util.TestMask(level, l.option.logLvl) {
   211  		return
   212  	}
   213  	var buffer util.ByteBuffer
   214  	if stack == nil {
   215  		buffer.InitCap(512)
   216  	} else {
   217  		buffer.InitCap(1024)
   218  	}
   219  	switch level {
   220  	case kiwi.TDebug:
   221  		buffer.WStringNoLen(l.headLogDebug)
   222  	case kiwi.TInfo:
   223  		buffer.WStringNoLen(l.headLogInfo)
   224  	case kiwi.TWarn:
   225  		buffer.WStringNoLen(l.headLogWarn)
   226  	case kiwi.TError:
   227  		buffer.WStringNoLen(l.headLogError)
   228  	case kiwi.TFatal:
   229  		buffer.WStringNoLen(l.headLogFatal)
   230  	}
   231  	buffer.WStringNoLen(l.getTimestamp())
   232  	if msg != "" {
   233  		buffer.WStringNoLen(" ")
   234  		buffer.WStringNoLen(msg)
   235  	}
   236  	buffer.WStringNoLen(l.tail)
   237  	ps, _ := util.JsonMarshal(params)
   238  	_, _ = buffer.Write(ps)
   239  	buffer.WStringNoLen("\n")
   240  	buffer.WStringNoLen(caller)
   241  	if stack != nil {
   242  		_, _ = buffer.Write(stack)
   243  	}
   244  	buffer.WStringNoLen("\n")
   245  	_, _ = l.option.writer.Write(buffer.All())
   246  	buffer.Dispose()
   247  }
   248  
   249  func (l *stdLogger) Trace(pid, tid int64, caller string, params util.M) {
   250  	var buffer util.ByteBuffer
   251  	buffer.InitCap(512)
   252  	buffer.WStringNoLen(l.headSign)
   253  	buffer.WStringNoLen(l.getTimestamp())
   254  	buffer.WStringNoLen(" pid:")
   255  	buffer.WStringNoLen(strconv.FormatInt(pid, 10))
   256  	buffer.WStringNoLen(" tid:")
   257  	buffer.WStringNoLen(strconv.FormatInt(tid, 10))
   258  	buffer.WStringNoLen(l.tail)
   259  	ps, _ := util.JsonMarshal(params)
   260  	_, _ = buffer.Write(ps)
   261  	buffer.WStringNoLen("\n")
   262  	buffer.WStringNoLen(caller)
   263  	buffer.WStringNoLen("\n")
   264  	_, _ = l.option.writer.Write(buffer.All())
   265  	buffer.Dispose()
   266  }
   267  
   268  func (l *stdLogger) Span(level kiwi.TLevel, tid int64, msg, caller string, stack []byte, params util.M) {
   269  	if !util.TestMask(level, l.option.traceLvl) {
   270  		return
   271  	}
   272  	var buffer util.ByteBuffer
   273  	buffer.InitCap(1024)
   274  	switch level {
   275  	case kiwi.TDebug:
   276  		buffer.WStringNoLen(l.headTraceDebug)
   277  	case kiwi.TInfo:
   278  		buffer.WStringNoLen(l.headTraceInfo)
   279  	case kiwi.TWarn:
   280  		buffer.WStringNoLen(l.headTraceWarn)
   281  	case kiwi.TError:
   282  		buffer.WStringNoLen(l.headTraceError)
   283  	case kiwi.TFatal:
   284  		buffer.WStringNoLen(l.headTraceFatal)
   285  	}
   286  	buffer.WStringNoLen(l.getTimestamp())
   287  	buffer.WStringNoLen(" tid:")
   288  	buffer.WStringNoLen(strconv.FormatInt(tid, 10))
   289  	if msg != "" {
   290  		buffer.WStringNoLen(" ")
   291  		buffer.WStringNoLen(msg)
   292  	}
   293  	buffer.WStringNoLen(l.tail)
   294  	ps, _ := util.JsonMarshal(params)
   295  	_, _ = buffer.Write(ps)
   296  	buffer.WStringNoLen("\n")
   297  	buffer.WStringNoLen(caller)
   298  	if stack != nil {
   299  		_, _ = buffer.Write(stack)
   300  	}
   301  	buffer.WStringNoLen("\n")
   302  	_, _ = l.option.writer.Write(buffer.All())
   303  	buffer.Dispose()
   304  }