You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
5.5 KiB
236 lines
5.5 KiB
package log
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io/fs"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path"
|
|
"time"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
"gopkg.in/yaml.v2"
|
|
)
|
|
|
|
var (
|
|
logger Logger
|
|
)
|
|
|
|
type YLogger struct {
|
|
Logger
|
|
dynamicLevel zap.AtomicLevel
|
|
}
|
|
|
|
type Logger interface {
|
|
Info(args ...interface{})
|
|
Warn(args ...interface{})
|
|
Error(args ...interface{})
|
|
Debug(args ...interface{})
|
|
|
|
Infof(fmt string, args ...interface{})
|
|
Warnf(fmt string, args ...interface{})
|
|
Errorf(fmt string, args ...interface{})
|
|
Debugf(fmt string, args ...interface{})
|
|
}
|
|
|
|
func init() {
|
|
var (
|
|
cfg LogCfg
|
|
logCfg GlobalCfg
|
|
)
|
|
|
|
log.Println("config file name -->", ConfigFile)
|
|
log.Println("starting ...")
|
|
if _, err := toml.DecodeFile(ConfigFile, &logCfg); err != nil {
|
|
//log.Fatalf("Read config file err:%s", err.Error())
|
|
log.Println("failed to open config file")
|
|
if err = InitLog("", cfg); nil != err {
|
|
log.Println(err.Error())
|
|
}
|
|
return
|
|
}
|
|
cfg = logCfg.Logs
|
|
|
|
cfg.OutputPaths = cfg.LogPath + cfg.APPName + time.Now().Format("2006-01-02") + ".log"
|
|
cfg.ErrorOutputPaths = cfg.LogPath + cfg.APPName + ".error"
|
|
|
|
err := InitLog(cfg.LogConf, cfg)
|
|
if err != nil {
|
|
log.Printf("[InitLog] warn: %v", err)
|
|
}
|
|
}
|
|
|
|
func ReloadLogger(configFile string) {
|
|
var (
|
|
cfg LogCfg
|
|
logCfg GlobalCfg
|
|
)
|
|
|
|
log.Println("config file name -->", configFile)
|
|
if _, err := toml.DecodeFile(configFile, &logCfg); err != nil {
|
|
log.Fatalf("Read config file err:%s", err.Error())
|
|
}
|
|
cfg = logCfg.Logs
|
|
cfg.OutputPaths = cfg.LogPath + cfg.APPName + time.Now().Format("2006-01-02") + ".log"
|
|
cfg.ErrorOutputPaths = cfg.LogPath + cfg.APPName + ".error"
|
|
|
|
err := InitLog(cfg.LogConf, cfg)
|
|
if err != nil {
|
|
log.Printf("[ReloadLogger] warn: %v", err)
|
|
}
|
|
}
|
|
|
|
func RotateLogger(cfg LogCfg) {
|
|
cfg.OutputPaths = cfg.LogInfoPath + cfg.APPName + ".log"
|
|
cfg.ErrorOutputPaths = cfg.LogErrPath + cfg.APPName + ".error"
|
|
if _, err := os.Stat(cfg.OutputPaths); errors.Is(err, fs.ErrNotExist) {
|
|
if _, err = os.Create(cfg.OutputPaths); nil != err {
|
|
log.Printf("[RotateLogger] error: %s", err.Error())
|
|
return
|
|
}
|
|
}
|
|
//if _, err := os.Stat(cfg.ErrorOutputPaths); errors.Is(err, fs.ErrNotExist) {
|
|
// if _, err = os.Create(cfg.ErrorOutputPaths); nil != err {
|
|
// log.Printf("[RotateLogger] error: %s", err.Error())
|
|
// return
|
|
// }
|
|
//}
|
|
err := InitLog(cfg.LogConf, cfg)
|
|
if err != nil {
|
|
log.Printf("[RotateLogger] warn: %v", err)
|
|
}
|
|
}
|
|
|
|
var defaultZapConfig = []byte(`
|
|
level: "info"
|
|
development: false
|
|
disableCaller: false
|
|
disableStacktrace: false
|
|
sampling:
|
|
encoding: "console"
|
|
|
|
# encoder
|
|
encoderConfig:
|
|
messageKey: "message"
|
|
levelKey: "level"
|
|
timeKey: "time"
|
|
nameKey: "logger"
|
|
callerKey: "caller"
|
|
stacktraceKey: "stacktrace"
|
|
lineEnding: ""
|
|
# levelEncoder: "capitalColor"
|
|
timeEncoder: "iso8601"
|
|
durationEncoder: "seconds"
|
|
callerEncoder: "short"
|
|
nameEncoder: ""
|
|
`)
|
|
|
|
func InitLog(logConfFile string, cfg LogCfg) error {
|
|
conf := &zap.Config{}
|
|
if logConfFile != "" {
|
|
if path.Ext(logConfFile) != ".yml" {
|
|
InitLogger(nil)
|
|
return fmt.Errorf("log configure file name{%s} suffix must be .yml", logConfFile)
|
|
}
|
|
|
|
confFileStream, err := ioutil.ReadFile(logConfFile)
|
|
if err != nil {
|
|
InitLogger(nil)
|
|
return fmt.Errorf("ioutil.ReadFile(file:%s) = error:%v", logConfFile, err)
|
|
}
|
|
|
|
err = yaml.Unmarshal(confFileStream, conf)
|
|
if err != nil {
|
|
InitLogger(nil)
|
|
return fmt.Errorf("[Unmarshal]init logger error: %v", err)
|
|
}
|
|
} else {
|
|
conf = &zap.Config{
|
|
Level: zap.NewAtomicLevel(),
|
|
Development: false,
|
|
DisableCaller: false,
|
|
DisableStacktrace: false,
|
|
Sampling: nil,
|
|
Encoding: "console",
|
|
EncoderConfig: zapcore.EncoderConfig{
|
|
MessageKey: "message",
|
|
LevelKey: "level",
|
|
TimeKey: "time",
|
|
NameKey: "logger",
|
|
CallerKey: "caller",
|
|
StacktraceKey: "stacktrace",
|
|
EncodeTime: zapcore.EpochMillisTimeEncoder,
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: zapcore.ShortCallerEncoder,
|
|
EncodeName: nil,
|
|
EncodeLevel: nil,
|
|
},
|
|
}
|
|
|
|
err := yaml.Unmarshal(defaultZapConfig, conf)
|
|
if err != nil {
|
|
InitLogger(nil)
|
|
return fmt.Errorf("[Unmarshal]init logger error: %v", err)
|
|
}
|
|
}
|
|
conf.OutputPaths = append(conf.OutputPaths, cfg.OutputPaths)
|
|
conf.ErrorOutputPaths = append(conf.ErrorOutputPaths, cfg.ErrorOutputPaths)
|
|
InitLogger(conf)
|
|
|
|
return nil
|
|
}
|
|
|
|
func InitLogger(conf *zap.Config) {
|
|
var zapLoggerConfig zap.Config
|
|
if conf == nil {
|
|
zapLoggerConfig = zap.NewDevelopmentConfig()
|
|
zapLoggerEncoderConfig := zapcore.EncoderConfig{
|
|
TimeKey: "time",
|
|
LevelKey: "level",
|
|
NameKey: "logger",
|
|
CallerKey: "caller",
|
|
MessageKey: "message",
|
|
StacktraceKey: "stacktrace",
|
|
EncodeTime: zapcore.ISO8601TimeEncoder,
|
|
EncodeDuration: zapcore.SecondsDurationEncoder,
|
|
EncodeCaller: zapcore.ShortCallerEncoder,
|
|
}
|
|
zapLoggerConfig.EncoderConfig = zapLoggerEncoderConfig
|
|
} else {
|
|
zapLoggerConfig = *conf
|
|
}
|
|
zapLogger, _ := zapLoggerConfig.Build(zap.AddCallerSkip(1))
|
|
//logger = zapLogger.Sugar()
|
|
logger = &YLogger{Logger: zapLogger.Sugar(), dynamicLevel: zapLoggerConfig.Level}
|
|
}
|
|
|
|
func SetLogger(log Logger) {
|
|
logger = log
|
|
}
|
|
|
|
func GetLogger() Logger {
|
|
return logger
|
|
}
|
|
|
|
func SetLoggerLevel(level string) bool {
|
|
if l, ok := logger.(OpsLogger); ok {
|
|
l.SetLoggerLevel(level)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
type OpsLogger interface {
|
|
Logger
|
|
SetLoggerLevel(level string)
|
|
}
|
|
|
|
func (dl *YLogger) SetLoggerLevel(level string) {
|
|
l := new(zapcore.Level)
|
|
l.Set(level)
|
|
dl.dynamicLevel.SetLevel(*l)
|
|
}
|