inconshreveable / log15

Structured, composable logging for Go
https://godoc.org/github.com/inconshreveable/log15
Other
1.1k stars 145 forks source link

support log rotate #133

Open SongCF opened 7 years ago

SongCF commented 7 years ago

Dear

can you support auto create new file by date, for example: after call log.Must.FileHandler("filename", log.LogfmtFormat()), log15 will create file named "filename + Date" at different dates, such as: 2017-07-25 write log to file filename-2017-07-25.log, and 2017-07-26 write log to file filename-2017-07-26.log

And auto remove expired log file.

Thanks

SongCF commented 7 years ago
//log rotate: 1.change file handler by date. 2.remove expired log file
func logRotate(expiredDays int, prefixFile string, f log.Format, lvl log.Lvl, logger log.Logger) {
    for {
        lastFileHandler := setLogFileHandler(prefixFile, f, lvl, logger)
        now := time.Now()
        next := time.Date(now.Year(), now.Month(), now.Day() + 1, 0, 0, 0, 0, now.Location())
        t := time.NewTimer(next.Sub(now))
        <-t.C
        // 1.change log file to date
        temp := setLogFileHandler(prefixFile, f, lvl, L)
        //lastFileHandler.Close()  //Close file. the struct of closingHandler not exported!
        reflect.ValueOf(lastFileHandler).MethodByName("Close").Call([]reflect.Value{})
        lastFileHandler = temp
        // TODO 2.remove expired log file
        //
    }
}

//get log file name
func getLogFileName(prefixFile string, t time.Time) string {
    return fmt.Sprintf("%v-%04d-%02d-%02d.log", prefixFile, t.Year(), t.Month(), t.Day())
}

//set log handler, and return file handler.
func setLogFileHandler(prefixFile string, f log.Format, lvl log.Lvl, logger log.Logger) log.Handler {
    curFilename := getLogFileName(prefixFile, time.Now())
    fileHandler := log.Must.FileHandler(curFilename, f)
    logger.SetHandler(log.MultiHandler(
        log.LvlFilterHandler(
            lvl,
            log.CallerFileHandler(log.StdoutHandler)),
        log.LvlFilterHandler(
            lvl,
            fileHandler)))
    return fileHandler
}

I run go logRotate() in my proj.

notzippy commented 7 years ago

Log rotate does not need to be supported. Use the lumberjsack logger to create a rotating log output stream

xgfone commented 7 years ago

lumberjsack logger is based on the file size.

I have implemented a log rotating based on time, TimedRotatingFile in the sub-package github.com/xgfone/go-tools/log/handler.

You just need to implement an adapter for log15, for example:

type closingHandler struct {
    io.WriteCloser
    log15.Handler
}

func (h *closingHandler) Close() error {
    return h.WriteCloser.Close()
}

// The handler adapter for log15.
func TimedRotatingFileHandler(fmtr log15.Format, filename string, backupCount, interval int) (h log15.Handler, err error) {
    defer func() {
        if _err := recover(); _err != nil {
            err = _err.(error)
            return
        }
    }()

    _h := handler.NewTimedRotatingFile(filename)
    _h.SetBackupCount(backupCount).SetInterval(interval)

    return closingHandler{_h, log15.StreamHandler(_h, fmtr)}, nil
}