219 lines
4.9 KiB
Go
219 lines
4.9 KiB
Go
package log
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/mattn/go-colorable"
|
|
"github.com/natefinch/lumberjack"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
// Logger represents a logger
|
|
type Logger struct {
|
|
log *zap.SugaredLogger
|
|
f *os.File
|
|
Flags int `json:"flags"`
|
|
Filename string `json:"filename"`
|
|
Rotate bool `json:"rotate"`
|
|
Daily bool `json:"Daily"`
|
|
Maxdays int `json:"maxdays"`
|
|
StacktraceLevel string `json:"stacktraceLevel"`
|
|
Level string `json:"level"`
|
|
}
|
|
|
|
// NewLogger creates a new logger
|
|
func NewLogger(name, provider string, configJSON string) error {
|
|
logger, err := newLogger(name, provider, configJSON)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
Default.loggers[name] = logger
|
|
return nil
|
|
}
|
|
|
|
// GetLogger returns the logger
|
|
func GetLogger(name string) *Logger {
|
|
return Default.loggers[name]
|
|
}
|
|
|
|
// DelLogger delete a log
|
|
func DelLogger(name string) {
|
|
delete(Default.loggers, name)
|
|
}
|
|
|
|
func convertLevel(lvl string) zapcore.Level {
|
|
switch lvl {
|
|
case "debug", "trace":
|
|
return zap.DebugLevel
|
|
case "warn":
|
|
return zap.WarnLevel
|
|
case "error":
|
|
return zap.ErrorLevel
|
|
case "critical":
|
|
return zap.PanicLevel
|
|
case "fatal":
|
|
return zap.FatalLevel
|
|
case "info":
|
|
fallthrough
|
|
default:
|
|
return zap.InfoLevel
|
|
}
|
|
}
|
|
|
|
func MyPath(ec zapcore.EntryCaller) string {
|
|
if !ec.Defined {
|
|
return "undefined"
|
|
}
|
|
idx := strings.LastIndexByte(ec.File, '/')
|
|
if idx == -1 {
|
|
return ec.FullPath()
|
|
}
|
|
// Find the penultimate separator.
|
|
idx = strings.LastIndexByte(ec.File[:idx], '/')
|
|
if idx == -1 {
|
|
return ec.FullPath()
|
|
}
|
|
var buf strings.Builder
|
|
// Keep everything after the penultimate separator.
|
|
buf.WriteString(ec.File[idx+1:])
|
|
buf.WriteByte(':')
|
|
buf.WriteString(fmt.Sprintf("%d", ec.Line))
|
|
return buf.String()
|
|
}
|
|
|
|
func MyCallerEncoder(caller zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) {
|
|
enc.AppendString(MyPath(caller))
|
|
}
|
|
|
|
func newLogger(name, provider string, configJSON string) (*Logger, error) {
|
|
var l Logger
|
|
if configJSON != "" {
|
|
err := json.Unmarshal([]byte(configJSON), &l)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
encoderConfig := zapcore.EncoderConfig{
|
|
TimeKey: "time",
|
|
LevelKey: "level",
|
|
NameKey: "logger",
|
|
CallerKey: "caller",
|
|
MessageKey: "msg",
|
|
StacktraceKey: "stacktrace",
|
|
LineEnding: zapcore.DefaultLineEnding,
|
|
EncodeLevel: zapcore.CapitalLevelEncoder,
|
|
EncodeTime: zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000"),
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: MyCallerEncoder, // 全路径编码器
|
|
ConsoleSeparator: " ",
|
|
}
|
|
|
|
var writeSyncers []zapcore.WriteSyncer
|
|
|
|
if provider == "console" {
|
|
encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
|
|
writeSyncers = append(writeSyncers, zapcore.AddSync(colorable.NewColorableStdout()))
|
|
} else if provider == "file" {
|
|
if l.Filename == "" {
|
|
l.Filename = "xlog.log"
|
|
}
|
|
if l.Rotate {
|
|
if l.Maxdays == 0 {
|
|
l.Maxdays = 7
|
|
}
|
|
lumberJackLogger := &lumberjack.Logger{
|
|
Filename: l.Filename,
|
|
MaxBackups: l.Maxdays,
|
|
MaxAge: l.Maxdays,
|
|
Compress: false,
|
|
}
|
|
|
|
writeSyncers = append(writeSyncers, zapcore.AddSync(lumberJackLogger))
|
|
} else {
|
|
var err error
|
|
l.f, err = os.Create(l.Filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
writeSyncers = append(writeSyncers, zapcore.AddSync(l.f))
|
|
}
|
|
}
|
|
|
|
atomicLevel := zap.NewAtomicLevel()
|
|
atomicLevel.SetLevel(convertLevel(l.Level))
|
|
|
|
core := zapcore.NewCore(
|
|
zapcore.NewConsoleEncoder(encoderConfig),
|
|
zapcore.NewMultiWriteSyncer(writeSyncers...),
|
|
atomicLevel,
|
|
)
|
|
|
|
if l.StacktraceLevel == "" {
|
|
l.StacktraceLevel = "critical"
|
|
}
|
|
|
|
l.log = zap.New(core,
|
|
zap.AddCaller(),
|
|
zap.AddCallerSkip(3),
|
|
zap.AddStacktrace(convertLevel(l.StacktraceLevel)),
|
|
).Sugar()
|
|
|
|
return &l, nil
|
|
}
|
|
|
|
// GetLevel return the log level
|
|
func (l *Logger) GetLevel() string {
|
|
return l.Level
|
|
}
|
|
|
|
// Debug record debug log
|
|
func (l *Logger) Debug(format string, args ...interface{}) {
|
|
l.log.Debugf(format, args...)
|
|
}
|
|
|
|
// Trace record trace log
|
|
func (l *Logger) Trace(format string, args ...interface{}) {
|
|
l.log.Debugf(format, args...)
|
|
}
|
|
|
|
// Info record info log
|
|
func (l *Logger) Info(format string, args ...interface{}) {
|
|
l.log.Infof(format, args...)
|
|
}
|
|
|
|
// Warn record warn log
|
|
func (l *Logger) Warn(format string, args ...interface{}) {
|
|
l.log.Warnf(format, args...)
|
|
}
|
|
|
|
// Error record error log
|
|
func (l *Logger) Error(format string, args ...interface{}) {
|
|
l.log.Errorf(format, args...)
|
|
}
|
|
|
|
// Critical record critical error log
|
|
func (l *Logger) Critical(format string, args ...interface{}) {
|
|
l.log.Panicf(format, args...)
|
|
}
|
|
|
|
// Fatal record fatal log
|
|
func (l *Logger) Fatal(format string, args ...interface{}) {
|
|
l.log.Fatalf(format, args...)
|
|
}
|
|
|
|
// Close should be invoked before exit the program
|
|
func (l *Logger) Close() {
|
|
if l.log != nil {
|
|
l.log.Sync()
|
|
}
|
|
if l.f != nil {
|
|
l.f.Close()
|
|
}
|
|
}
|