golang结构化日志记录插件库logrus的使用
Golang 结构化日志记录插件库 logrus 的使用
Logrus 是 Go 语言的一个结构化日志记录库,完全兼容标准库 logger 的 API。
基础使用
简单示例
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
}).Info("A walrus appears")
}
配置示例
package main
import (
"os"
log "github.com/sirupsen/logrus"
)
func init() {
// 使用 JSON 格式而不是默认的 ASCII 格式
log.SetFormatter(&log.JSONFormatter{})
// 输出到 stdout 而不是默认的 stderr
log.SetOutput(os.Stdout)
// 只记录 warning 级别及以上的日志
log.SetLevel(log.WarnLevel)
}
func main() {
log.WithFields(log.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
log.WithFields(log.Fields{
"omg": true,
"number": 122,
}).Warn("The group's number increased tremendously!")
log.WithFields(log.Fields{
"omg": true,
"number": 100,
}).Fatal("The ice breaks!")
}
日志级别
Logrus 有七个日志级别:Trace, Debug, Info, Warning, Error, Fatal 和 Panic。
log.Trace("Something very low level.")
log.Debug("Useful debugging information.")
log.Info("Something noteworthy happened!")
log.Warn("You should probably take a look at this.")
log.Error("Something failed but I'm not quitting.")
log.Fatal("Bye.") // 调用 os.Exit(1)
log.Panic("I'm bailing.") // 调用 panic()
字段
Logrus 鼓励使用字段进行结构化日志记录:
log.WithFields(log.Fields{
"event": event,
"topic": topic,
"key": key,
}).Fatal("Failed to send event")
默认字段
可以为日志条目设置默认字段:
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
requestLogger.Info("something happened on that request")
requestLogger.Warn("something not great happened")
日志格式
TextFormatter (默认)
log.SetFormatter(&log.TextFormatter{
DisableColors: true,
FullTimestamp: true,
})
JSONFormatter
log.SetFormatter(&log.JSONFormatter{})
自定义格式
可以实现 Formatter
接口来自定义格式:
type MyJSONFormatter struct {
}
log.SetFormatter(new(MyJSONFormatter))
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
serialized, err := json.Marshal(entry.Data)
if err != nil {
return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
}
return append(serialized, '\n'), nil
}
钩子(Hooks)
可以添加钩子来处理特定级别的日志:
import (
log "github.com/sirupsen/logrus"
"gopkg.in/gemnasium/logrus-airbrake-hook.v2"
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
"log/syslog"
)
func init() {
log.AddHook(airbrake.NewHook(123, "xyz", "production"))
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
if err != nil {
log.Error("Unable to connect to local syslog daemon")
} else {
log.AddHook(hook)
}
}
测试
Logrus 提供了测试工具:
import(
"github.com/sirupsen/logrus"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
"testing"
)
func TestSomething(t *testing.T){
logger, hook := test.NewNullLogger()
logger.Error("Helloerror")
assert.Equal(t, 1, len(hook.Entries))
assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
assert.Equal(t, "Helloerror", hook.LastEntry().Message)
hook.Reset()
assert.Nil(t, hook.LastEntry())
}
完整示例
package main
import (
"os"
log "github.com/sirupsen/logrus"
)
func init() {
// 设置日志格式为 JSON
log.SetFormatter(&log.JSONFormatter{})
// 设置输出到标准输出
log.SetOutput(os.Stdout)
// 设置日志级别
log.SetLevel(log.InfoLevel)
// 启用调用者信息
log.SetReportCaller(true)
}
func main() {
// 基础日志
log.Info("Starting application")
// 带字段的日志
log.WithFields(log.Fields{
"component": "user",
"action": "login",
"user_id": 12345,
}).Info("User logged in")
// 错误日志
log.WithFields(log.Fields{
"error": "connection timeout",
"attempts": 3,
"service": "database",
}).Error("Failed to connect to database")
// 创建带默认字段的记录器
contextLogger := log.WithFields(log.Fields{
"request_id": "abc123",
"ip": "192.168.1.1",
})
contextLogger.Info("Request started")
contextLogger.Warn("Request taking longer than expected")
// 致命错误
log.WithFields(log.Fields{
"error": "disk full",
}).Fatal("Cannot continue execution")
}
Logrus 是一个功能强大且灵活的结构化日志记录库,适合在各种规模的 Go 项目中使用。
更多关于golang结构化日志记录插件库logrus的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang结构化日志记录插件库logrus的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
logrus - Go语言结构化日志记录库
logrus是Go语言中最流行的结构化日志记录库之一,它提供了丰富的日志功能和灵活的配置选项。下面我将详细介绍logrus的使用方法。
基本安装与导入
首先安装logrus:
go get github.com/sirupsen/logrus
然后导入:
import (
log "github.com/sirupsen/logrus"
)
基本用法
package main
import (
log "github.com/sirupsen/logrus"
)
func main() {
// 基本日志输出
log.Info("This is an info message")
log.Warn("This is a warning message")
log.Error("This is an error message")
// 带字段的日志
log.WithFields(log.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
}
日志级别
logrus支持7个日志级别:
log.Trace("Very low level debug information")
log.Debug("Debug information")
log.Info("General operational entries")
log.Warn("Non-critical issues")
log.Error("Errors that should definitely be noted")
log.Fatal("Critical errors - calls os.Exit(1)")
log.Panic("Highest level of severity - calls panic()")
设置日志级别:
func main() {
// 只记录警告及以上级别的日志
log.SetLevel(log.WarnLevel)
log.Info("This won't be logged") // 不会输出
log.Warn("This will be logged") // 会输出
}
日志格式
logrus支持多种日志格式:
func main() {
// 文本格式(默认)
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
})
// JSON格式
log.SetFormatter(&log.JSONFormatter{})
log.WithFields(log.Fields{
"event": "purchase",
"amount": 123.45,
}).Info("Order processed")
}
钩子(Hooks)
logrus支持钩子,可以在日志记录前后执行自定义操作:
type MyHook struct{}
func (hook *MyHook) Levels() []log.Level {
return log.AllLevels
}
func (hook *MyHook) Fire(entry *log.Entry) error {
// 在这里可以添加自定义逻辑,如发送日志到远程服务器
entry.Data["custom_field"] = "custom_value"
return nil
}
func main() {
log.AddHook(&MyHook{})
log.Info("This log will have a custom field")
}
文件输出
将日志输出到文件:
import (
"os"
log "github.com/sirupsen/logrus"
)
func main() {
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(file)
} else {
log.Info("Failed to log to file, using default stderr")
}
log.Info("This will be written to the log file")
}
上下文日志
可以创建带有预设字段的日志实例:
func main() {
logger := log.WithFields(log.Fields{
"app": "myapp",
"env": "production",
})
logger.Info("Starting application")
logger.WithField("user", "john").Info("User logged in")
}
性能优化
对于高性能场景,可以使用Entry的日志方法:
func main() {
logger := log.WithFields(log.Fields{
"component": "user",
})
// 更高效的方式
entry := logger.WithField("method", "login")
entry.Info("User login attempt")
entry.WithField("ip", "192.168.1.1").Info("User login from IP")
}
实际应用示例
package main
import (
"os"
log "github.com/sirupsen/logrus"
)
func initLogger() {
// 设置JSON格式
log.SetFormatter(&log.JSONFormatter{})
// 设置输出到标准输出和文件
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
log.SetOutput(file)
} else {
log.Info("Failed to log to file, using default stderr")
}
// 设置日志级别
log.SetLevel(log.InfoLevel)
}
func main() {
initLogger()
// 创建带有应用信息的日志实例
appLogger := log.WithFields(log.Fields{
"app": "my-application",
"version": "1.0.0",
})
appLogger.Info("Application starting")
// 处理请求示例
processRequest(appLogger, "user123", "/api/data")
appLogger.Info("Application shutting down")
}
func processRequest(logger *log.Entry, userID, path string) {
requestLogger := logger.WithFields(log.Fields{
"user": userID,
"path": path,
})
requestLogger.Info("Processing request")
// 模拟业务逻辑
if path == "/api/data" {
requestLogger.WithField("data", "sensitive").Warn("Accessing sensitive data")
}
requestLogger.Info("Request processed")
}
logrus提供了强大而灵活的日志记录功能,特别适合需要结构化日志的应用程序。通过合理配置,可以满足从开发调试到生产环境的各种日志需求。