185 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | |
| }
 |