You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
4.4 KiB
Go
223 lines
4.4 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.StarChanStack
|
|
stackStarted bool = false
|
|
stackStopChan chan int
|
|
stackMu sync.Mutex
|
|
stdScreen io.Writer = colorable.NewColorableStdout()
|
|
errScreen io.Writer = colorable.NewColorableStderr()
|
|
)
|
|
|
|
type starlog struct {
|
|
mu *sync.Mutex
|
|
output io.Writer
|
|
errOutputLevel int
|
|
showFuncName bool
|
|
showThread bool
|
|
showLevel bool
|
|
showDeatilFile bool
|
|
showColor bool
|
|
switching bool
|
|
showStd bool
|
|
onlyColorLevel bool
|
|
stopWriter bool
|
|
id string
|
|
name string
|
|
colorList map[int][]Attr
|
|
colorMe map[int]*Color
|
|
}
|
|
|
|
type StarLogger struct {
|
|
thread string
|
|
handlerFunc func(LogData)
|
|
logcore *starlog
|
|
isStd bool
|
|
}
|
|
|
|
type logTransfer struct {
|
|
handlerFunc func(LogData)
|
|
LogData
|
|
}
|
|
|
|
type LogData struct {
|
|
Name string
|
|
Log string
|
|
Colors []Attr
|
|
}
|
|
|
|
func newLogCore(out io.Writer) *starlog {
|
|
return &starlog{
|
|
mu: &sync.Mutex{},
|
|
output: out,
|
|
errOutputLevel: LvError,
|
|
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{FgCyan},
|
|
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{FgCyan}...),
|
|
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) StdErrLevel() int {
|
|
logger.logcore.mu.Lock()
|
|
defer logger.logcore.mu.Unlock()
|
|
return logger.logcore.errOutputLevel
|
|
}
|
|
|
|
func (logger *StarLogger) SetStdErrLevel(level int) {
|
|
logger.logcore.mu.Lock()
|
|
defer logger.logcore.mu.Unlock()
|
|
logger.logcore.errOutputLevel = level
|
|
}
|
|
|
|
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 (logger *StarLogger) SetName(name string) {
|
|
logger.logcore.mu.Lock()
|
|
defer logger.logcore.mu.Unlock()
|
|
logger.logcore.name = name
|
|
}
|
|
|
|
func (logger *StarLogger) GetName() string {
|
|
return logger.logcore.name
|
|
}
|
|
|
|
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
|
|
}
|
|
unlock := make(chan struct{})
|
|
go func() {
|
|
stackStarted = true
|
|
stacks = starmap.NewStarChanStack(1024)
|
|
stackMu.Unlock()
|
|
unlock <- struct{}{}
|
|
defer func() {
|
|
stackStarted = false
|
|
}()
|
|
for {
|
|
select {
|
|
case <-stackStopChan:
|
|
return
|
|
default:
|
|
}
|
|
poped, err := stacks.Pop()
|
|
if err != nil {
|
|
return
|
|
}
|
|
val := poped.(logTransfer)
|
|
if val.handlerFunc != nil {
|
|
val.handlerFunc(val.LogData)
|
|
}
|
|
}
|
|
}()
|
|
<-unlock
|
|
}
|
|
|
|
func StopStacks() {
|
|
if !stackStarted {
|
|
return
|
|
}
|
|
stackStopChan <- 1
|
|
}
|
|
|
|
func Stop() {
|
|
stacks.Close()
|
|
StopStacks()
|
|
}
|