在项目中输出日志是比较常见的需求,golang默认的日志包功能比较弱,这里介绍Logrus日志处理包。

Logrus是一个结构化日志处理框架,并且api完全兼容golang标准库的logger日志api,意味着你可以直接使用Logrus替换logger。

通常我们输出的日志都是非结构化的,例如:

2019-09-10 10:10:00 [info] connect to redis error,ip=12.11.21.1

这样格式的日志,不方便对日志进行分析,尤其大数据处理,通常需要对日志进行格式化。

结构化的日志,就方便程序解析日志的内容,例如json格式:

{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}

1.安装包

go get github.com/sirupsen/logrus

2.Logrus简单例子

package main

import (
	"os"

	// 导入logrus日志包,别名为log
	log "github.com/sirupsen/logrus"
)

func main() {
    // 设置日志等级
	log.SetLevel(log.DebugLevel)
	// 设置日志输出到什么地方去
	// 将日志输出到标准输出,就是直接在控制台打印出来。
	log.SetOutput(os.Stdout)
	// 设置为true则显示日志在代码什么位置打印的
	//log.SetReportCaller(true)

	// 设置日志以json格式输出, 如果不设置默认以text格式输出
	log.SetFormatter(&log.JSONFormatter{})

	// 打印日志
	log.Debug("调试信息")
	log.Info("提示信息")
	log.Warn("警告信息")
	log.Error("错误信息")
	//log.Panic("致命错误")
	//
	// 为日志加上字段信息,log.Fields其实就是map[string]interface{}类型的别名
	log.WithFields(log.Fields{
		"user_id": 1001,
		"ip" : "123.12.12.11",
		"request_id" : "kana012uasdb8a918gad712",
	}).Info("用户登陆失败.")
}

执行后日志输出:

{"level":"debug","msg":"调试信息","time":"2019-09-11T11:30:14+08:00"}
{"level":"info","msg":"提示信息","time":"2019-09-11T11:30:14+08:00"}
{"level":"warning","msg":"警告信息","time":"2019-09-11T11:30:14+08:00"}
{"level":"error","msg":"错误信息","time":"2019-09-11T11:30:14+08:00"}
{"ip":"123.12.12.11","level":"info","msg":"用户登陆失败.","request_id":"kana012uasdb8a918gad712","time":"2019-09-11T11:30:14+08:00","user_id":1001}

3.将日志保存到文件

我们如何将日志保存到本地文件。

前面的例子我们知道,可以通过SetOutput函数设置将日志保存到什么地方,下面演示如何将日志保存到文件中。

// 先打开一个日志文件
file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
	// 设置将日志输出到文件
	log.SetOutput(file)
} else {
    log.Info("打开日志文件失败,默认输出到stderr")
}

4.自定义日志保存的位置

SetOutput函数定义:

func SetOutput(out io.Writer)

SetOutput函数接受的是一个实现了io.Writer接口的对象,只要实现了这个接口,你可以将日志保存到任何地方,例如,我们可以自定义个实现了io.Writer接口的日志存储对象,将日志保存到阿里云日志服务。

例子:

// 自定义日志存储,实现io.Writer接口
type Alilog struct {
}

// io.Writer接口只有Write一个函数
func (v *Alilog) Write(p []byte) (n int, err error) {
	// 日志内容,传进来的是字节数组
	
	// 将日志发送到阿里云日志服务
	// 当然这里可以做下缓存,批量想阿里云发送日志,不用一条条的发
	return
}

// 设置日志存储方式
log.SetOutput(&Alilog{})