代码拉取完成,页面将自动刷新
package log
import (
"context"
"fmt"
. "gitee.com/kristas/booting-go/framework/common/util/console"
"gitee.com/kristas/booting-go/framework/common/util/lang"
"path"
"runtime"
"strconv"
"strings"
"sync"
"time"
)
const (
maximumCallerDepth int = 6
DefaultDepth int = 4
)
type LoggerFacade struct {
Ctx context.Context
frame *runtime.Frame
lvl Level
Logger LoggerAdapter
Conf *Configure
depth int
callerInitOnce sync.Once
minimumCallerDepth int
loggerPackage string
}
func New(logger LoggerAdapter, conf *Configure, depth int) (Logger, error) {
l := &LoggerFacade{
Logger: logger,
Conf: conf,
depth: depth,
}
return l, nil
}
func (l *LoggerFacade) Context(ctx context.Context) Logger {
l.Ctx = ctx
return l
}
func (l *LoggerFacade) Trace(format string, a ...interface{}) {
l.lvl = Trace
l.Logger.Trace(l.build(format, a...))
}
func (l *LoggerFacade) Debug(format string, a ...interface{}) {
l.lvl = Debug
l.Logger.Debug(l.build(format, a...))
}
func (l *LoggerFacade) Info(format string, a ...interface{}) {
l.lvl = Info
l.Logger.Info(l.build(format, a...))
}
func (l *LoggerFacade) Warn(format string, a ...interface{}) {
l.lvl = Warn
l.Logger.Warn(l.build(format, a...))
}
func (l *LoggerFacade) Error(format string, a ...interface{}) {
l.lvl = Error
l.Logger.Error(l.build(format, a...))
}
func (l *LoggerFacade) Panic(format string, a ...interface{}) {
l.lvl = Panic
l.Logger.Panic(l.build(format, a...))
}
func (l *LoggerFacade) Fatal(format string, a ...interface{}) {
l.lvl = Fatal
l.Logger.Fatal(l.build(format, a...))
}
type parser func(spec *Spec) string
func (l *LoggerFacade) build(format string, a ...interface{}) string {
l.frame = l.getCaller()
if l.frame == nil {
return ""
}
spec := l.Conf.Style.Spec
s := lang.NewEmptyString()
for _, tmp := range l.Conf.Style.Template {
s = s.Concat(l.styleParser(tmp)(spec[tmp]))
}
message := fmt.Sprintf(format, a...)
return s.Format(message).String()
}
func (l *LoggerFacade) styleParser(template string) parser {
switch template {
case timestamp:
return l.parseTimestamp
case level:
return l.parseLevel
case function:
return l.parseFunction
case location:
return l.parseLocation
case separator:
return l.parseSeparator
case message:
return l.parseMessage
default:
return func(spec *Spec) string {
return ""
}
}
}
func (l *LoggerFacade) parseTimestamp(spec *Spec) string {
now := time.Now()
return Draw(spec.Color, now.Format(spec.Layout))
}
func (l *LoggerFacade) parseLevel(spec *Spec) string {
switch l.lvl {
case Trace:
return Drawf(BlueBold, spec.Layout, l.lvl.String())
case Debug:
return Drawf(CyanBold, spec.Layout, l.lvl.String())
case Info:
return Drawf(GreenBold, spec.Layout, l.lvl.String())
case Warn:
return Drawf(YellowBold, spec.Layout, l.lvl.String())
case Error:
return Drawf(RedBold, spec.Layout, l.lvl.String())
case Fatal:
return Drawf(RedBold, spec.Layout, l.lvl.String())
case Panic:
return Drawf(RedBold, spec.Layout, l.lvl.String())
}
return ""
}
func (l *LoggerFacade) parseFunction(spec *Spec) string {
fc := l.packageParser(l.frame.Function)
return Draw(spec.Color, lang.NewString(spec.Layout).Format(fc).String())
}
func (l *LoggerFacade) parseLocation(spec *Spec) string {
dir, file := path.Split(l.frame.File)
line := strconv.Itoa(l.frame.Line)
return Draw(spec.Color, lang.NewString(spec.Layout).
ReplaceAll("dir", dir).
ReplaceAll("file", file).
ReplaceAll("line", line).String())
}
func (l *LoggerFacade) parseSeparator(spec *Spec) string {
return Draw(spec.Color, spec.Layout)
}
func (l *LoggerFacade) parseMessage(spec *Spec) string {
return Draw(spec.Color, spec.Layout)
}
func (l *LoggerFacade) packageParser(pkg string) string {
split := lang.NewString(pkg).ReplaceAll("/", ".").Split(".")
pkgArr := lang.TransferSliceToSimple(split)
var tmp []string
skipIndex := l.Conf.SkipIndex
for i, s := range pkgArr {
if i < skipIndex {
tmp = append(tmp, s[:1])
} else {
tmp = append(tmp, s)
}
}
return strings.Join(tmp, ".")
}
func (l *LoggerFacade) getCaller() *runtime.Frame {
l.callerInitOnce.Do(func() {
pcs := make([]uintptr, maximumCallerDepth)
_ = runtime.Callers(0, pcs)
for i := 0; i < maximumCallerDepth; i++ {
funcName := runtime.FuncForPC(pcs[i]).Name()
if strings.Contains(funcName, "getCaller") {
l.loggerPackage = getPackageName(funcName)
break
}
}
l.minimumCallerDepth = l.depth
})
pcs := make([]uintptr, maximumCallerDepth)
depth := runtime.Callers(l.minimumCallerDepth, pcs)
frames := runtime.CallersFrames(pcs[:depth])
for f, again := frames.Next(); again; f, again = frames.Next() {
pkg := getPackageName(f.Function)
if pkg != l.loggerPackage {
return &f //nolint:scopelint
}
}
return nil
}
func getPackageName(f string) string {
for {
lastPeriod := strings.LastIndex(f, ".")
lastSlash := strings.LastIndex(f, "/")
if lastPeriod > lastSlash {
f = f[:lastPeriod]
} else {
break
}
}
return f
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。