本文介绍: Logrus 是一个用于 Go 语言的结构化日志框架,它提供了丰富的日志级别、钩子和格式化选项。代码中导入Loglus可以添加一个 TraceLevel 级别来更详细地跟踪程序的执行流程import (使用钩子来实现自定义的日志处理逻辑。import (“net/smtp“// 设置日志级别和输出格式// 添加邮件钩子return nil},})// 实现发送邮件的逻辑。
前言
Logrus 是一个用于 Go 语言的结构化日志框架,它提供了丰富的日志级别、钩子和格式化选项。
环境搭建:
go get github.com/sirupsen/logrus
import (
"github.com/sirupsen/logrus"
)
Loglus常见用法
自定义日志级别
可以添加一个 TraceLevel 级别来更详细地跟踪程序的执行流程
package main
import (
"github.com/sirupsen/logrus"
)
var TraceLevel = logrus.Level(6)
func main() {
logger := logrus.New()
logger.SetLevel(TraceLevel)
logger.Trace("This is a trace level log")
}
使用字段钩子
使用字段钩子来在日志中添加额外的字段信息。例如,你可以添加一个钩子来记录每条日志的时间戳:
package main
import (
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})
logger.AddHook(&logrus.FieldHook{
Field: "timestamp",
Func: func() (interface{}, error) {
return time.Now().Format("2006-01-02T15:04:05.999Z07:00"), nil
},
})
logger.Info("This is a log entry with timestamp field")
}
输出到多个位置
可以将日志同时输出到多个位置,比如标准输出和文件。以下是一个示例,将日志同时输出到控制台和文件中:
package main
import (
"os"
"io"
"github.com/sirupsen/logrus"
)
func main() {
logger := logrus.New()
// 设置日志级别和输出格式
// 输出到控制台
logger.SetOutput(os.Stdout)
// 输出到文件
file, err := os.OpenFile("logfile.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
mw := io.MultiWriter(os.Stdout, file)
logger.SetOutput(mw)
} else {
logger.Info("Failed to log to file, using default stderr")
}
logger.Info("This log entry will be output to both console and file")
}
使用钩子实现自定义日志处理
使用钩子来实现自定义的日志处理逻辑。例如,你可以添加一个邮件钩子,在产生错误日志时发送邮件通知:
package main
import (
"github.com/sirupsen/logrus"
"net/smtp"
)
func main() {
logger := logrus.New()
// 设置日志级别和输出格式
// 添加邮件钩子
logger.AddHook(&logrus.Hook{
Levels: []logrus.Level{logrus.ErrorLevel, logrus.FatalLevel},
Fire: func(entry *logrus.Entry) error {
sendEmailNotification(entry.Message)
return nil
},
})
logger.Error("An error occurred, email notification will be sent")
}
func sendEmailNotification(message string) {
// 实现发送邮件的逻辑
}
demo
package middleware
import (
"fmt"
"github.com/gin-gonic/gin"
retalog "github.com/lestrrat-go/file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"log"
"math"
"os"
"path"
"time"
)
// SetOutputFile 设置输出文件名称,如果没有就创建
func SetOutputFile() (*os.File, string, error) {
now := time.Now()
logFilePath := ""
if dir, err := os.Getwd(); err == nil {
logFilePath = dir + "/logs"
}
_, err := os.Stat(logFilePath)
if os.IsNotExist(err) {
if err := os.MkdirAll(logFilePath, 0777); err != nil {
log.Println(err.Error())
return nil, "", err
}
}
logFileName := now.Format("2006-01-02") + ".log"
filePath := path.Join(logFilePath, logFileName)
if _, err := os.Stat(filePath); err != nil {
if _, err := os.Create(filePath); err != nil {
log.Println(err.Error())
return nil, "", err
}
}
src, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
fmt.Println("err: ", err)
return nil, "", err
}
log.Println("create log path: ", filePath)
return src, filePath, nil
}
// Logger 日志,此操作可以复用
func Logger() gin.HandlerFunc {
//建立软连接,需要管理员权限
linkName := "latest_log.log"
//设置日志文件的路径
src, filePath, _ := SetOutputFile()
//创建日志
logger := logrus.New()
//输出
logger.Out = src
//设置日志级别
logger.SetLevel(logrus.DebugLevel)
// 显示日志行数
//logger.SetReportCaller(true)
//添加时间分割
logWriter, _ := retalog.New(
filePath,
retalog.WithMaxAge(14*24*time.Hour), //日志保留时间:2周
retalog.WithRotationTime(24*time.Hour), //24小时分割一次
retalog.WithLinkName(linkName), //建立软连接
)
writeMap := lfshook.WriterMap{
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
logrus.DebugLevel: logWriter,
logrus.WarnLevel: logWriter,
logrus.ErrorLevel: logWriter,
logrus.PanicLevel: logWriter,
}
//实例化
Hook := lfshook.NewHook(writeMap, &logrus.TextFormatter{
TimestampFormat: "2006-01-02 15:04:05",
})
logger.AddHook(Hook)
return func(c *gin.Context) {
startTime := time.Now()
c.Next()
stopTime := time.Since(startTime)
spendTime := fmt.Sprintf("%d ms", int(math.Ceil(float64(stopTime.Nanoseconds()/1000000.0))))
hostName, err := os.Hostname()
if err != nil {
hostName = "unknown"
}
statusCode := c.Writer.Status()
clientIp := c.ClientIP()
//userAgent := c.Request.UserAgent()
dataSize := c.Writer.Size()
if dataSize < 0 {
dataSize = 0
}
method := c.Request.Method
requestPath := c.Request.RequestURI
entry := logger.WithFields(logrus.Fields{
"HostName": hostName,
"status": statusCode,
"SpendTime": spendTime,
"Ip": clientIp,
"Method": method,
"Path": requestPath,
"DataSize": dataSize,
//"Agent": userAgent, // TODO: UA
})
if len(c.Errors) > 0 {
entry.Error(c.Errors.ByType(gin.ErrorTypePrivate).String())
}
if statusCode >= 500 {
entry.Error()
} else if statusCode >= 400 {
entry.Warn()
} else {
entry.Info()
}
}
}
在gin中调用Logger()
r := gin.New()
r.Use(gin.Recovery())
r.Use(middleware.Logger())
原文地址:https://blog.csdn.net/baidu_33256174/article/details/134766326
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_37888.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。