| | |
| | | package logger |
| | | |
| | | import ( |
| | | "fmt" |
| | | "log" |
| | | "github.com/natefinch/lumberjack" |
| | | "go.uber.org/zap" |
| | | "go.uber.org/zap/zapcore" |
| | | "os" |
| | | "os/exec" |
| | | "strings" |
| | | "time" |
| | | ) |
| | | |
| | | type BLog struct { |
| | | logger *zap.SugaredLogger |
| | | } |
| | | |
| | | func (l *BLog) Write(buf []byte) (n int, err error) { |
| | | l.logger.Debug(strings.Replace(string(buf),"\n","", -1)) |
| | | return len(buf),nil |
| | | } |
| | | |
| | | func GetLogFile() *BLog { |
| | | return blog |
| | | } |
| | | |
| | | var blog *BLog |
| | | |
| | | const ( |
| | | PanicLevel int = iota |
| | | FatalLevel |
| | | ErrorLevel |
| | | WarnLevel |
| | | DebugLevel = iota -1 |
| | | InfoLevel |
| | | DebugLevel |
| | | WarnLevel |
| | | ErrorLevel |
| | | DPanicLevel |
| | | PanicLevel |
| | | FatalLevel |
| | | ) |
| | | |
| | | const ( |
| | | color_red = uint8(iota + 91) |
| | | color_green // 绿 |
| | | color_yellow // 黄 |
| | | color_blue // 蓝 |
| | | color_magenta // 洋红 |
| | | ) |
| | | |
| | | const ( |
| | | fatalPrefix = "[FATAL] " |
| | | errorPrefix = "[ERROR] " |
| | | warnPrefix = "[WARN] " |
| | | infoPrefix = "[INFO] " |
| | | debugPrefix = "[DEBUG] " |
| | | ) |
| | | |
| | | const ( |
| | | ByDay int = iota |
| | | ByWeek |
| | | ByMonth |
| | | BySize |
| | | ) |
| | | |
| | | type LogFile struct { |
| | | level int // 日志等级 |
| | | saveMode int // 保存模式 |
| | | saveDays int // 日志保存天数 |
| | | logTime int64 // |
| | | fileName string // 日志文件名 |
| | | filesize int64 // 文件大小, 需要设置 saveMode 为 BySize 生效 |
| | | fileFd *os.File |
| | | } |
| | | |
| | | var logFile LogFile |
| | | |
| | | func init() { |
| | | //logFile.logTime = time.Now().Unix() |
| | | logFile.saveMode = ByDay // 默认按天保存 |
| | | logFile.saveDays = 15 // 默认保存三天的 |
| | | logFile.level = ErrorLevel |
| | | logFile.filesize = 1024 * 1024 * 10 // 默认10M, 需要设置 saveMode 为 BySize |
| | | } |
| | | |
| | | func Config(logFolder string, level int) { |
| | | logFile.fileName = logFolder |
| | | logFile.level = level |
| | | |
| | | log.SetOutput(logFile) |
| | | //log.SetFlags(log.Lmicroseconds | log.Lshortfile) |
| | | log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) |
| | | } |
| | | func GetLogFile() (*LogFile) { |
| | | return &logFile |
| | | } |
| | | |
| | | func SetLevel(level int) { |
| | | logFile.level = level |
| | | } |
| | | |
| | | func SetSaveMode(saveMode int) { |
| | | logFile.saveMode = saveMode |
| | | } |
| | | |
| | | func SetSaveDays(saveDays int) { |
| | | logFile.saveDays = saveDays |
| | | } |
| | | |
| | | func SetSaveSize(saveSize int64) { |
| | | logFile.filesize = saveSize |
| | | } |
| | | |
| | | func Debug(args ...interface{}) { |
| | | if logFile.level >= DebugLevel { |
| | | log.SetPrefix(blue(debugPrefix)) |
| | | _ = log.Output(2, fmt.Sprintln(args...)) |
| | | } |
| | | } |
| | | |
| | | func Info(args ...interface{}) { |
| | | if logFile.level >= InfoLevel { |
| | | log.SetPrefix(green(infoPrefix)) |
| | | _ = log.Output(2, fmt.Sprintln(args...)) |
| | | } |
| | | } |
| | | |
| | | func Warn(args ...interface{}) { |
| | | if logFile.level >= WarnLevel { |
| | | log.SetPrefix(magenta(warnPrefix)) |
| | | _ = log.Output(2, fmt.Sprintln(args...)) |
| | | } |
| | | } |
| | | |
| | | func Error(args ...interface{}) { |
| | | if logFile.level >= ErrorLevel { |
| | | log.SetPrefix(red(errorPrefix)) |
| | | _ = log.Output(2, fmt.Sprintln(args...)) |
| | | } |
| | | } |
| | | |
| | | func Fatal(args ...interface{}) { |
| | | if logFile.level >= FatalLevel { |
| | | log.SetPrefix(red(fatalPrefix)) |
| | | _ = log.Output(2, fmt.Sprintln(args...)) |
| | | } |
| | | } |
| | | |
| | | func GetRedPrefix(s string) string { |
| | | return fmt.Sprintf("\x1b[%dm%s\x1b[0m", color_red, s) |
| | | } |
| | | |
| | | func red(s string) string { |
| | | return fmt.Sprintf("\x1b[%dm%s\x1b[0m", color_red, s) |
| | | } |
| | | |
| | | func green(s string) string { |
| | | return fmt.Sprintf("\x1b[%dm%s\x1b[0m", color_green, s) |
| | | } |
| | | |
| | | func yellow(s string) string { |
| | | return fmt.Sprintf("\x1b[%dm%s\x1b[0m", color_yellow, s) |
| | | } |
| | | |
| | | func blue(s string) string { |
| | | return fmt.Sprintf("\x1b[%dm%s\x1b[0m", color_blue, s) |
| | | } |
| | | |
| | | func magenta(s string) string { |
| | | return fmt.Sprintf("\x1b[%dm%s\x1b[0m", color_magenta, s) |
| | | } |
| | | |
| | | func (me LogFile) Write(buf []byte) (n int, err error) { |
| | | if me.fileName == "" { |
| | | fmt.Printf("consol: %s", buf) |
| | | return len(buf), nil |
| | | } |
| | | |
| | | switch logFile.saveMode { |
| | | case BySize: |
| | | fileInfo, err := os.Stat(logFile.fileName) |
| | | if err != nil { |
| | | logFile.createLogFile() |
| | | logFile.logTime = time.Now().Unix() |
| | | }else { |
| | | filesize:= fileInfo.Size(); |
| | | if logFile.fileFd == nil || |
| | | filesize > logFile.filesize { |
| | | logFile.createLogFile() |
| | | logFile.logTime = time.Now().Unix() |
| | | } |
| | | } |
| | | default: // 默认按天 ByDay |
| | | if logFile.logTime+3600*24 < time.Now().Unix() { |
| | | logFile.createLogFile() |
| | | logFile.logTime = time.Now().Unix() |
| | | } |
| | | } |
| | | |
| | | if logFile.fileFd == nil { |
| | | fmt.Printf("log fileFd is nil !\n") |
| | | return len(buf), nil |
| | | } |
| | | |
| | | return logFile.fileFd.Write(buf) |
| | | } |
| | | |
| | | func (me *LogFile) createLogFile() { |
| | | func InitLogger(logPath string, logLevel int,maxSize int, maxBackups int, maxAge int) { |
| | | logdir := "./logger/" |
| | | if index := strings.LastIndex(me.fileName, "/"); index != -1 { |
| | | logdir = me.fileName[0:index] + "/" |
| | | os.MkdirAll(me.fileName[0:index], os.ModePerm) |
| | | if index := strings.LastIndex(logPath, "/"); index != -1 { |
| | | logdir = logPath[0:index] + "/" |
| | | } |
| | | fi,err := os.Stat(logdir) |
| | | if !((err == nil || os.IsExist(err)) && fi.IsDir()) { |
| | | os.MkdirAll(logdir, os.ModePerm) |
| | | } |
| | | hook := lumberjack.Logger { |
| | | Filename: logPath, //日志文件的位置 |
| | | MaxSize: maxSize, //在进行切割之前,日志文件的最大大小(以MB为单位) |
| | | MaxBackups: maxBackups, //保留旧文件的最大个数 |
| | | MaxAge: maxAge, //保留旧文件的最大天数 |
| | | Compress: true, //是否压缩 |
| | | LocalTime: true, |
| | | } |
| | | w := zapcore.AddSync(&hook) |
| | | |
| | | var level zapcore.Level |
| | | switch logLevel { |
| | | case DebugLevel: |
| | | level = zap.DebugLevel |
| | | case InfoLevel: |
| | | level = zap.InfoLevel |
| | | case WarnLevel: |
| | | level = zap.WarnLevel |
| | | case ErrorLevel: |
| | | level = zap.ErrorLevel |
| | | case DPanicLevel: |
| | | level = zap.DPanicLevel |
| | | case PanicLevel: |
| | | level = zap.PanicLevel |
| | | case FatalLevel: |
| | | level = zap.FatalLevel |
| | | default: |
| | | level = zap.InfoLevel |
| | | } |
| | | encoderConfig := zap.NewProductionEncoderConfig() |
| | | encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder |
| | | encoderConfig.CallerKey = "file" |
| | | encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder |
| | | encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { |
| | | enc.AppendString(t.Format("2006-01-02 15:04:05")) |
| | | } |
| | | |
| | | now := time.Now() |
| | | filename := fmt.Sprintf("%s_%04d%02d%02d%02d", |
| | | me.fileName, now.Year(), now.Month(), now.Day(), now.Hour()) |
| | | if err := os.Rename(me.fileName, filename); err == nil { |
| | | go func() { |
| | | filenameTemp := filename + "Temp" |
| | | tarCmd := exec.Command("tar", "-zcf", filename + ".tar.gz", filenameTemp, "--remove-files") |
| | | tarCmd.Run() |
| | | |
| | | rmSrcCmd := exec.Command("rm", filename) |
| | | rmSrcCmd.Run() |
| | | |
| | | rmCmd := exec.Command("/bin/sh", "-c", |
| | | "find "+logdir+` -type f -mtime +` +string(logFile.saveDays)+ ` -exec rm {} \;`) |
| | | rmCmd.Run() |
| | | }() |
| | | core := zapcore.NewCore( |
| | | zapcore.NewConsoleEncoder(encoderConfig), |
| | | w, |
| | | level, |
| | | ) |
| | | log := zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) |
| | | blog = &BLog{ |
| | | logger: log.Sugar(), |
| | | } |
| | | blog.logger.Info("init logger success") |
| | | } |
| | | |
| | | for index := 0; index < 10; index++ { |
| | | if fd, err := os.OpenFile(me.fileName, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666); nil == err { |
| | | me.fileFd.Sync() |
| | | me.fileFd.Close() |
| | | me.fileFd = fd |
| | | break |
| | | }else { |
| | | fmt.Println("Open logfile error! err: ", err.Error()) |
| | | } |
| | | me.fileFd = nil |
| | | } |
| | | func Debug(v ...interface{}) { |
| | | blog.logger.Debug(v...) |
| | | } |
| | | |
| | | func Debugf(template string, v ...interface{}) { |
| | | blog.logger.Debugf(template, v...) |
| | | } |
| | | |
| | | func Info(v ...interface{}) { |
| | | blog.logger.Info(v) |
| | | } |
| | | |
| | | func Infof(template string, v ...interface{}) { |
| | | blog.logger.Infof(template, v...) |
| | | } |
| | | |
| | | func Warn(v ...interface{}) { |
| | | blog.logger.Warn(v...) |
| | | } |
| | | |
| | | func Warnf(template string, v ...interface{}) { |
| | | blog.logger.Warnf(template, v...) |
| | | } |
| | | |
| | | func Error(v ...interface{}) { |
| | | blog.logger.Error(v...) |
| | | } |
| | | |
| | | func Errorf(template string, v ...interface{}) { |
| | | blog.logger.Errorf(template, v...) |
| | | } |
| | | |
| | | func Fatal(v ...interface{}) { |
| | | blog.logger.Fatal(v...) |
| | | } |
| | | |
| | | func Fatalf(template string, v ...interface{}) { |
| | | blog.logger.Fatalf(template, v...) |
| | | } |