内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

Golang logrus的高级配置(hook,logrotate)

2018-01-12 16:56 出处:清屏网 人气: 评论(0

前言:

这次聊下最近使用logrus的心得,没有高深的源码,只是一些相对高级的配置吧。golang默认的log模块略显简陋,连基本的info, warn, error 打印方法都没有,不是太适用。 在使用logrus模块之前,我先前都在使用自己封装的log模块,虽然比不上logrus那么多功能,够用是没问题的。 

话说,golang社区里排名最高的日志模块就那么几个,logrus,log4j … 单看github的活跃度logrus显得更显一筹了。国内外比较出名的golang开源项目,大多都是自己实现的日志磨矿。

logrus日志切分功能 ?

对的,logrus默认是没有该功能的,我曾经在issue里问过sirupsen, 为毛没有日志基本的logrotate ? 他的回复说,不需要切分,首先该功能不是核心功能,最重要的是 作者建议大家把日志输出到其他的日志server里,比如 filebeat, logstash, syslog, rsyslog, Fluentd 等等。 logrus官方支持的日志服务列表有很多,只要我们能想到的基本都有。

那么,如果我现在logrus实现日志切分,该如何操作? 两种方法.  

第一种,借助于 linux logrotate命令 。

/devops/app/go/src/task_dispatcher/logs/*.log
{
    daily
    sharedscripts
    dateext
    nocompress
    size 1G
    missingok
    notifempty
    copytruncate
    rotate 3

第二种方法,  使用logrus的hook来加载  github.com/lestrrat/go-file-rotatelogs 模块. 每次当我们写入日志的时候,logrus都会调用 go-file-rotatelogs 来判断日志是否要进行切分…   go-file-rotatelogs  可以实现linux logratate 的大多数功能。

package context
 
import (
    "github.com/lestrrat/go-file-rotatelogs"
    "github.com/rifflock/lfshook"
    log "github.com/sirupsen/logrus"
    "github.com/pkg/errors"
    "path"
    "time"
    "os"
    "fmt"
    "bufio"
)
 
func InitLogger() {
    baseLogPath := path.Join(GlobalConfig.LogConf.Logdir,
        GlobalConfig.LogConf.Filename)
    writer, err := rotatelogs.New(
        baseLogPath+".%Y%m%d%H%M",
        rotatelogs.WithLinkName(baseLogPath),      // 生成软链,指向最新日志文件
        rotatelogs.WithMaxAge(7*24*time.Hour),     // 文件最大保存时间
        rotatelogs.WithRotationTime(24*time.Hour), // 日志切割时间间隔
    )
    if err != nil {
        log.Errorf("config local file system logger error. %v", errors.WithStack(err))
    }
 
    //log.SetFormatter(&log.TextFormatter{})
    switch level := GlobalConfig.LogConf.LogLevel; level {
    /*
    如果日志级别不是debug就不要打印日志到控制台了
     */
    case "debug":
        log.SetLevel(log.DebugLevel)
        log.SetOutput(os.Stderr)
    case "info":
        setNull()
        log.SetLevel(log.InfoLevel)
    case "warn":
        setNull()
        log.SetLevel(log.WarnLevel)
    case "error":
        setNull()
        log.SetLevel(log.ErrorLevel)
    default:
        setNull()
        log.SetLevel(log.InfoLevel)
    }
 
    lfHook := lfshook.NewHook(lfshook.WriterMap{
        log.DebugLevel: writer, // 为不同级别设置不同的输出目的
        log.InfoLevel:  writer,
        log.WarnLevel:  writer,
        log.ErrorLevel: writer,
        log.FatalLevel: writer,
        log.PanicLevel: writer,
    })
    log.AddHook(lfHook)
}
 
func setNull() {
    src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
    if err!= nil{
        fmt.Println("err", err)
    }
    writer := bufio.NewWriter(src)
    log.SetOutput(writer)
}

既然作者这么推荐大家使用logrus hook的方式来扩展日志功能,那么怎么自己写一个hook模块?  其实很简单,只需要实现这几个方法就可以了,主要看  Fire 函数…  当我们调用logrus.addHook把自定义的hook加载后,每次我们写日志的时候,都会调用Fire方法。 

logrus hook 是一个值得深入学习的设计,你可以轻易适用hook来实现多文件写入。 比如,error级别的日志独立输出到error.log文件里,其他都放在一起。

package syslog
 
import (
 "fmt"
 "log/syslog"
 "os"
 
 "github.com/sirupsen/logrus"
)
 
 
type SyslogHook struct {
 Writer        *syslog.Writer
 SyslogNetwork string
 SyslogRaddr   string
}
 
func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) {
 w, err := syslog.Dial(network, raddr, priority, tag)
 return &SyslogHook{w, network, raddr}, err
}
 
func (hook *SyslogHook) Fire(entry *logrus.Entry) error {
 line, err := entry.String()
 if err != nil {
 fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err)
 return err
 }
 
 switch entry.Level {
 case logrus.PanicLevel:
 return hook.Writer.Crit(line)
 case logrus.FatalLevel:
 return hook.Writer.Crit(line)
 case logrus.ErrorLevel:
 return hook.Writer.Err(line)
 case logrus.WarnLevel:
 return hook.Writer.Warning(line)
 case logrus.InfoLevel:
 return hook.Writer.Info(line)
 case logrus.DebugLevel:
 return hook.Writer.Debug(line)
 default:
 return nil
 }
}
 
func (hook *SyslogHook) Levels() []logrus.Level {
 return logrus.AllLevels
}

总结,个人对logrus的功能不是太满意,压根用不到的功能贼多,真正会用到的功能不够简单干练。  针对logrus日志切割的问题,我给作者提过两次了,作者忽忽悠悠把issue给关了。

分享给小伙伴们:
本文标签: Golanglogrushooklogrotate

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号