美文网首页go
sirupsen/logrus 简单实现根据日志大小,自动分文件

sirupsen/logrus 简单实现根据日志大小,自动分文件

作者: Zekero | 来源:发表于2018-11-20 16:26 被阅读145次

    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 简单实现根据日志大小,自动分文件

        本文链接:https://www.haomeiwen.com/subject/jzlxqqtx.html