前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >手把手,带你从零封装Gin框架(十一):使用文件记录错误日志 & 跨域处理

手把手,带你从零封装Gin框架(十一):使用文件记录错误日志 & 跨域处理

作者头像
用户10002156
发布2024-01-23 15:56:05
6650
发布2024-01-23 15:56:05
举报
文章被收录于专栏:生活处处有BUG

前言

Gin 框架的日志默认是在控制台输出,本篇将使用 Gin 提供的 RecoveryWithWriter() 方法,封装一个中间件,使用 lumberjack 作为的写入器,将错误日志写入文件中;同时使用 github.com/gin-contrib/cors ,作下跨域处理。

安装

代码语言:javascript
复制
go get -u gopkg.in/natefinch/lumberjack.v2
go get github.com/gin-contrib/cors

Recovery 中间件

app/common/response/response.go 文件中,添加 ServerError() 方法,作为 RecoveryFunc

代码语言:javascript
复制
package response

import (
    "github.com/gin-gonic/gin"
    "jassue-gin/global"
    "net/http"
    "os"
)

// ...

func ServerError(c *gin.Context, err interface{}) {
    msg := "Internal Server Error"
    // 非生产环境显示具体错误信息
    if global.App.Config.App.Env != "production" && os.Getenv(gin.EnvGinMode) != gin.ReleaseMode {
        if _, ok := err.(error); ok {
            msg = err.(error).Error()
        }
    }
    c.JSON(http.StatusInternalServerError, Response{
        http.StatusInternalServerError,
        nil,
        msg,
    })
    c.Abort()
}
// ...

新建 app/middleware/recovery.go 文件,编写:

代码语言:javascript
复制
package middleware

import (
    "github.com/gin-gonic/gin"
    "gopkg.in/natefinch/lumberjack.v2"
    "jassue-gin/app/common/response"
    "jassue-gin/global"
)

func CustomRecovery() gin.HandlerFunc {
    return gin.RecoveryWithWriter(
        &lumberjack.Logger{
            Filename:   global.App.Config.Log.RootDir + "/" + global.App.Config.Log.Filename,
            MaxSize:    global.App.Config.Log.MaxSize,
            MaxBackups: global.App.Config.Log.MaxBackups,
            MaxAge:     global.App.Config.Log.MaxAge,
            Compress:   global.App.Config.Log.Compress,
        },
        response.ServerError)
}

CORS 跨域处理

新建 app/middleware/cors.go 文件,编写:

代码语言:javascript
复制
package middleware

import (
    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
)

func Cors() gin.HandlerFunc {
    config := cors.DefaultConfig()
    config.AllowAllOrigins = true
    config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization"}
    config.AllowCredentials = true
    config.ExposeHeaders = []string{"New-Token", "New-Expires-In", "Content-Disposition"}

    return cors.New(config)
}

使用中间件

bootstrap/router.go 文件,编写:

代码语言:javascript
复制
func setupRouter() *gin.Engine {
    if global.App.Config.App.Env == "production" {
        gin.SetMode(gin.ReleaseMode)
    }
    router := gin.New()
    router.Use(gin.Logger(), middleware.CustomRecovery())

    // 跨域处理
    // router.Use(middleware.Cors())

    // ...
}

测试

为了演示,这里我故意将数据库配置写错,请求登录接口,中间件成功生效

image-20231005192124398

接着查看 storage/logs/app.log 文件,错误信息成功写入到文件,内容如下:

代码语言:javascript
复制
runtime error: invalid memory address or nil pointer dereference
C:/Program Files/Go/src/runtime/panic.go:260 (0xeeb846)
    panicmem: panic(memoryError)
C:/Program Files/Go/src/runtime/signal_windows.go:257 (0xeeb816)
    sigpanic: panicmem()
C:/Users/xj/go/pkg/mod/gorm.io/gorm@v1.25.4/gorm.go:399 (0x14a8398)
    (*DB).getInstance: if db.clone > 0 {
C:/Users/xj/go/pkg/mod/gorm.io/gorm@v1.25.4/chainable_api.go:201 (0x149dfbb)
    (*DB).Where: tx = db.getInstance()
C:/www/go-project-demo/app/services/user.go:31 (0x1652c1e)
    (*userService).Login: err = global.App.DB.Where("mobile = ?", params.Mobile).First(&user).Error
C:/www/go-project-demo/app/controllers/app/auth.go:18 (0x1653d78)
    Login: if err, user := services.UserService.Login(form); err != nil {
C:/Users/xj/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 (0x163bfe1)
    (*Context).Next: c.handlers[c.index](c)
C:/Users/xj/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/recovery.go:102 (0x163bfcc)
    CustomRecoveryWithWriter.func1: c.Next()
C:/Users/xj/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 (0x163b106)
    (*Context).Next: c.handlers[c.index](c)
C:/Users/xj/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/logger.go:240 (0x163b0e9)
    LoggerWithConfig.func1: c.Next()
C:/Users/xj/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 (0x163a1aa)
    (*Context).Next: c.handlers[c.index](c)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生活处处有BUG 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 安装
  • Recovery 中间件
  • CORS 跨域处理
  • 使用中间件
  • 测试
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档