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 }