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/starlog.go

490 lines
10 KiB
Go

package starlog
import (
"fmt"
"io"
"os"
"path/filepath"
"runtime"
"strconv"
"sync"
"time"
"github.com/mattn/go-colorable"
)
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",
}
Colors = 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},
}
)
type StarLogger struct {
mu sync.Mutex
lock sync.Mutex
out io.Writer
ShowLine bool
ShowLevel bool
DoWrite bool
DoShow bool
switching bool
//HandleFunc
waiting chan int
outshow io.Writer
LogLevel int
HandleFunc func([]Attr, string)
StdFuncColor bool
}
var Std = New(nil)
func init() {
Std.DoShow = true
}
func New(out io.Writer) *StarLogger {
logger := new(StarLogger)
logger.DoShow = false
logger.ShowLevel = true
logger.ShowLine = true
logger.DoWrite = true
logger.out = out
logger.outshow = colorable.NewColorableStdout()
logger.StdFuncColor = true
return logger
}
func (logger *StarLogger) write(logstr string) {
if (!logger.DoWrite) || (logger.out == nil) {
return
}
i := 0
for logger.switching {
time.Sleep(time.Millisecond * 100)
i++
if i > 20 {
return
}
}
if &(logger.out) == nil {
return
}
logger.out.Write([]byte(logstr))
}
func (logger *StarLogger) OutPut(logstr string) {
logger.out.Write([]byte(logstr))
}
func (logger *StarLogger) output(level int, logstr string) {
var logs string
logger.mu.Lock()
defer logger.mu.Unlock()
if level < logger.LogLevel {
return
}
_, fname, line, _ := runtime.Caller(3)
fname = filepath.Base(fname)
date := time.Now().Format("2006-01-02 15:04:05.000 Mon")
if logger.ShowLine && logger.ShowLevel {
logs = fmt.Sprintf("%s %s %s %s", date, fname+":"+strconv.Itoa(line), `[`+levels[level]+`]`, logstr)
} else if logger.ShowLine && !logger.ShowLevel {
logs = fmt.Sprintf("%s %s %s", date, fname+":"+strconv.Itoa(line), logstr)
} else if !logger.ShowLine && logger.ShowLevel {
logs = fmt.Sprintf("%s %s %s", date, `[`+levels[level]+`]`, logstr)
} else {
logs = fmt.Sprintf("%s %s", date, logstr)
}
if logger.DoShow {
logcolor := NewColor(Colors[level]...)
logcolor.Fprint(logger.outshow, logs)
}
if logger.HandleFunc != nil {
go logger.HandleFunc(Colors[level], logs)
}
if logger.DoWrite {
logger.write(logs)
}
}
func (logger *StarLogger) Debug(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvDebug, strs)
}
func Debug(str ...interface{}) {
Std.Debug(str...)
}
func (logger *StarLogger) Debugf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvDebug, strs)
}
func Debugf(format string, str ...interface{}) {
Std.Debugf(format, str...)
}
func (logger *StarLogger) Debugln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvDebug, strs)
}
func Debugln(str ...interface{}) {
Std.Debugln(str...)
}
func (logger *StarLogger) Info(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvInfo, strs)
}
func Info(str ...interface{}) {
Std.Info(str...)
}
func (logger *StarLogger) Infof(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvInfo, strs)
}
func Infof(format string, str ...interface{}) {
Std.Infof(format, str...)
}
func (logger *StarLogger) Infoln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvInfo, strs)
}
func Infoln(str ...interface{}) {
Std.Infoln(str...)
}
func (logger *StarLogger) Notice(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvNotice, strs)
}
func Notice(str ...interface{}) {
Std.Notice(str...)
}
func (logger *StarLogger) Noticef(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvNotice, strs)
}
func Noticef(format string, str ...interface{}) {
Std.Noticef(format, str...)
}
func (logger *StarLogger) Noticeln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvNotice, strs)
}
func Noticeln(str ...interface{}) {
Std.Noticeln(str...)
}
func (logger *StarLogger) Warning(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvWarning, strs)
}
func Warning(str ...interface{}) {
Std.Warning(str...)
}
func (logger *StarLogger) Warningf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvWarning, strs)
}
func Warningf(format string, str ...interface{}) {
Std.Warningf(format, str...)
}
func (logger *StarLogger) Warningln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvWarning, strs)
}
func Warningln(str ...interface{}) {
Std.Warningln(str...)
}
func (logger *StarLogger) Error(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvError, strs)
}
func Error(str ...interface{}) {
Std.Error(str...)
}
func (logger *StarLogger) Errorf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvError, strs)
}
func Errorf(format string, str ...interface{}) {
Std.Errorf(format, str...)
}
func (logger *StarLogger) Errorln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvError, strs)
}
func Errorln(str ...interface{}) {
Std.Errorln(str...)
}
func (logger *StarLogger) Critical(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvCritical, strs)
}
func Critical(str ...interface{}) {
Std.Critical(str...)
}
func (logger *StarLogger) Criticalf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvCritical, strs)
}
func Criticalf(format string, str ...interface{}) {
Std.Criticalf(format, str...)
}
func (logger *StarLogger) Criticalln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvCritical, strs)
}
func Criticalln(str ...interface{}) {
Std.Criticalln(str...)
}
func (logger *StarLogger) Fatal(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvFatal, strs)
os.Exit(9)
}
func Fatal(str ...interface{}) {
Std.Fatal(str...)
}
func (logger *StarLogger) Fatalf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvFatal, strs)
os.Exit(9)
}
func Fatalf(format string, str ...interface{}) {
Std.Fatalf(format, str...)
}
func (logger *StarLogger) Fatalln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvFatal, strs)
os.Exit(9)
}
func Fatalln(str ...interface{}) {
Std.Fatalln(str...)
}
func (logger *StarLogger) Panic(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.output(LvPanic, strs)
panic(str)
}
func Panic(str ...interface{}) {
Std.Panic(str...)
}
func (logger *StarLogger) Panicf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.output(LvPanic, strs)
panic(fmt.Sprintf(format, str...))
}
func Panicf(format string, str ...interface{}) {
Std.Panicf(format, str...)
}
func (logger *StarLogger) Panicln(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.output(LvPanic, strs)
panic(fmt.Sprintln(str...))
}
func Panicln(str ...interface{}) {
Std.Panicln(str...)
}
func (logger *StarLogger) Print(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprint(str...)
logger.OutPut(strs)
}
func Print(str ...interface{}) {
Std.Print(str...)
}
func (logger *StarLogger) Printf(format string, str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintf(format, str...)
logger.OutPut(strs)
}
func Printf(format string, str ...interface{}) {
Std.Printf(format, str...)
}
func (logger *StarLogger) Println(str ...interface{}) {
logger.lock.Lock()
defer logger.lock.Unlock()
strs := fmt.Sprintln(str...)
logger.OutPut(strs)
}
func Println(str ...interface{}) {
Std.Println(str...)
}
func StdPrint(c []Attr, str ...interface{}) {
Std.lock.Lock()
defer Std.lock.Unlock()
colorstr := NewColor(c...)
colorstr.Print(str...)
if Std.StdFuncColor && Std.HandleFunc != nil {
go Std.HandleFunc(c, fmt.Sprint(str...))
}
}
func StdPrintf(c []Attr, format string, str ...interface{}) {
Std.lock.Lock()
defer Std.lock.Unlock()
colorstr := NewColor(c...)
colorstr.Printf(format, str...)
if Std.StdFuncColor && Std.HandleFunc != nil {
go Std.HandleFunc(c, fmt.Sprintf(format, str...))
}
}
func StdPrintln(c []Attr, str ...interface{}) {
Std.lock.Lock()
defer Std.lock.Unlock()
colorstr := NewColor(c...)
colorstr.Println(str...)
if Std.StdFuncColor && Std.HandleFunc != nil {
go Std.HandleFunc(c, fmt.Sprintln(str...))
}
}
func (logger *StarLogger) SwitchOut(out io.Writer) {
logger.lock.Lock()
defer logger.lock.Unlock()
logger.switching = true
logger.out = out
logger.switching = false
}
func SetLogFile(path string) error {
var err error
Std.out, err = os.Create(path)
Std.switching = false
return err
}
func SwitchFile(path string) error {
Std.switching = true
return SetLogFile(path)
}