sirupsen/logrus 简单实现根据日志大小,自动分文件的方法,以及实现日志回滚的思路

logurs

logurs 是个很受欢迎的日志库,github上的star 8000+ 。功能也很强大。但是却没有日志文件管理的功能。颇感遗憾。自己就想简单的封装一下,看能不能实现对日志文件管理的功能。

思路

思路如下。
1. 实现io.Writer 接口。 里面实现把数据写入到文件和对文件大小的计算。
2. 把logurs的输出重定向到1实现的io.Writer中

实现io.Writer

io.Writer 只有一个方法
type interface Writer{ Write(p []byte) (n int, err error }
很简单。 下面实现这个接口


    type logFileWriter struct {
    file *os.File
    size int64
    }
func (p *logFileWriter) Write(data []byte) (n int, err error) {
    if p == nil {
        return 0, errors.New("logFileWriter is nil")
    }
    if p.file == nil {
        return 0, errors.New("file not opened")
    }
    n, e := p.file.Write(data)
    p.size += int64(n)
          //文件最大 64 K byte
    if p.size > 1024*64 {
        p.file.Close()
        fmt.Println("log file full")
        p.file, _ = os.OpenFile("./mylog"+strconv.FormatInt(time.Now().Unix(), 10), os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_SYNC, 0600)
        p.size = 0
    }
    return n, e
}

实现logrus的输出重定向

logrus 提供了相应的接口,直接调用
log.SetOutput(&fileWriter)

完整代码

package main

import (
    "errors"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    log "github.com/sirupsen/logrus"
    "os"
    "strconv"
    "sync"
    "time"
)

type logFileWriter struct {
    file *os.File
    //write count
    size int64
}

var wg sync.WaitGroup

func main() {
    //log.SetFormatter(&log.JSONFormatter{})
    file, err := os.OpenFile("./mylog"+strconv.FormatInt(time.Now().Unix(), 10), os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_SYNC, 0600)
    if err != nil {
        log.Fatal("log  init failed")
    }

    info, err := file.Stat()
    if err != nil {
        log.Fatal(err)
    }
    fileWriter := logFileWriter{file, info.Size()}
    log.SetOutput(&fileWriter)
    log.Info("start.....")
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go logTest(i)
    }
    log.Warn("waitting...")
    wg.Wait()
}
func (p *logFileWriter) Write(data []byte) (n int, err error) {
    if p == nil {
        return 0, errors.New("logFileWriter is nil")
    }
    if p.file == nil {
        return 0, errors.New("file not opened")
    }
    n, e := p.file.Write(data)
    p.size += int64(n)
        //文件最大 64K byte
    if p.size > 1024*64 {
        p.file.Close()
        fmt.Println("log file full")
        p.file, _ = os.OpenFile("./mylog"+strconv.FormatInt(time.Now().Unix(), 10), os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_SYNC, 0600)
        p.size = 0
    }
    return n, e
}

func logTest(id int) {
    for i := 0; i < 100; i++ {
        log.Info("Thread:", id, " value:", i)
        time.Sleep(10 * time.Millisecond)
    }
    wg.Done()
}

测试结果

DeepinScreenshot_select-area_20181120162011.png

文件大了一点点,但是日志对于这种差别并不敏感,所以没有关系了

关于日志回滚的思路

logrus 虽然强大,但是还是没有实现日志的回滚功能。 想必仔细看的朋友也可以想到,使用以上类似的思路也是可以实现日志的回滚的:通过实现io.Writer 接口,里面添加必要的对日志文件管理的功能,重定向输出到自定义的io.Writer接口。其实相比自动分文件,日志回滚就是加多了对日志文件的管理,就可以达到了。

你可能感兴趣的:(sirupsen/logrus 简单实现根据日志大小,自动分文件的方法,以及实现日志回滚的思路)