Golang日志库logrus的介绍与使用示例代码

 更新时间:2024年10月21日 11:46:41   作者:千年死缓  
Logrus是Go语言的一个功能丰富的日志库,支持结构化日志和多级别日志记录,它兼容标准log库,并可通过自定义Hooks和Formatter进行高度定制化,支持集成如syslog等系统,便于管理和分析,Logrus还支持自定义日志颜色和格式,以及根据日志级别进行不同处理,如panic和exit

logrus概述 

简介

Logrus 是一个流行的 Go 语言日志库,它提供了结构化日志和多种日志级别的功能。Logrus 非常灵活,支持自定义日志格式和输出,被许多 Go 语言项目广泛使用

特点

完全兼容log标准库:Logrus 可以很容易地替换掉log标准库,因为它实现了相同的接口

  • 结构化日志记录:可以很容易地记录字段数据,这些数据随后可以被其他日志处理系统解析
  • 多个日志级别:Logrus 支持多种日志级别,包括:PanicFatalErrorWarnInfoDebugTrace
  • 易于集成:Logrus 可以与其他系统如syslog、Hook等集成,便于日志的集中管理和分析
  • 高度可定制:可以通过 Hooks 和格式化器来自定义日志的输出格式和内容

下载

go get github.com/sirupsen/logrus

logrus常用方法

logrus.Debugln("Debugln")
logrus.Infoln("Infoln")
logrus.Warnln("Warnln")
logrus.Errorln("Errorln")
logrus.Println("Println")
// 输出如下
time="2024-10-20T16:08:01+08:00" level=info msg=Infoln   
time="2024-10-20T16:08:01+08:00" level=warning msg=Warnln
time="2024-10-20T16:08:01+08:00" level=error msg=Errorln 
time="2024-10-20T16:08:01+08:00" level=info msg=Println

debug的没有输出,是因为logrus默认的日志输出等级是 info

日志级别

  • logrus.PanicLevel: 记录日志,然后调用 panic()
  • logrus.FatalLevel: 记录日志,然后调用 os.Exit(1)
  • logrus.ErrorLevel: 记录错误级别的日志
  • logrus.WarnLevel: 记录警告级别的日志
  • logrus.InfoLevel: 记录信息级别的日志
  • logrus.DebugLevel: 记录调试级别的日志
  • logrus.TraceLevel: 记录跟踪级别的日志
package main
import (
	"os"
	"github.com/sirupsen/logrus"
)
func main() {
	// 设置日志输出到 os.Stdout
	logrus.SetOutput(os.Stdout)
	// 设置日志级别为 InfoLevel,这意味着 InfoLevel 及以上级别的日志会被记录
	logrus.SetLevel(logrus.InfoLevel)
	// 记录不同级别的日志
	logrus.Trace("This is a trace message and will not be printed.")
	logrus.Debug("This is a debug message and will not be printed.")
	logrus.Info("This is an info message and will be printed.")
	logrus.Warn("This is a warning message and will be printed.")
	logrus.Error("This is an error message and will be printed.")
	// 注意:通常不推荐在生产环境中使用 PanicLevel 和 FatalLevel,因为它们会导致程序退出。
	// logrus.Panic("This is a panic message and will cause the program to panic.")
	// logrus.Fatal("This is a fatal message and will cause the program to exit.")
}

字段

  • WithField(key string, value interface{}) *Entry:添加一个字段到日志条目
  • WithFields(fields log.Fields) *Entry:添加多个字段到日志条目
  • WithError(err error) *Entry:添加错误字段到日志条目
package main
import (
	"os"
	"github.com/sirupsen/logrus"
)
func main() {
	// 设置日志输出到 os.Stdout
	logrus.SetOutput(os.Stdout)
	// 设置日志格式为 JSON,这对于结构化日志记录很有用
	logrus.SetFormatter(&logrus.JSONFormatter{})
	// 使用 WithField 方法添加一个字段
	logEntry := logrus.WithField("user", "Alice")
	// 使用 WithFields 方法添加多个字段
	logEntry = logEntry.WithFields(logrus.Fields{
		"operation": "login",
		"result":    "success",
	})
	// 记录一条包含字段的日志
	logEntry.Info("User logged in successfully")
	// 使用 WithError 方法添加一个错误字段
	err := fmt.Errorf("something went wrong")
	logEntry.WithError(err).Error("An error occurred")
}

输出

日志样式

显示行号

logrus.SetReportCaller(true)

样式设置

默认的是以text的形式展示,也可以设置为jsong样式

textLogger := logrus.New()
	// 创建一个 TEXT 格式的日志记录器
	textLogger.SetFormatter(&logrus.TextFormatter{
		DisableColors: false,
		FullTimestamp: true,
	})
	// 创建一个 JSON 格式的日志记录器
	jsonLogger := logrus.New()
	jsonLogger.SetFormatter(&logrus.JSONFormatter{})

