GitHub 仓库:https://github.com/sirupsen/logrus
Logrus是一个流行的Go语言日志库,提供了丰富的日志输出和格式化功能。它被广泛应用于Go语言项目中,用于记录程序的运行状态、错误信息和调试信息等。
Logrus具有以下特点:
灵活的日志级别:Logrus支持多种日志级别,包括调试、信息、警告、错误和致命等级别,可以根据不同的需求设置日志级别。
多种输出格式:Logrus支持多种输出格式,包括文本格式、JSON格式等,可以根据需要选择适合的格式。
可扩展的钩子机制:Logrus提供了钩子(hook)机制,可以自定义日志的输出方式,比如将日志发送到远程服务器、写入文件等。
上下文(context)日志:Logrus支持给日志添加上下文信息,可以很方便地记录一些附加的上下文数据,比如请求ID、用户ID等。
日志字段标签化:Logrus支持为日志字段添加标签(Field Tags),可以更好地组织和搜索日志信息。
在Go语言项目中使用 Logrus 需要先安装 Logrus 库,然后在代码中引入即可。
安装 Logrus 库:
使用go命令可以很方便地安装Logrus库:
go get github.com/sirupsen/logrus
引入 Logrus 库:
import (
"github.com/sirupsen/logrus"
)
Logrus 支持 7 种不同的日志级别,严重程度从高到低依次为panic>>fatal>>error>>warn>>info>>debug>>trace
:
const (
// PanicLevel级别,最高严重级别。记录日志后调用panic,并传递给Debug、Info等方法的消息。
PanicLevel Level = iota
// FatalLevel级别。记录日志后调用logger.Exit(1),即使日志级别设置为Panic也会退出。
FatalLevel
// ErrorLevel级别。用于必须被注意到的错误。通常用于将错误发送到错误跟踪服务的钩子中。
ErrorLevel
// WarnLevel级别。不是关键的条目,但值得关注。
WarnLevel
// InfoLevel级别。关于应用程序内部正在进行的一般操作的记录。
InfoLevel
// DebugLevel级别。通常仅在调试时启用。非常详细的日志记录。
DebugLevel
// TraceLevel级别。比Debug更细粒度的信息事件。
TraceLevel
)
在 Logrus 中,默认的日志级别是InfoLevel
,即 Info 级别。这意味着只有级别大于或等于Info的日志才会被打印出来。如果需要更改输出日志级别可以使用logger.SetLevel()
方法来设置:
logger.SetLevel(logrus.DebugLevel)
在Logrus中,你可以使用WithField()
和WithFields()
方法来为日志添加特定字段。这些字段可以提供额外的上下文信息,并且可以轻松地在日志中显示。
logger.WithField("user", "John Doe").Info("Login successful")
logger.WithFields(logrus.Fields{
"user": "John Doe",
"account": "123456789",
}).Info("Account created")
在上述代码中,我们使用WithField()
方法添加了一个名为"user"的特定字段,并将其设置为"John Doe"。然后,我们使用Info()
方法记录一条日志并触发该字段。
另外,我们还使用了WithFields()
方法来添加多个特定字段,其中包括"user"和"account"。然后,我们使用Info()
方法记录一条带有多个字段的日志。
输出示例:
time="2023-10-04T08:45:57+08:00" level=info msg="Login successful" user="John Doe"
time="2023-10-04T08:45:57+08:00" level=info msg="Account created" account="123456789" user="John Doe"
通常,在一个应用中、或者应用的一部分中,都有一些固定的 Field。比如在处理用户 http 请求时,上下文中所有的日志都会有 request_id 和 user_ip,为了避免每次记录日志都要使用 logrus.WithFields(logrus.Fields{"ip": "0.0.0.1",})
,我们可以创建一个 logrus.Entry
实例,为这个实例设置默认 Fields,后续直接在上下文中使用这个
logrus.Entry
实例记录日志即可。
修改后样例如下:
var (
logger *logrus.Entry
)
func init() {
// 设置日志级别
logrus.SetLevel(logrus.DebugLevel)
// 创建 logrus.Entry 实例
logger = logrus.WithFields(logrus.Fields{
"ip": "0.0.0.1",
})
// 设置日志输出格式
logrus.SetFormatter(&logrus.JSONFormatter{})
// 设置日志输出位置为标准输出
logrus.SetOutput(os.Stdout)
}
首先,我们定义了一个logger变量,它将用于记录日志。这是一个指向logrus.Entry
类型的指针。
在init()
函数中,我们使用SetLevel()
方法设置了日志级别为Debug级别。这意味着只有级别大于或等于Debug级别的日志才会被记录。
然后,我们使用WithFields()
方法创建了一个Logger实例,并设置了一个名为"ip"的特定字段,其值为"0.0.0.1"。
接下来,我们使用SetFormatter()
方法设置了日志输出格式为JSON格式。这将把日志记录为JSON格式,以便更轻松地对其进行后续处理。
最后,我们使用SetOutput()
方法将日志输出位置设置为标准输出。这意味着日志将记录在控制台上。
Logrus 提供了两种预定义的 Formatter:TextFormatter
和 JSONFormatter
,同时也支持自定义的Formatter。
TextFormatter(默认格式):
import (
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.New()
logger.Formatter = &logrus.TextFormatter{}
logger.Info("This is a log message")
}
输出示例:
time="2023-10-04T09:16:25+08:00" level=info msg="This is a log message"
JSONFormatter:
import (
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.New()
logger.Formatter = &logrus.JSONFormatter{}
logger.Info("This is a log message")
}
输出示例:
{"level":"info","msg":"This is a log message","time":"2023-10-04T09:16:25+08:00"}
在Logrus中,可以通过设置 Formatter 来为日志添加颜色。具体而言,Logrus提供了一个TextFormatter
的属性ForceColors
用于启用日志的颜色输出:
// 设置日志输出格式
logrus.SetFormatter(&logrus.TextFormatter{
ForceColors: true,
})
我们将 Logrus 实例的 Formatter 设置为TextFormatter
,接着,我们将ForceColors
属性设置为true
,启用日志的颜色输出。
如果你想自定义这些颜色,那么可以跳转查看这篇文章:Logrus 日志框架——自定义日志颜色
输出到控制台:
// 设置日志输出位置为标准输出
logrus.SetOutput(os.Stdout)
输出到文件:
//创建文件
logFile, err := os.OpenFile("logs.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
fmt.Println("无法创建日志文件:", err)
return
}
// 设置日志输出位置为文件
logrus.SetOutput(logFile)
控制台文件同时输出:
// 设置日志输出位置为控制台文件
logrus.SetOutput(io.MultiWriter(os.Stdout, logFile))
// 设置 logrus 输出日志中的文件名和行号
logrus.SetReportCaller(true)
在 logrus
中,hook
可以被用于将日志消息发送到多个目标,比如发送到 Elasticsearch、Slack、email 等。hook
接口定义了在每次写入新的日志消息时需要执行的方法,这些方法可以使用我们想要的任何数据通道或协议来传递日志消息。
logrus
内置了一些常见的 hook
,比如 SyslogHook
,可以将日志消息发送到系统日志中。此外,还有一些第三方库提供各种 hook
,可以满足各种需求。
下面是一个简单的自定义 hook
示例代码:
package main
import (
"fmt"
"time"
"github.com/sirupsen/logrus"
log "github.com/rifflock/loggers"
_ "github.com/rifflock/loggers/logrus" // 导入 logurs 适配器
)
// 自定义的 Hook
type CustomHook struct {
}
func (h *CustomHook) Levels() []logrus.Level {
return logrus.AllLevels
}
func (h *CustomHook) Fire(entry *logrus.Entry) error {
// 获取日志消息和级别
message := entry.Message
level := entry.Level
// 获取当前时间
now := time.Now().Format("2006-01-02 15:04:05")
// 构造自定义消息格式
customMessage := fmt.Sprintf("[%s] [%s] %s", now, level, message)
// 输出到标准输出
fmt.Println(customMessage)
return nil
}
func main() {
// 创建 logurs 的 logger
logger, _ := log.New("logrus")
// 配置 logrus 日志记录器
logrus.SetFormatter(&logrus.TextFormatter{
DisableColors: true,
DisableSorting: true,
FullTimestamp: true,
QuoteEmptyFields: true,
})
logrus.SetOutput(logger) // 将 logurs logger 设置为 logrus 的输出
// 设置自定义的 Hook
logrus.AddHook(&CustomHook{})
// 进行日志记录
logrus.Info("This is a log message.")
}
在上面的示例中,我们实现了一个自定义的 hook
,称为 CustomHook
。我们通过实现两个方法:Levels()
和 Fire()
来满足 hook
接口。Levels()
方法指定了我们想要监听哪些日志级别,这里我们监听了所有的级别。Fire()
方法是在每个日志消息写入时被调用,并传递 logrus.Entry
指针,这个指针包含了当前的日志消息及其元数据。