package logutil import ( "bytes" "fmt" "io" "os" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) type Logger struct { *zap.SugaredLogger logPath string } func NewLogger(logPath string) *Logger { zapCfg := zap.NewDevelopmentConfig() consoleCfg := zapcore.EncoderConfig{ TimeKey: "time", LevelKey: "level", NameKey: "logger", MessageKey: "msg", CallerKey: "", StacktraceKey: "", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.CapitalColorLevelEncoder, EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.StringDurationEncoder, } consoleEncoder := zapcore.NewConsoleEncoder(consoleCfg) fileCfg := zapcore.EncoderConfig{ TimeKey: "time", LevelKey: "level", NameKey: "logger", MessageKey: "msg", CallerKey: "", StacktraceKey: "", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.CapitalLevelEncoder, EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.StringDurationEncoder, } fileEncoder := zapcore.NewConsoleEncoder(fileCfg) // Set up file logging with overwrite mode logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { panic("cannot open log file: " + err.Error()) } fmt.Println("Logging to", logPath) core := zapcore.NewTee( zapcore.NewCore(consoleEncoder, zapcore.AddSync(os.Stdout), zapCfg.Level), zapcore.NewCore(fileEncoder, zapcore.AddSync(logFile), zapCfg.Level), ) logger := zap.New(core, zap.AddCaller(), zap.Development()) defer logger.Sync() // flushes buffer, if any sugar := logger.Sugar() zLogger := &Logger{ SugaredLogger: sugar, logPath: logPath, } return zLogger } func (l *Logger) Named(name string) *Logger { return &Logger{ SugaredLogger: l.SugaredLogger.Named(name), logPath: l.logPath, } } func (l *Logger) GetLogsFromFile() (string, error) { file, err := os.Open(l.logPath) if err != nil { return "", err } defer file.Close() var buffer bytes.Buffer _, err = io.Copy(&buffer, file) if err != nil { return "", err } return buffer.String(), nil }