go fiber: 把异常信息写到错误日志中
一,代码:
1,userBusiness.go
package business
import ("fmt")
//得到多个用户,按分页返回
func GetUserList(page int ,pageSize int) (string,error) {
b := 0
a:=100/b
fmt.Println(a)
return "1,2,3",nil
}
代码中包含有除0错,会引发panic
2,userController.go
它用调用包含除0错的userBusiness
package controller
import (
"github.com/gofiber/fiber/v2"
//"time"
"industry/business"
"fmt"
)
type UserController struct{}
func NewUserController() *UserController {
return &UserController{}
}
func (dc *UserController) ListUser(c *fiber.Ctx) error {
// 处理列出用户的逻辑
list,_:=business.GetUserList(1,30)
fmt.Println(list)
return c.SendString("列出用户")
}
3,recoverMiddleware.go
参考了fiber官方的recover类,添加了写日志功能
package middleware
import (
"fmt"
//"os"
"runtime/debug"
"time"
"github.com/gofiber/fiber/v2"
"industry/config"
)
//在中间件中得到panic,获取堆栈后写入到日志中
func NewRecover(c *fiber.Ctx) (err error) { //nolint:nonamedreturns // Uses recover() to overwrite the error
// Catch panics
defer func() {
if r := recover(); r != nil {
// fmt.Printf("panic: %v\n%s\n", r.(error), debug.Stack())
timeStr:=time.Now().Format("2006-01-02 15:04:05")
//得到时间,ip地址,请求的地址,参数,user-agent,
fullURL := c.OriginalURL() //url
clientIP := c.IP() //ip地址
method := c.Method() // 获取请求方法
userAgent := c.Get("User-Agent") //user agent
// 获取所有查询参数
queryParams := fmt.Sprintf("%v",c.Queries())
fmt.Println("Query Params:", queryParams)
filename:="/data/logs/gologs/exception-" + time.Now().Format("2006-01-02") + ".log"
content:="["+timeStr+"] "+r.(error).Error()+"\n"+clientIP+" "+method+" "+fullURL+" "+userAgent+"\n"+queryParams+"\n"+string(debug.Stack())+"\n"
config.GlobalWriteFile(filename,content)
var ok bool
if err, ok = r.(error); !ok {
// Set error that will call the global error handler
err = fmt.Errorf("%v", r)
}
}
}()
// Return err if exist, else move to next handler
return c.Next()
}
4,routes.go
package routes
import (
"github.com/gofiber/fiber/v2"
"industry/controller"
"runtime/debug"
"industry/middleware"
"fmt"
)
func SetupRoutes() *fiber.App {
app := fiber.New(fiber.Config{
ErrorHandler: func(c *fiber.Ctx, err error) error {
// 发送自定义错误页面
//return c.Status(code).JSON(config.Error("内部错误:"+err.Error()))
return c.SendString("内部错误:"+err.Error())
},
})
app.Use(middleware.NewRecover)
//用户模块
userController := controller.NewUserController()
user := app.Group("/user")
user.Get("/info", userController.GetUser)
user.Post("/", userController.CreateUser)
user.Get("/list", userController.ListUser)
return app
}
5,写日志的类:
package config
import (
"os"
"fmt"
)
// filename:文件路径,content:要写的内容
func GlobalWriteFile(filename,content string) error {
// 输出到文件
file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
fmt.Println("日志文件的打开错误 : " + err.Error())
return err
}
defer file.Close()
if _, err := file.WriteString(content); err != nil {
fmt.Println("写入日志文件错误 : " + err.Error())
return err
}
return nil
}
二,测试效果:
[2024-11-14 17:56:51] runtime error: integer divide by zero
192.168.219.1 POST /user/list?token=111&a=22&c=33 PostmanRuntime/7.42.0
map[a:22 c:33 token:111]
goroutine 21 [running]:
runtime/debug.Stack()
/usr/local/soft/go/src/runtime/debug/stack.go:26 +0x5e
industry/middleware.NewRecover.func1()
/data/goapp/industry/middleware/recoverMiddleware.go:37 +0x29a
panic({0x6f9360?, 0xa08960?})
/usr/local/soft/go/src/runtime/panic.go:785 +0x132
industry/business.GetUserList(0x7f008002000000?, 0xc00005ba80?)
/data/goapp/industry/business/userBusiness.go:9 +0x9
industry/controller.(*UserController).ListUser(0x467edd?, 0xc00014e008)
/data/goapp/industry/controller/userController.go:29 +0x26
github.com/gofiber/fiber/v2.(*App).next(0xc0000e4a08, 0xc00014e008)
/data/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.5/router.go:145 +0x1be
github.com/gofiber/fiber/v2.(*Ctx).Next(0x10?)
/data/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.5/ctx.go:1034 +0x4d
industry/middleware.NewRecover(0x6f65e0?)
/data/goapp/industry/middleware/recoverMiddleware.go:50 +0x53
github.com/gofiber/fiber/v2.(*App).next(0xc0000e4a08, 0xc00014e008)
/data/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.5/router.go:145 +0x1be
github.com/gofiber/fiber/v2.(*App).handler(0xc0000e4a08, 0x4adc0f?)
/data/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.5/router.go:172 +0x69
github.com/valyala/fasthttp.(*Server).serveConn(0xc0000ec248, {0x7d3198, 0xc0000ac1e0})
/data/gopath/pkg/mod/github.com/valyala/fasthttp@v1.57.0/server.go:2385 +0xed1
github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc00011a090, 0xc0000e63a0)
/data/gopath/pkg/mod/github.com/valyala/fasthttp@v1.57.0/workerpool.go:225 +0x92
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
/data/gopath/pkg/mod/github.com/valyala/fasthttp@v1.57.0/workerpool.go:197 +0x32
created by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1
/data/gopath/pkg/mod/github.com/valyala/fasthttp@v1.57.0/workerpool.go:196 +0x194