Golang log日志以及日志框架logrus
logrus是目前github上star数量最多的日志库。logrus功能强大,性能高效,而且具备高度灵活性,logrus是一个可插拔的,结构化的日志框架,提供了自定义插件的功能,如docker prometheus等,都是用了logrus来记录日志。
文章共3,453字 · 阅读需要大约12分钟
一键AI生成摘要,助你高效阅读
问答
·
先看实例
package main
import (
"log"
"os"
)
func init() {
// 配置日志输出格式
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
// 配置前缀
log.SetPrefix("order:")
// 配置输出位置
logFile, err := os.OpenFile("./test.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Panic("打开日志文件异常")
}
log.SetOutput(logFile)
}
func main() {
log.Println("golang,log标准库测试")
}
输出结果
运行程序,会创建一个test.log文件。文件的内容如下:
order:2022/09/14 10:03:19 main.go:22: golang,log标准库测试
标准库日志log
log包提供了简单的日志功能,该包中定义了一个结构体Logger,该结构体有一些方法实现日志功能。
logger结构体
type Logger struct {
mu sync.Mutex // ensures atomic writes; protects the following fields
prefix string // prefix on each line to identify the logger (but see Lmsgprefix)
flag int // properties
out io.Writer // destination for output
buf []byte // for accumulating text to write
isDiscard int32 // atomic boolean: whether out == io.Discard
}
日志的输出格式
日志的输出格式可以通过Flag标记来控制,可以使用的常量有以下几个:
const (
Ldate = 1 << iota // the date in the local time zone: 2009/01/23
Ltime // the time in the local time zone: 01:23:23
Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
Llongfile // full file name and line number: /a/b/c/d.go:23
Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
Lmsgprefix // move the "prefix" from the beginning of the line to before the message
LstdFlags = Ldate | Ltime // initial values for the standard logger
)
logrus简介
logrus是目前github上star数量最多的日志库。logrus功能强大,性能高效,而且具备高度灵活性,logrus是一个可插拔的,结构化的日志框架,提供了自定义插件的功能,如docker prometheus等,都是用了logrus来记录日志
logrus特性
- GitHub访问地址:https://github.com/sirupsen/logrus
- 完全兼容golang标准库日志模块: logrus拥有六种日志级别: debug、info,warn、error、fatal和panic,这是golang标准库日志模块的API的超集。如果您的项目使用标准库日志模块,完全可以以最低的代价迁移到logrus上
- 可扩展的Hook机制:允许使用者通过hook的方式将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或
者mq等,或者通过hook定义日志内容和格式等 - 可选的日志输出格式:logrus内置了两种日志格式,JSONFrmatter和TextFormatter,如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式
- Field机制: logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过几长的消息来记录日志。
logrus实例
安装logrus
go get github.com/sirupsen/logrus
实例
package main
import log "github.com/sirupsen/logrus"
func main() {
log.Info("golang ,logrus")
}
运行结果
time="2022-09-15T11:32:40+08:00" level=info msg="golang ,logrus"
logrus日志级别
logrus支持如下日志级别:
Debug,Info,Warn,Error,Fatal和Panic
package main
import log "github.com/sirupsen/logrus"
func main() {
// 设置日志级别
// log.SetLevel(log.InfoLevel)
log.SetLevel(log.ErrorLevel)
// 下面输出,日志级别由低到高,输出情况由上面的日志级别控制
// 例如:设置日志级别为 ErrorLevel,则 infor、debug、warn不再输出
log.Info("info")
log.Debug("debug")
log.Warn("warn")
log.Error("error")
log.Panic("panic")
log.Fatal("fatal")
}
日志格式
logrus支持俩种日志格式,普通文本和json数据,当然也可以自己自定义
package main
import log "github.com/sirupsen/logrus"
func main() {
// 文本格式
// log.SetFormatter(&log.TextFormatter{})
// json格式
log.SetFormatter(&log.JSONFormatter{})
log.Info("info")
}
文本格式运行结果
time="2022-09-15T11:44:51+08:00" level=info msg=info
json格式运行结果
{"level":"info","msg":"info","time":"2022-09-15T11:43:36+08:00"}
日志输出
logrus日志输出可以有多种方式,可以是控制台,文件等。
package main
import (
"os"
log "github.com/sirupsen/logrus"
)
func main() {
// 设置输出,标准输出控制台
log.SetOutput(os.Stdout)
log.Info("info")
// 输出到日志文件
file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_CREATE, 0666)
if err == nil {
log.SetOutput(file)
} else {
log.Info("日志文件创建失败")
}
log.Info("info")
}
logrus结构化记录日志,Fields
logrus不推荐使用冗长的消息来记录运行信息,他推荐使用Fields来进行精细化的,结构化的信息记录
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
var event = "下订单"
var topic = "order"
var key = 1001
// log.Fatalf("事件 %s 发送到主题 %s 失败, 使用的key %d", event, topic, key)
//替代方案
log.WithFields(log.Fields{
"event": event,
"topic": topic,
"key": key,
}).Fatal("事件发送失败")
}
运行结果:
time="2022-09-15T11:54:59+08:00" level=fatal msg="事件发送失败" event="下订单" key=1001 topic=order
exit status 1
输出文件路径函数名称和行号
使用log.SetReportCaller(true),进行设置,默认是false不进行输出
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
// 输出文件路径函数名称和行号,默认是false
log.SetReportCaller(true)
log.Info("info")
}
logger
package main
import (
"os"
"github.com/sirupsen/logrus"
)
// log实例
var log = logrus.New()
// 初始化配置
func init() {
// 输出
log.Out = os.Stdout
// 格式
log.Formatter = &logrus.JSONFormatter{}
// 日志级别
logrus.SetLevel(logrus.InfoLevel)
}
func main() {
var event = "下订单"
var topic = "order"
var key = 1001
//替代方案
log.WithFields(logrus.Fields{
"event": event,
"topic": topic,
"key": key,
}).Fatal("事件发送失败")
}
日志本地文件分割
logrus本身不带日志本地分割功能,但是我们可以通过foel-rotatelogs进行日志本地文件分割。每次当我们写入日志的的时候,logrus都会调用file-rotatelogs来判断日志是否要进行切分
package main
import (
"time"
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
log "github.com/sirupsen/logrus"
)
func init() {
path := "message.log"
/* 日志轮转相关函数
`WithLinkName` 为最新的日志建立软连接
`WithRotationTime` 设置日志分割的时间,隔多久分割一次
WithMaxAge 和 WithRotationCount二者只能设置一个
`WithMaxAge` 设置文件清理前的最长保存时间
`WithRotationCount` 设置文件清理前最多保存的个数
*/
// 下面配置日志每隔 1 分钟轮转一个新文件,保留最近 3 分钟的日志文件,多余的自动清理掉。
writer, _ := rotatelogs.New(
path+".%Y%m%d%H%M",
rotatelogs.WithLinkName(path),
rotatelogs.WithMaxAge(time.Duration(180)*time.Second),
rotatelogs.WithRotationTime(time.Duration(60)*time.Second),
)
log.SetOutput(writer)
//log.SetFormatter(&log.JSONFormatter{})
}
func main() {
for {
log.Info("hello, world!")
time.Sleep(time.Duration(2) * time.Second)
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)