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.
starlog/typed.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()
}