153 lines
4.1 KiB
Go
153 lines
4.1 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"tinyurl/pkg/config"
|
|
"tinyurl/pkg/trace"
|
|
|
|
"github.com/fatih/color"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
)
|
|
|
|
type Logger struct {
|
|
logger *zap.Logger
|
|
}
|
|
|
|
const (
|
|
StdOutput = "std"
|
|
FileOutput = "file"
|
|
)
|
|
|
|
var levelMap = map[string]zapcore.Level{
|
|
"debug": zapcore.DebugLevel,
|
|
"info": zapcore.InfoLevel,
|
|
"warn": zapcore.WarnLevel,
|
|
"error": zapcore.ErrorLevel,
|
|
"dpanic": zapcore.DPanicLevel,
|
|
"panic": zapcore.PanicLevel,
|
|
"fatal": zapcore.FatalLevel,
|
|
}
|
|
|
|
var colors = map[color.Attribute]*color.Color{
|
|
color.FgGreen: color.New(color.FgGreen),
|
|
color.FgHiWhite: color.New(color.FgHiWhite),
|
|
color.FgYellow: color.New(color.FgYellow),
|
|
color.FgRed: color.New(color.FgRed, color.Underline),
|
|
color.FgHiRed: color.New(color.FgHiRed, color.Underline, color.Bold),
|
|
color.FgBlue: color.New(color.FgBlue),
|
|
}
|
|
|
|
func New(c config.Log) (*Logger, error) {
|
|
level := getLevel(c.Level)
|
|
var writer zapcore.WriteSyncer
|
|
if c.Output == StdOutput {
|
|
writer = getStdWriter()
|
|
} else if c.Output == FileOutput {
|
|
writer = getFileWriter(c.Rotate)
|
|
} else {
|
|
return nil, errors.New("output must in [std, file]")
|
|
}
|
|
encoder := getJSONEncoder()
|
|
var opts []zap.Option
|
|
if c.Development {
|
|
encoder = getConsoleEncoder()
|
|
opts = append(opts, zap.AddCaller(), zap.AddCallerSkip(1), zap.Development())
|
|
}
|
|
core := zapcore.NewCore(encoder, writer, level)
|
|
return &Logger{zap.New(core, opts...)}, nil
|
|
}
|
|
|
|
func getLevel(level string) zapcore.Level {
|
|
if l, ok := levelMap[level]; ok {
|
|
return l
|
|
}
|
|
return zapcore.InfoLevel
|
|
}
|
|
|
|
func getJSONEncoder() zapcore.Encoder {
|
|
conf := zap.NewProductionEncoderConfig()
|
|
conf.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
|
|
conf.EncodeCaller = zapcore.FullCallerEncoder
|
|
return zapcore.NewJSONEncoder(conf)
|
|
}
|
|
|
|
func getConsoleEncoder() zapcore.Encoder {
|
|
conf := zap.NewProductionEncoderConfig()
|
|
conf.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05")
|
|
conf.EncodeCaller = zapcore.FullCallerEncoder
|
|
return zapcore.NewConsoleEncoder(conf)
|
|
}
|
|
|
|
func getFileWriter(c config.Rotate) zapcore.WriteSyncer {
|
|
logger := &lumberjack.Logger{
|
|
Filename: c.Filename,
|
|
MaxSize: c.MaxSize, //Mb
|
|
MaxAge: c.MaxAge, //days
|
|
MaxBackups: c.MaxBackups, //int backup maximum number of old log files
|
|
LocalTime: c.LocalTime, //bool backup files is the computer's local time
|
|
Compress: c.Compress, //bool
|
|
}
|
|
return zapcore.AddSync(logger)
|
|
}
|
|
|
|
func getStdWriter() zapcore.WriteSyncer {
|
|
return os.Stdout
|
|
}
|
|
|
|
func (l *Logger) Sync() error {
|
|
return l.logger.Sync()
|
|
}
|
|
|
|
func (l *Logger) Debug(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgBlue].Sprintf("%s", msg)
|
|
l.logger.Debug(msg, fields...)
|
|
}
|
|
|
|
func (l *Logger) Info(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgGreen].Sprintf("%s", msg)
|
|
l.logger.Info(msg, fields...)
|
|
}
|
|
|
|
func (l *Logger) Warn(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgYellow].Sprintf("%s", msg)
|
|
l.logger.Warn(msg, fields...)
|
|
}
|
|
|
|
func (l *Logger) Error(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgRed].Sprintf("%s", msg)
|
|
l.logger.Error(msg, fields...)
|
|
}
|
|
|
|
func (l *Logger) DPanic(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgHiRed].Sprintf("%s", msg)
|
|
l.logger.DPanic(msg, fields...)
|
|
}
|
|
|
|
func (l *Logger) Panic(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgHiRed].Sprintf("%s", msg)
|
|
l.logger.Panic(msg, fields...)
|
|
}
|
|
|
|
func (l *Logger) Fatal(ctx context.Context, msg string, fields ...zap.Field) {
|
|
fields = append(fields, getTrace(ctx))
|
|
msg = colors[color.FgHiRed].Sprintf("%s", msg)
|
|
l.logger.Fatal(msg, fields...)
|
|
}
|
|
|
|
func getTrace(ctx context.Context) zapcore.Field {
|
|
if ctx == nil {
|
|
return zap.Skip()
|
|
}
|
|
return zap.String("trace", trace.Trace(ctx))
|
|
}
|