logrus概述
简介
logrus 是一个流行的 go 语言日志库,它提供了结构化日志和多种日志级别的功能。logrus 非常灵活,支持自定义日志格式和输出,被许多 go 语言项目广泛使用
特点
完全兼容log
标准库:logrus 可以很容易地替换掉log
标准库,因为它实现了相同的接口
- 结构化日志记录:可以很容易地记录字段数据,这些数据随后可以被其他日志处理系统解析
- 多个日志级别:logrus 支持多种日志级别,包括:
panic
、fatal
、error
、warn
、info
、debug
和trace
- 易于集成: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
结构体实现了levels
和fire
方法。levels
方法返回一个日志级别切片,表示这个钩子会对哪些级别的日志进行响应。在这个例子中,我们使用logrus.alllevels
,这意味着它会对所有级别的日志做出响应。
fire
方法会在每次记录日志时被调用。在这个方法中,我们使用 runtime.caller
来获取调用日志记录函数的函数名和文件名,并打印出来。
在 main
函数中,我们创建了一个 logrus 实例,并使用 addhook
方法将自定义的 myhook
添加到 logrus 中。之后,当我们记录日志时,myhook
的 fire
方法会被调用,并打印出调用日志的函数名和文件名。
- 代码输出:
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内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论