ai-css/library/logger/logger.go

205 lines
5.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package logger
import (
"fmt"
"os"
"runtime"
"strings"
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
)
var (
zlog *zap.SugaredLogger
)
type LoggerConfig struct {
Filename string `mapstructure:"filename" json:"filename" yaml:"filename"`
Level string `mapstructure:"level" json:"level" yaml:"level"`
Format string `mapstructure:"format" json:"format" yaml:"format"`
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"`
Director string `mapstructure:"director" json:"director" yaml:"director"`
ShowLine bool `mapstructure:"show-line" json:"show-line" yaml:"show-line"`
EncodeLevel string `mapstructure:"encode-level" json:"encode-level" yaml:"encode-level"`
StacktraceKey string `mapstructure:"stacktrace-key" json:"stacktrace-key" yaml:"stacktrace-key"`
LogInConsole bool `mapstructure:"log-in-console" json:"log-in-console" yaml:"log-in-console"`
}
func Init(conf *LoggerConfig) {
if conf.Filename == "/dev/stdout" {
ecf := zap.NewProductionEncoderConfig()
ecf.FunctionKey = "func"
ecf.EncodeTime = zapcore.ISO8601TimeEncoder
ecf.ConsoleSeparator = " "
ecf.EncodeCaller = zapcore.ShortCallerEncoder
core := zapcore.NewCore(
zapcore.NewConsoleEncoder(ecf),
zapcore.AddSync(os.Stdout),
zap.DebugLevel,
)
zl := zap.New(core, zap.AddCallerSkip(1), zap.AddCaller())
zlog = zl.Sugar()
return
}
_, err := os.Stat(conf.Filename)
if err != nil {
if os.IsNotExist(err) {
err = os.MkdirAll(conf.Filename, os.ModePerm)
if err != nil {
panic(err)
}
} else {
fmt.Println("logger init error:", err)
}
}
if strings.LastIndex(conf.Filename, "/") != 0 {
conf.Filename = conf.Filename + "/"
}
encoder := zapcore.NewConsoleEncoder(zapcore.EncoderConfig{
MessageKey: "msg",
LevelKey: "level",
EncodeLevel: zapcore.CapitalLevelEncoder,
TimeKey: "ts",
EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02 15:04:05"))
},
CallerKey: "file",
EncodeCaller: zapcore.ShortCallerEncoder,
EncodeDuration: func(d time.Duration, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendInt64(int64(d) / 1000000)
},
})
// 实现两个判断日志等级的interface
infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.InfoLevel
})
errorLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl >= zapcore.ErrorLevel
})
// 获取 info、error日志文件的io.Writer 抽象 getWriter() 在下方实现
now := time.Now()
fileTime := now.Format("20060102") + "-" + now.Format("150405")
fileFormat := "%s%s-%s.log"
infoWriter := getWriter(fmt.Sprintf(fileFormat, conf.Filename, "info", fileTime))
errorWriter := getWriter(fmt.Sprintf(fileFormat, conf.Filename, "error", fileTime))
// 最后创建具体的Logger
core := zapcore.NewTee(
zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), infoLevel), //打印到控制台
zapcore.NewCore(encoder, infoWriter, infoLevel),
zapcore.NewCore(encoder, errorWriter, errorLevel),
)
zl := zap.New(core, zap.AddCallerSkip(1), zap.AddCaller())
zlog = zl.Sugar()
}
func GetDefault() *zap.SugaredLogger {
return zlog
}
func InitDefault() {
Init(&LoggerConfig{
Filename: "/dev/stdout",
})
}
func Sync() {
_ = zlog.Sync()
}
func getWriter(filename string) zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: filename, // 文件位置
MaxSize: 100, // 进行切割之前,日志文件的最大大小(MB为单位)
MaxAge: 10, // 保留旧文件的最大天数
MaxBackups: 3, // 保留旧文件的最大个数
Compress: false, // 是否压缩/归档旧文件
}
// AddSync 将 io.Writer 转换为 WriteSyncer。
// 它试图变得智能:如果 io.Writer 的具体类型实现了 WriteSyncer我们将使用现有的 Sync 方法。
// 如果没有,我们将添加一个无操作同步。
return zapcore.AddSync(lumberJackLogger)
}
func Debug(args ...interface{}) {
zlog.Debug(args...)
}
func Debugf(template string, args ...interface{}) {
zlog.Debugf(template, args...)
}
func Info(args ...interface{}) {
zlog.Info(args...)
}
func Infof(template string, args ...interface{}) {
zlog.Infof(template, args...)
}
func Warn(args ...interface{}) {
zlog.Warn(args...)
}
func Warnf(template string, args ...interface{}) {
zlog.Warnf(template, args...)
}
func Error(args ...interface{}) {
zlog.Error(args...)
}
func Errorf(template string, args ...interface{}) {
zlog.Errorf(template, args...)
}
func DPanic(args ...interface{}) {
zlog.DPanic(args...)
}
func DPanicf(template string, args ...interface{}) {
zlog.DPanicf(template, args...)
}
func Panic(args ...interface{}) {
zlog.Panic(args...)
}
func Panicf(template string, args ...interface{}) {
zlog.Panicf(template, args...)
}
func Fatal(args ...interface{}) {
zlog.Fatal(args...)
}
func Fatalf(template string, args ...interface{}) {
zlog.Fatalf(template, args...)
}
func SafeGoroutine(fn func()) {
go func() {
defer func() {
if r := recover(); r != nil {
buf := make([]byte, 1<<16) // 64KB
stackSize := runtime.Stack(buf, false)
msg := fmt.Sprintf("panic: %v\n%s\n", r, buf[:stackSize])
Errorf(msg)
}
}()
fn()
}()
}