输出地址

  • SetOutput(io.Writer):设置日志的输出目的地
  • SetFormatter(formatter Formatter):设置日志的格式化器
package main
import (
	"os"
	"github.com/sirupsen/logrus"
)
func main() {
	// 创建一个新的 Logrus 实例
	log := logrus.New()
	// 输出到 os.Stdout
	log.SetOutput(os.Stdout)
	// 输出到文件
	file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err == nil {
		log.SetOutput(file)
	} else {
		log.Fatalf("Failed to log to file, using default stderr: %v", err)
	}
	// 输出到自定义 io.Writer,例如 bytes.Buffer
	var buffer bytes.Buffer
	log.SetOutput(&buffer)
	// 记录一些日志
	log.Info("This is an info message")
	log.Warn("This is a warning message")
	log.Error("This is an error message")
	// 如果输出到 bytes.Buffer,你可以获取日志内容
	logBytes := buffer.Bytes()
	os.Stdout.Write(logBytes) // 将 buffer 中的内容输出到 os.Stdout
}

日志颜色

默认颜色

  • DebugLevel: 蓝色
  • InfoLevel: 绿色
  • WarningLevel: 黄色
  • ErrorLevel: 红色
  • FatalLevel: 红色(通常伴随有其他指示,比如退出程序)
  • PanicLevel: 红色(通常伴随有 panic)

禁用颜色

log.SetFormatter(&logrus.TextFormatter{
	DisableColors: true,
})

自定义颜色

  • 创建一个新的 TextFormatter 结构体
  • 重写 Format 方法,在格式化日志时添加自定义颜色代码
  • 将自定义的 Formatter 设置给 Logrus 实例

自定义格式

通过实现 logrus.Formatter 接口来自定义日志格式

package main
import (
	"bytes"
	"fmt"
	"github.com/sirupsen/logrus"
	"os"
)
// CustomFormatter 自定义格式化器
type CustomFormatter struct {
	logrus.TextFormatter
}
// Format 实现 logrus.Formatter 接口
func (f *CustomFormatter) Format(entry *logrus.Entry) ([]byte, error) {
	var b *bytes.Buffer
	if entry.Buffer != nil {
		b = entry.Buffer
	} else {
		b = &bytes.Buffer{}
	}
	// 添加自定义颜色代码
	color := ""
	switch entry.Level {
	case logrus.DebugLevel:
		color = "\x1b[34m" // 蓝色
	case logrus.InfoLevel:
		color = "\x1b[32m" // 绿色
	case logrus.WarnLevel:
		color = "\x1b[33m" // 黄色
	case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
		color = "\x1b[31m" // 红色
	}
	// 写入颜色代码和日志内容
	fmt.Fprintf(b, "%s%s\x1b[0m\n", color, entry.Message)
	return b.Bytes(), nil
}
func main() {
	log := logrus.New()
	log.SetFormatter(&CustomFormatter{
		TextFormatter: logrus.TextFormatter{
			DisableColors: false,
			FullTimestamp: true,
		},
	})
	log.Debug("This is a debug message")
	log.Info("This is an info message")
	log.Warn("This is a warning message")
	log.Error("This is an error message")
}

MyFormatter 结构体实现了 Format 方法,该方法接收一个 logrus.Entry 对象,该对象包含了日志条目的所有信息,包括时间戳、日志级别、消息和字段。Format 方法将这些信息格式化为一个字符串,并返回字节数组。

[2024-10-20T17:14:22+08:00] [info] A group of walrus emerges from the ocean size=10 animal=walrus 

Hook

  • 在 Logrus 中,Hook 是一个接口,允许你添加自定义的逻辑,这些逻辑会在日志记录之前或之后执行。通过实现 logrus.Hook 接口,你可以创建自己的钩子来执行额外的操作,比如发送日志到远程系统、写入数据库、执行特定的监控检查等。
  • 在 Logrus 中,Hook 的基本用法涉及以下步骤:
  • 定义一个 Hook 结构体:这个结构体需要实现 Levels()Fire(entry *logrus.Entry) error 方法。
  • 实现 Levels() 方法:这个方法返回一个 logrus.Level 切片,表示该 Hook 将被哪些日志级别触发。
  • 实现 Fire(entry \*logrus.Entry) error 方法:这个方法定义了当日志被记录时应该执行的逻辑。
  • 将 Hook 添加到 Logrus 实例:使用 log.AddHook(hook) 方法。

自定义 Hook 示例,它会在每次记录日志时打印出当前的函数名和文件名:

