[ 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. 日志
为什么要使用日志
- 记录用户操作,猜测用户行为
- 记录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的日志