package log import ( "fmt" "io/ioutil" "log" "path" "github.com/BurntSushi/toml" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/yaml.v2" ) var ( logger Logger //OutputPaths = "" //ErrOutputPaths = "" ) 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 ( 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(""); nil != err { log.Println(err.Error()) } return } cfg = logCfg.Logs cfg.OutputPaths = cfg.LogPath + cfg.APPName + ".log" cfg.ErrorOutputPaths = cfg.LogPath + cfg.APPName + ".error" err := InitLog(cfg.LogConf) if err != nil { log.Printf("[InitLog] warn: %v", err) } } func ReloadLogger(configFile string) { var ( 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 + ".log" cfg.ErrorOutputPaths = cfg.LogPath + cfg.APPName + ".error" err := InitLog(cfg.LogConf) if err != nil { log.Printf("[ReloadLogger] warn: %v", err) } } func InitLog(logConfFile string) error { if logConfFile == "" { InitLogger(nil) return fmt.Errorf("log configure file name is nil") } 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) } conf := &zap.Config{} err = yaml.Unmarshal(confFileStream, conf) if err != nil { InitLogger(nil) return fmt.Errorf("[Unmarshal]init logger error: %v", err) } log.Println("to set yuanex logger ...") conf.OutputPaths = append(conf.OutputPaths, cfg.OutputPaths) conf.ErrorOutputPaths = append(conf.ErrorOutputPaths, cfg.ErrorOutputPaths) log.Println("ErrorOutputPahts -->", conf.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) }