github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/goutils/logger/impl.go (about) 1 /* 2 * Copyright (c) 2020-present unTill Pro, Ltd. 3 * @author Maxim Geraskin 4 * 5 * This source code is licensed under the MIT license found in the 6 * LICENSE file in the root directory of this source tree. 7 */ 8 9 package logger 10 11 import ( 12 "fmt" 13 "runtime" 14 "strings" 15 "sync/atomic" 16 ) 17 18 const ( 19 globalSkipStackFramesCount = 4 20 ) 21 22 const ( 23 errorPrefix = "*****" 24 warningPrefix = "!!!" 25 infoPrefix = "===" 26 verbosePrefix = "---" 27 tracePrefix = "..." 28 ) 29 30 var globalLogPrinter = logPrinter{logLevel: LogLevelInfo} 31 32 type logPrinter struct { 33 logLevel TLogLevel 34 } 35 36 func isEnabled(logLevel TLogLevel) bool { 37 curLogLevel := TLogLevel(atomic.LoadInt32((*int32)(&globalLogPrinter.logLevel))) 38 return curLogLevel >= logLevel 39 } 40 41 func (p *logPrinter) getFuncName(skipCount int) (funcName string, line int) { 42 var fn string 43 pc, _, line, ok := runtime.Caller(skipCount) 44 details := runtime.FuncForPC(pc) 45 if ok && details != nil { 46 elems := strings.Split(details.Name(), "/") 47 if len(elems) > 0 { 48 fn = elems[len(elems)-1] 49 } 50 } 51 return fn, line 52 } 53 54 func (p *logPrinter) getFormattedMsg(msgType string, funcName string, line int, args ...interface{}) string { 55 out := "01/02 15:04:05.000" 56 out += ": " + msgType 57 out += fmt.Sprintf(": [%v:%v]:", funcName, line) 58 if len(args) > 0 { 59 var s string 60 for _, arg := range args { 61 s += fmt.Sprint(" ", arg) 62 } 63 out += s 64 } 65 return out 66 } 67 68 func (p *logPrinter) print(skipStackFrames int, level TLogLevel, msgType string, args ...interface{}) { 69 funcName, line := p.getFuncName(skipStackFrames + globalSkipStackFramesCount) 70 out := p.getFormattedMsg(msgType, funcName, line, args...) 71 72 PrintLine(level, out) 73 } 74 75 func getLevelPrefix(level TLogLevel) string { 76 switch level { 77 case LogLevelError: 78 return errorPrefix 79 case LogLevelWarning: 80 return warningPrefix 81 case LogLevelInfo: 82 return infoPrefix 83 case LogLevelVerbose: 84 return verbosePrefix 85 case LogLevelTrace: 86 return tracePrefix 87 } 88 return "" 89 } 90 91 func printIfLevel(skipStackFrames int, level TLogLevel, args ...interface{}) { 92 if isEnabled(level) { 93 globalLogPrinter.print(skipStackFrames, level, getLevelPrefix(level), args...) 94 } 95 }