Golang日志庫(kù)logrus的介紹與使用示例代碼
logrus概述
簡(jiǎn)介
Logrus 是一個(gè)流行的 Go 語(yǔ)言日志庫(kù),它提供了結(jié)構(gòu)化日志和多種日志級(jí)別的功能。Logrus 非常靈活,支持自定義日志格式和輸出,被許多 Go 語(yǔ)言項(xiàng)目廣泛使用
特點(diǎn)
完全兼容log標(biāo)準(zhǔn)庫(kù):Logrus 可以很容易地替換掉log標(biāo)準(zhǔn)庫(kù),因?yàn)樗鼘?shí)現(xiàn)了相同的接口
- 結(jié)構(gòu)化日志記錄:可以很容易地記錄字段數(shù)據(jù),這些數(shù)據(jù)隨后可以被其他日志處理系統(tǒng)解析
- 多個(gè)日志級(jí)別:Logrus 支持多種日志級(jí)別,包括:
Panic、Fatal、Error、Warn、Info、Debug和Trace - 易于集成:Logrus 可以與其他系統(tǒng)如syslog、Hook等集成,便于日志的集中管理和分析
- 高度可定制:可以通過(guò) Hooks 和格式化器來(lái)自定義日志的輸出格式和內(nèi)容
下載
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=Printlndebug的沒(méi)有輸出,是因?yàn)閘ogrus默認(rèn)的日志輸出等級(jí)是 info
日志級(jí)別
logrus.PanicLevel: 記錄日志,然后調(diào)用 panic()logrus.FatalLevel: 記錄日志,然后調(diào)用 os.Exit(1)logrus.ErrorLevel: 記錄錯(cuò)誤級(jí)別的日志logrus.WarnLevel: 記錄警告級(jí)別的日志logrus.InfoLevel: 記錄信息級(jí)別的日志logrus.DebugLevel: 記錄調(diào)試級(jí)別的日志logrus.TraceLevel: 記錄跟蹤級(jí)別的日志
package main
import (
"os"
"github.com/sirupsen/logrus"
)
func main() {
// 設(shè)置日志輸出到 os.Stdout
logrus.SetOutput(os.Stdout)
// 設(shè)置日志級(jí)別為 InfoLevel,這意味著 InfoLevel 及以上級(jí)別的日志會(huì)被記錄
logrus.SetLevel(logrus.InfoLevel)
// 記錄不同級(jí)別的日志
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.")
// 注意:通常不推薦在生產(chǎn)環(huán)境中使用 PanicLevel 和 FatalLevel,因?yàn)樗鼈儠?huì)導(dǎo)致程序退出。
// 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:添加一個(gè)字段到日志條目WithFields(fields log.Fields) *Entry:添加多個(gè)字段到日志條目WithError(err error) *Entry:添加錯(cuò)誤字段到日志條目
package main
import (
"os"
"github.com/sirupsen/logrus"
)
func main() {
// 設(shè)置日志輸出到 os.Stdout
logrus.SetOutput(os.Stdout)
// 設(shè)置日志格式為 JSON,這對(duì)于結(jié)構(gòu)化日志記錄很有用
logrus.SetFormatter(&logrus.JSONFormatter{})
// 使用 WithField 方法添加一個(gè)字段
logEntry := logrus.WithField("user", "Alice")
// 使用 WithFields 方法添加多個(gè)字段
logEntry = logEntry.WithFields(logrus.Fields{
"operation": "login",
"result": "success",
})
// 記錄一條包含字段的日志
logEntry.Info("User logged in successfully")
// 使用 WithError 方法添加一個(gè)錯(cuò)誤字段
err := fmt.Errorf("something went wrong")
logEntry.WithError(err).Error("An error occurred")
}輸出
日志樣式
顯示行號(hào)
logrus.SetReportCaller(true)
樣式設(shè)置
默認(rèn)的是以text的形式展示,也可以設(shè)置為jsong樣式
textLogger := logrus.New()
// 創(chuàng)建一個(gè) TEXT 格式的日志記錄器
textLogger.SetFormatter(&logrus.TextFormatter{
DisableColors: false,
FullTimestamp: true,
})
// 創(chuàng)建一個(gè) JSON 格式的日志記錄器
jsonLogger := logrus.New()
jsonLogger.SetFormatter(&logrus.JSONFormatter{})輸出地址
SetOutput(io.Writer):設(shè)置日志的輸出目的地SetFormatter(formatter Formatter):設(shè)置日志的格式化器
package main
import (
"os"
"github.com/sirupsen/logrus"
)
func main() {
// 創(chuàng)建一個(gè)新的 Logrus 實(shí)例
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,你可以獲取日志內(nèi)容
logBytes := buffer.Bytes()
os.Stdout.Write(logBytes) // 將 buffer 中的內(nèi)容輸出到 os.Stdout
}日志顏色
默認(rèn)顏色
- DebugLevel: 藍(lán)色
- InfoLevel: 綠色
- WarningLevel: 黃色
- ErrorLevel: 紅色
- FatalLevel: 紅色(通常伴隨有其他指示,比如退出程序)
- PanicLevel: 紅色(通常伴隨有 panic)
禁用顏色
log.SetFormatter(&logrus.TextFormatter{
DisableColors: true,
})自定義顏色
- 創(chuàng)建一個(gè)新的
TextFormatter結(jié)構(gòu)體 - 重寫(xiě)
Format方法,在格式化日志時(shí)添加自定義顏色代碼 - 將自定義的
Formatter設(shè)置給 Logrus 實(shí)例
自定義格式
通過(guò)實(shí)現(xiàn) logrus.Formatter 接口來(lái)自定義日志格式
package main
import (
"bytes"
"fmt"
"github.com/sirupsen/logrus"
"os"
)
// CustomFormatter 自定義格式化器
type CustomFormatter struct {
logrus.TextFormatter
}
// Format 實(shí)現(xiàn) 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" // 藍(lán)色
case logrus.InfoLevel:
color = "\x1b[32m" // 綠色
case logrus.WarnLevel:
color = "\x1b[33m" // 黃色
case logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel:
color = "\x1b[31m" // 紅色
}
// 寫(xiě)入顏色代碼和日志內(nèi)容
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 結(jié)構(gòu)體實(shí)現(xiàn)了 Format 方法,該方法接收一個(gè) logrus.Entry 對(duì)象,該對(duì)象包含了日志條目的所有信息,包括時(shí)間戳、日志級(jí)別、消息和字段。Format 方法將這些信息格式化為一個(gè)字符串,并返回字節(jié)數(shù)組。
[2024-10-20T17:14:22+08:00] [info] A group of walrus emerges from the ocean size=10 animal=walrus
Hook
- 在 Logrus 中,
Hook是一個(gè)接口,允許你添加自定義的邏輯,這些邏輯會(huì)在日志記錄之前或之后執(zhí)行。通過(guò)實(shí)現(xiàn)logrus.Hook接口,你可以創(chuàng)建自己的鉤子來(lái)執(zhí)行額外的操作,比如發(fā)送日志到遠(yuǎn)程系統(tǒng)、寫(xiě)入數(shù)據(jù)庫(kù)、執(zhí)行特定的監(jiān)控檢查等。 - 在 Logrus 中,
Hook的基本用法涉及以下步驟: - 定義一個(gè) Hook 結(jié)構(gòu)體:這個(gè)結(jié)構(gòu)體需要實(shí)現(xiàn)
Levels()和Fire(entry *logrus.Entry) error方法。 - 實(shí)現(xiàn)
Levels()方法:這個(gè)方法返回一個(gè)logrus.Level切片,表示該 Hook 將被哪些日志級(jí)別觸發(fā)。 - 實(shí)現(xiàn)
Fire(entry \*logrus.Entry) error方法:這個(gè)方法定義了當(dāng)日志被記錄時(shí)應(yīng)該執(zhí)行的邏輯。 - 將 Hook 添加到 Logrus 實(shí)例:使用
log.AddHook(hook)方法。
自定義 Hook 示例,它會(huì)在每次記錄日志時(shí)打印出當(dāng)前的函數(shù)名和文件名:
package main
import (
"fmt"
"runtime"
"github.com/sirupsen/logrus"
)
// MyHook 是一個(gè)自定義的 Logrus 鉤子
type MyHook struct {
}
// Levels 定義了這個(gè)鉤子會(huì)被哪些日志級(jí)別觸發(fā)
func (hook *MyHook) Levels() []logrus.Level {
return logrus.AllLevels
}
// Fire 是每次日志記錄時(shí)都會(huì)調(diào)用的方法
func (hook *MyHook) Fire(entry *logrus.Entry) error {
// 獲取調(diào)用者的函數(shù)名和文件名
pc, file, line, ok := runtime.Caller(8) // 8 是調(diào)用棧的深度,可能需要根據(jù)你的代碼結(jié)構(gòu)進(jìn)行調(diào)整
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結(jié)構(gòu)體實(shí)現(xiàn)了Levels和Fire方法。Levels方法返回一個(gè)日志級(jí)別切片,表示這個(gè)鉤子會(huì)對(duì)哪些級(jí)別的日志進(jìn)行響應(yīng)。在這個(gè)例子中,我們使用logrus.AllLevels,這意味著它會(huì)對(duì)所有級(jí)別的日志做出響應(yīng)。
Fire 方法會(huì)在每次記錄日志時(shí)被調(diào)用。在這個(gè)方法中,我們使用 runtime.Caller 來(lái)獲取調(diào)用日志記錄函數(shù)的函數(shù)名和文件名,并打印出來(lái)。
在 main 函數(shù)中,我們創(chuàng)建了一個(gè) Logrus 實(shí)例,并使用 AddHook 方法將自定義的 MyHook 添加到 Logrus 中。之后,當(dāng)我們記錄日志時(shí),MyHook 的 Fire 方法會(huì)被調(diào)用,并打印出調(diào)用日志的函數(shù)名和文件名。
- 代碼輸出:
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
到此這篇關(guān)于Golang日志庫(kù)logrus的介紹與使用的文章就介紹到這了,更多相關(guān)Golang日志庫(kù)logrus內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Go語(yǔ)言實(shí)現(xiàn)一個(gè)并發(fā)端口掃描器
這篇文章主要介紹了如何使用 Go 實(shí)現(xiàn)一個(gè)并發(fā)端口掃描器,通過(guò) Goroutine 并發(fā)掃描多個(gè)端口,極大地提升端口掃描的效率,本文不僅講解了如何使用 Go 的并發(fā)特性,還涉及了如何處理超時(shí)和錯(cuò)誤,保證端口掃描的健壯性和效率,需要的朋友可以參考下2025-08-08
關(guān)于go語(yǔ)言載入json可能遇到的一個(gè)坑
Go 語(yǔ)言從新手到大神,每個(gè)人多少都會(huì)踩一些坑,那么下面這篇文章主要給大家介紹了關(guān)于go語(yǔ)言載入json可能遇到的一個(gè)坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-07-07
Go語(yǔ)言的隊(duì)列和堆棧實(shí)現(xiàn)方法
這篇文章主要介紹了Go語(yǔ)言的隊(duì)列和堆棧實(shí)現(xiàn)方法,涉及container/list包的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02
Go開(kāi)發(fā)Gin項(xiàng)目添加jwt功能實(shí)例詳解
這篇文章主要為大家介紹了Go開(kāi)發(fā)Gin項(xiàng)目中添加jwt功能實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
為什么Go里值為nil可以調(diào)用函數(shù)原理分析
這篇文章主要為大家介紹了為什么Go里值為nil可以調(diào)用函數(shù)原理分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

