177 lines
3.3 KiB
Go
177 lines
3.3 KiB
Go
package log
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"sync"
|
|
|
|
goansi "github.com/k0kubun/go-ansi"
|
|
"github.com/mgutz/ansi"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
// goansi works nicer on Windows platform
|
|
var stdout = goansi.NewAnsiStdout()
|
|
var stderr = goansi.NewAnsiStderr()
|
|
|
|
type terminalLogger struct {
|
|
mutex sync.Mutex
|
|
level zapcore.Level
|
|
loadingText *loadingText
|
|
}
|
|
|
|
type levelFuncType int32
|
|
|
|
const (
|
|
fatalFn levelFuncType = iota
|
|
infoFn
|
|
errorFn
|
|
warnFn
|
|
debugFn
|
|
doneFn
|
|
)
|
|
|
|
type levelFuncInfo struct {
|
|
tag string
|
|
color string
|
|
level zapcore.Level
|
|
stream io.Writer
|
|
}
|
|
|
|
var levelFuncMap = map[levelFuncType]*levelFuncInfo{
|
|
doneFn: {
|
|
tag: "[done] √ ",
|
|
color: "green+b",
|
|
level: zapcore.InfoLevel,
|
|
stream: stdout,
|
|
},
|
|
debugFn: {
|
|
tag: "[debug] ",
|
|
color: "green+b",
|
|
level: zapcore.DebugLevel,
|
|
stream: stdout,
|
|
},
|
|
infoFn: {
|
|
tag: "[info] ",
|
|
color: "cyan+b",
|
|
level: zapcore.InfoLevel,
|
|
stream: stdout,
|
|
},
|
|
warnFn: {
|
|
tag: "[warn] ",
|
|
color: "magenta+b",
|
|
level: zapcore.WarnLevel,
|
|
stream: stdout,
|
|
},
|
|
errorFn: {
|
|
tag: "[error] ",
|
|
color: "yellow+b",
|
|
level: zapcore.ErrorLevel,
|
|
stream: stdout,
|
|
},
|
|
fatalFn: {
|
|
tag: "[fatal] ",
|
|
color: "red+b",
|
|
level: zapcore.FatalLevel,
|
|
stream: stdout,
|
|
},
|
|
}
|
|
|
|
func (t *terminalLogger) writeMessage(funcType levelFuncType, message string) {
|
|
funcInfo := levelFuncMap[funcType]
|
|
if t.level <= funcInfo.level {
|
|
// 如果当前有消息在加载,需先暂停
|
|
if t.loadingText != nil {
|
|
t.loadingText.stop()
|
|
}
|
|
|
|
funcInfo.stream.Write([]byte(ansi.Color(funcInfo.tag, funcInfo.color)))
|
|
funcInfo.stream.Write([]byte(message))
|
|
|
|
// 恢复加载
|
|
if t.loadingText != nil && funcType != fatalFn {
|
|
t.loadingText.start()
|
|
}
|
|
}
|
|
}
|
|
|
|
// StartWait prints a waiting message until StopWait is called
|
|
func (t *terminalLogger) StartWait(message string) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
// 撤销之前的加载
|
|
if t.loadingText != nil {
|
|
t.loadingText.stop()
|
|
t.loadingText = nil
|
|
}
|
|
|
|
// 创建新的加载字符串
|
|
t.loadingText = &loadingText{
|
|
message: message,
|
|
stream: goansi.NewAnsiStdout(),
|
|
}
|
|
|
|
t.loadingText.start()
|
|
}
|
|
|
|
// StopWait stops waiting
|
|
func (t *terminalLogger) StopWait() {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
if t.loadingText != nil {
|
|
t.loadingText.stop()
|
|
t.loadingText = nil
|
|
}
|
|
}
|
|
|
|
func (t *terminalLogger) Sync() {
|
|
|
|
}
|
|
|
|
func (t *terminalLogger) Debugf(format string, args ...interface{}) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
t.writeMessage(debugFn, fmt.Sprintf(format, args...)+"\n")
|
|
}
|
|
|
|
func (t *terminalLogger) Donef(format string, args ...interface{}) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
t.writeMessage(doneFn, fmt.Sprintf(format, args...)+"\n")
|
|
}
|
|
|
|
func (t *terminalLogger) Infof(format string, args ...interface{}) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
t.writeMessage(infoFn, fmt.Sprintf(format, args...)+"\n")
|
|
}
|
|
|
|
func (t *terminalLogger) Errorf(format string, args ...interface{}) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
t.writeMessage(errorFn, fmt.Sprintf(format, args...)+"\n")
|
|
}
|
|
|
|
func (t *terminalLogger) Warnf(format string, args ...interface{}) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
t.writeMessage(warnFn, fmt.Sprintf(format, args...)+"\n")
|
|
}
|
|
|
|
func (t *terminalLogger) Fatalf(format string, args ...interface{}) {
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
t.writeMessage(fatalFn, fmt.Sprintf(format, args...)+"\n")
|
|
|
|
os.Exit(1)
|
|
}
|