package main
import (
	"fmt"
	"runtime"
	"github.com/sirupsen/logrus"
)
// MyHook 是一个自定义的 Logrus 钩子
type MyHook struct {
}
// Levels 定义了这个钩子会被哪些日志级别触发
func (hook *MyHook) Levels() []logrus.Level {
	return logrus.AllLevels
}
// Fire 是每次日志记录时都会调用的方法
func (hook *MyHook) Fire(entry *logrus.Entry) error {
	// 获取调用者的函数名和文件名
	pc, file, line, ok := runtime.Caller(8) // 8 是调用栈的深度,可能需要根据你的代码结构进行调整
	if !ok {
		fmt.Println("Could not get caller info")
		return nil
	}
	function := runtime.FuncForPC(pc).Name()
	fmt.Printf("Caller: %s:%d %s\n", file, line, function)
	return nil
}
func main() {
	log := logrus.New()
	// 添加自定义钩子
	log.AddHook(&MyHook{})
	log.Info("This is an informational message")
	log.Warn("This is a warning message")
}
  • 在上面的代码中,MyHook 结构体实现了 LevelsFire 方法。Levels 方法返回一个日志级别切片,表示这个钩子会对哪些级别的日志进行响应。在这个例子中,我们使用 logrus.AllLevels,这意味着它会对所有级别的日志做出响应。

Fire 方法会在每次记录日志时被调用。在这个方法中,我们使用 runtime.Caller 来获取调用日志记录函数的函数名和文件名,并打印出来。

main 函数中,我们创建了一个 Logrus 实例,并使用 AddHook 方法将自定义的 MyHook 添加到 Logrus 中。之后,当我们记录日志时,MyHookFire 方法会被调用,并打印出调用日志的函数名和文件名。

  • 代码输出:

Caller: D:/goproject/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.windows-amd64/src/runtime/proc.go:272 runtime.main

time="2024-10-20T17:19:37+08:00" level=info msg="This is an informational message"

time="2024-10-20T17:19:37+08:00" level=warning msg="This is a warning message"

Caller: D:/goproject/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.2.windows-amd64/src/runtime/proc.go:272 runtime.main

到此这篇关于Golang日志库logrus的介绍与使用的文章就介绍到这了,更多相关Golang日志库logrus内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言实现钉钉发送通知

    Go语言实现钉钉发送通知

    本文通过代码给大家介绍了Go语言实现钉钉发送通知,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-11-11
  • Golang算法之田忌赛马问题实现方法分析

    Golang算法之田忌赛马问题实现方法分析

    这篇文章主要介绍了Golang算法之田忌赛马问题实现方法,结合具体实例形式分析了基于Go语言的田忌赛马问题原理与算法实现技巧,需要的朋友可以参考下
    2017-02-02
  • golang通过node_exporter监控GPU及cpu频率、温度的代码

    golang通过node_exporter监控GPU及cpu频率、温度的代码

    node_exporter这个开源组件是配合prometheus收集主机操作系统层的metrics的常用组件,但是官方没有提供GPU卡的metrics的采集,今天通过本文给大家介绍golang通过node_exporter监控GPU及cpu频率、温度的相关知识,感兴趣的朋友一起看看吧
    2022-05-05
  • go语言中的interface使用实例

    go语言中的interface使用实例

    这篇文章主要介绍了go语言中的interface使用实例,go语言中的interface是一组未实现的方法的集合,如果某个对象实现了接口中的所有方法,那么此对象就实现了此接口,需要的朋友可以参考下
    2015-05-05
  • Go语言中日志统一处理详解

    Go语言中日志统一处理详解

    在现代软件开发中,日志记录是一项至关重要的任务,它不仅帮助开发人员诊断问题,还有助于监控和维护应用程序,本文主要来和大家聊聊日志的统一处理,感兴趣的小伙伴可以了解下
    2024-01-01
  • golang中的三个点 ''...''的用法示例详解

    golang中的三个点 ''...''的用法示例详解

    这篇文章主要介绍了golang中的三个点 '...' 的用法示例详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 深入理解Golang channel的应用

    深入理解Golang channel的应用

    channel是用于 goroutine 之间的同步、通信的数据结构。它为程序员提供了更高一层次的抽象,封装了更多的功能,这样并发编程变得更加容易和安全。本文通过示例为大家详细介绍了channel的应用,需要的可以参考一下
    2022-10-10
  • 详解go语言是如何实现协程的

    详解go语言是如何实现协程的

    go语言的精华就在于协程的设计,只有理解协程的设计思想和工作机制,才能确保我们能够完全的利用协程编写强大的并发程序,所以本文将给大家介绍了go语言是如何实现协程的,文中有详细的代码讲解,需要的朋友可以参考下
    2024-04-04
  • Golang中Delve版本太低无法Debug的问题

    Golang中Delve版本太低无法Debug的问题

    这篇文章主要介绍了Golang中Delve版本太低无法Debug的问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Go语言中函数的参数传递与调用的基本方法

    Go语言中函数的参数传递与调用的基本方法

    这篇文章主要介绍了Go语言中函数的参数传递与调用的基本方法,是golang入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10

最新评论