package log
import (
"fmt"
"log"
"path"
"runtime"
"strings"
"sync"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
calmutils "github.com/w/calmwu-go/utils"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
var (
// Logger Log对象
logger *zap.SugaredLogger
initOnce sync.Once
// _errorCounter 执行log.Error(f)时用函数打点,避免循环调用
_errorCounter = promauto.NewCounter(prometheus.CounterOpts{
Name: "log_output_error_total",
Help: "The total total of service output",
})
)
// 字符串对应zap日志等级,方便查看配置
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,
}
func getLoggerLevel(lvl string) zapcore.Level {
if level, ok := levelMap[strings.ToLower(lvl)]; ok {
return level
}
// 默认info级别
return zapcore.InfoLevel
}
// 创建一个ZapLog对象
func newZapLog(logFullName string, logLevel zapcore.Level) *zap.SugaredLogger {
calmutils.InitDefaultZapLog(logFullName, logLevel, 1)
return calmutils.ZLog
}
// InitLog 初始化日志
func InitLog(logFullName, level string) {
initOnce.Do(func() {
logger = newZapLog(logFullName, getLoggerLevel(level))
})
}
// Debug uses fmt.Sprint to construct and log a message.
func Debug(args ...interface{}) {
if logger != nil {
logger.Debug(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Print(composeArgs...)
}
}
// Debugf uses fmt.Sprintf to log a templated message.
func Debugf(template string, args ...interface{}) {
if logger != nil {
logger.Debugf(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Printf(prefix+template, args...)
}
}
// Info uses fmt.Sprint to construct and log a message.
func Info(args ...interface{}) {
if logger != nil {
logger.Info(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Print(composeArgs...)
}
}
// Infof uses fmt.Sprintf to log a templated message.
func Infof(template string, args ...interface{}) {
if logger != nil {
logger.Infof(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Printf(prefix+template, args...)
}
}
// Warn uses fmt.Sprint to construct and log a message.
func Warn(args ...interface{}) {
if logger != nil {
logger.Warn(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Print(composeArgs...)
}
}
// Warnf uses fmt.Sprintf to log a templated message.
func Warnf(template string, args ...interface{}) {
if logger != nil {
logger.Warnf(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Printf(prefix+template, args...)
}
}
// Error uses fmt.Sprint to construct and log a message.
func Error(args ...interface{}) {
_errorCounter.Inc()
if logger != nil {
logger.Error(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Print(composeArgs...)
}
}
// Errorf uses fmt.Sprintf to log a templated message.
func Errorf(template string, args ...interface{}) {
_errorCounter.Inc()
if logger != nil {
logger.Errorf(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Printf(prefix+template, args...)
}
}
// DPanic uses fmt.Sprint to construct and log a message. In development, the
// logger then panics. (See DPanicLevel for details.)
func DPanic(args ...interface{}) {
if logger != nil {
logger.DPanic(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Panic(composeArgs...)
}
}
// DPanicf uses fmt.Sprintf to log a templated message. In development, the
// logger then panics. (See DPanicLevel for details.)s
func DPanicf(template string, args ...interface{}) {
if logger != nil {
logger.DPanicf(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Panicf(prefix+template, args...)
}
}
// Panic uses fmt.Sprint to construct and log a message, then panics.
func Panic(args ...interface{}) {
if logger != nil {
logger.Panic(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Panic(composeArgs...)
}
}
// Panicf uses fmt.Sprintf to log a templated message, then panics.
func Panicf(template string, args ...interface{}) {
if logger != nil {
logger.Panicf(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Panicf(prefix+template, args...)
}
}
// Fatal uses fmt.Sprint to construct and log a message, then calls os.Exit.
func Fatal(args ...interface{}) {
if logger != nil {
logger.Fatal(args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
composeArgs := []interface{}{prefix}
composeArgs = append(composeArgs, args...)
log.Fatal(composeArgs...)
}
}
// Fatalf uses fmt.Sprintf to log a templated message, then calls os.Exit.
func Fatalf(template string, args ...interface{}) {
if logger != nil {
logger.Fatalf(template, args...)
} else {
_, file, line, _ := runtime.Caller(1)
prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)
log.Fatalf(prefix+template, args...)
}
}
// GetLogger get *zap.Logger
func GetLogger() *zap.Logger {
if logger != nil {
return logger.Desugar()
}
return zap.NewNop()
}