GO常用web框架之gin学习笔记(5)| 青训营笔记

95 阅读4分钟

[ go 与 golang | 青训营笔记]

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天, 在学习了go的相关基础知识以后,可以说是初步的了解了go,接下来,我们将步入全新的环节,今天我们学习go的一个常用web框架gin

因为昨天审核的一些原因,gin的一些知识点还剩下两节,我们今天补充完毕后开启新的框架学习

中间件案例

权限验证

以前后端最流行的jwt为例,如果用户登录了,前端发来的每一次请求都会在请求头上携带上token

后台拿到这个token进行校验,验证是否过期,是否非法

如果通过就说明这个用户是登录过的

不通过就说明用户没有登录

package main

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

func JwtTokenMiddleware(c *gin.Context) {
  // 获取请求头的token
  token := c.GetHeader("token")
  // 调用jwt的验证函数
  if token == "1234" {
    // 验证通过
    c.Next()
    return
  }
  // 验证不通过
  c.JSON(200, gin.H{"msg": "权限验证失败"})
  c.Abort()
}

func main() {
  router := gin.Default()

  api := router.Group("/api")

  apiUser := api.Group("")
  {
    apiUser.POST("login", func(c *gin.Context) {
      c.JSON(200, gin.H{"msg": "登录成功"})
    })
  }
  apiHome := api.Group("system").Use(JwtTokenMiddleware)
  {
    apiHome.GET("/index", func(c *gin.Context) {
      c.String(200, "index")
    })
    apiHome.GET("/home", func(c *gin.Context) {
      c.String(200, "home")
    })
  }

  router.Run(":8080")
}

耗时统计

统计每一个视图函数的执行时间

func TimeMiddleware(c *gin.Context) {
  startTime := time.Now()
  c.Next()
  since := time.Since(startTime)
  // 获取当前请求所对应的函数
  f := c.HandlerName()
  fmt.Printf("函数 %s 耗时 %d\n", f, since)
}

9. 日志

为什么要使用日志

  1. 记录用户操作,猜测用户行为
  2. 记录bug

gin自带日志系统

输出日志到log文件

package main

import (
  "github.com/gin-gonic/gin"
  "io"
  "os"
)

func main() {
  // 输出到文件
  f, _ := os.Create("gin.log")
  //gin.DefaultWriter = io.MultiWriter(f)
  // 如果需要同时将日志写入文件和控制台,请使用以下代码。
  gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
  router := gin.Default()
  router.GET("/", func(c *gin.Context) {
    c.JSON(200, gin.H{"msg": "/"})
  })
  router.Run()
}

定义路由格式

启动gin,它会显示所有的路由,默认格式如下

[GIN-debug] POST   /foo    --> main.main.func1 (3 handlers)
[GIN-debug] GET    /bar    --> main.main.func2 (3 handlers)
[GIN-debug] GET    /status --> main.main.func3 (3 handlers)
gin.DebugPrintRouteFunc = func(
  httpMethod,
  absolutePath,
  handlerName string,
  nuHandlers int) {
  log.Printf(
    "[ ran ] %v %v %v %v\n",
    httpMethod,
    absolutePath,
    handlerName,
    nuHandlers,
  )
}
/*  输出如下
2022/12/11 14:10:28 [ ran ] GET / main.main.func3 3
2022/12/11 14:10:28 [ ran ] POST /index main.main.func4 3
2022/12/11 14:10:28 [ ran ] PUT /haha main.main.func5 3
2022/12/11 14:10:28 [ ran ] DELETE /home main.main.func6 3
*/

查看路由

router.Routes()  // 它会返回已注册的路由列表

环境切换

如果不想看到这些debug日志,那么我们可以改为release模式

gin.SetMode(gin.ReleaseMode)
router := gin.Default()

修改log的显示

默认的是这样的

[GIN] 2022/12/11 - 14:22:00 | 200 |  0s |  127.0.0.1 | GET  "/"

如果觉得不好看,我们可以自定义

package main

import (
  "fmt"
  "github.com/gin-gonic/gin"
)

func LoggerWithFormatter(params gin.LogFormatterParams) string {

  return fmt.Sprintf(
    "[ feng ] %s  | %d | \t %s | %s | %s \t  %s\n",
    params.TimeStamp.Format("2006/01/02 - 15:04:05"),
    params.StatusCode,  // 状态码
    params.ClientIP,  // 客户端ip
    params.Latency,  // 请求耗时
    params.Method,  // 请求方法
    params.Path,  // 路径
  )
}
func main() {
  router := gin.New()
  router.Use(gin.LoggerWithFormatter(LoggerWithFormatter))
  router.Run()

}

也可以这样

func LoggerWithFormatter(params gin.LogFormatterParams) string {
  return fmt.Sprintf(
    "[ feng ] %s  | %d | \t %s | %s | %s \t  %s\n",
    params.TimeStamp.Format("2006/01/02 - 15:04:05"),
    params.StatusCode,
    params.ClientIP,
    params.Latency,
    params.Method,
    params.Path,
  )
}
func main() {
  router := gin.New()
  router.Use(
    gin.LoggerWithConfig(
      gin.LoggerConfig{Formatter: LoggerWithFormatter},
    ),
  )
  router.Run()


但是你会发现自己这样输出之后,没有颜色了,不太好看,我们可以输出有颜色的log

func LoggerWithFormatter(params gin.LogFormatterParams) string {
  var statusColor, methodColor, resetColor string
  statusColor = params.StatusCodeColor()
  methodColor = params.MethodColor()
  resetColor = params.ResetColor()
  return fmt.Sprintf(
    "[ feng ] %s  | %s %d  %s | \t %s | %s | %s %-7s %s \t  %s\n",
    params.TimeStamp.Format("2006/01/02 - 15:04:05"),
    statusColor, params.StatusCode, resetColor,
    params.ClientIP,
    params.Latency,
    methodColor, params.Method, resetColor,
    params.Path,
  )
}

10.logrus

下载

go get github.com/sirupsen/logrus

logrus常用方法

logrus.Debugln("Debugln")
logrus.Infoln("Infoln")
logrus.Warnln("Warnln")
logrus.Errorln("Errorln")
logrus.Println("Println")

// 输出如下
time="2022-12-17T14:02:01+08:00" level=info msg=Infoln   
time="2022-12-17T14:02:01+08:00" level=warning msg=Warnln
time="2022-12-17T14:02:01+08:00" level=error msg=Errorln 
time="2022-12-17T14:02:01+08:00" level=info msg=Println

debug的没有输出,是因为logrus默认的日志输出等级是 info

fmt.Println(logrus.GetLevel())  // info

日志等级

PanicLevel  // 会抛一个异常
FatalLevel  // 打印日志之后就会退出
ErrorLevel
WarnLevel
InfoLevel
DebugLevel
TraceLevel  // 低级别

更改日志级别

如果你想显示Debug的日志,那么你可以更改日志显示等级

logrus.SetLevel(logrus.DebugLevel)

日志级别一般是和系统环境挂钩,例如开发环境,肯定就要显示debug信息,测试环境也是需要的

线上环境就不需要这些日志,可能只显示warnning的日志