package starlog import ( "fmt" "io" "math/rand" "sync" "time" "b612.me/starlog/colorable" "b612.me/starmap" ) const ( LvDebug = iota LvInfo LvNotice LvWarning LvError LvCritical LvPanic LvFatal ) var ( levels = map[int]string{ LvDebug: "DEBUG", LvInfo: "INFO", LvNotice: "NOTICE", LvWarning: "WARNING", LvError: "ERROR", LvCritical: "CRITICAL", LvPanic: "PANIC", LvFatal: "FATAL", } stacks starmap.StarStack stackStarted bool = false stackStopChan chan int stackMu sync.Mutex stdScreen io.Writer = colorable.NewColorableStdout() ) type starlog struct { mu *sync.Mutex output io.Writer showFuncName bool showThread bool showLevel bool showDeatilFile bool showColor bool switching bool showStd bool onlyColorLevel bool stopWriter bool id string colorList map[int][]Attr colorMe map[int]*Color } type StarLogger struct { thread string handlerFunc func([]Attr, string) logcore *starlog isStd bool } type logTransfer struct { handlerFunc func([]Attr, string) colors []Attr logStr string } func newLogCore(out io.Writer) *starlog { return &starlog{ mu: &sync.Mutex{}, output: out, showFuncName: true, showThread: true, showLevel: true, showStd: true, showDeatilFile: true, switching: false, stopWriter: false, showColor: true, id: generateId(), colorList: map[int][]Attr{ LvDebug: []Attr{FgWhite}, LvInfo: []Attr{FgGreen}, LvNotice: []Attr{FgBlue}, LvWarning: []Attr{FgYellow}, LvError: []Attr{FgMagenta}, LvCritical: []Attr{FgRed, Bold}, LvPanic: []Attr{FgRed, Bold}, LvFatal: []Attr{FgRed}, }, colorMe: map[int]*Color{ LvDebug: NewColor([]Attr{FgWhite}...), LvInfo: NewColor([]Attr{FgGreen}...), LvNotice: NewColor([]Attr{FgBlue}...), LvWarning: NewColor([]Attr{FgYellow}...), LvError: NewColor([]Attr{FgMagenta}...), LvCritical: NewColor([]Attr{FgRed, Bold}...), LvPanic: NewColor([]Attr{FgRed, Bold}...), LvFatal: NewColor([]Attr{FgRed}...), }, } } func NewStarlog(out io.Writer) *StarLogger { return &StarLogger{ handlerFunc: nil, thread: "MAN", logcore: newLogCore(out), isStd: false, } } func (logger *StarLogger) NewFlag() *StarLogger { return &StarLogger{ thread: getRandomFlag(false), handlerFunc: logger.handlerFunc, logcore: logger.logcore, isStd: false, } } func (logger *StarLogger) SetNewRandomFlag() { logger.thread = getRandomFlag(false) } func getRandomFlag(isMain bool) string { rand.Seed(time.Now().UnixNano()) if isMain { return "MAN" } flag := "MAN" for flag == "MAN" { flag = string([]byte{uint8(rand.Intn(26) + 65), uint8(rand.Intn(26) + 65), uint8(rand.Intn(26) + 65)}) } return flag } func generateId() string { rand.Seed(time.Now().UnixNano()) return fmt.Sprintf("%dstar%db612%d", time.Now().UnixNano(), rand.Intn(1000000), rand.Intn(1000000)) } func StartStacks() { stackMu.Lock() if stackStarted { stackMu.Unlock() return } go func() { stackStarted = true stackMu.Unlock() defer func() { stackStarted = false }() for { select { case <-stackStopChan: return default: } poped := stacks.MustPop() if poped == nil { time.Sleep(time.Millisecond * 10) continue } val := poped.(logTransfer) if val.handlerFunc != nil { val.handlerFunc(val.colors, val.logStr) } } }() } func StopStacks() { if !stackStarted { return } stackStopChan <- 1 } func Stop() { StopStacks() }