【gin】简单研发----中间件

在gin的框架中,中间件绑定在路由环节,常规的使用方式如下:

middlewares/auth.go

package middlewares

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

func Auth() gin.HandlerFunc {
	return func(c *gin.Context) {
		token, _ := c.GetQuery("token")
		if token == "" {
			c.JSON(http.StatusForbidden, gin.H{"code":50008, "message":"非法访问!"})
			c.Abort()
		}
		c.Next()
	}
}

router.go

package routers

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

func InitRouter() *gin.Engine {
	router := gin.Default()
	router.Use(
		middlewares.Cors(),		//跨域中间件
		middlewares.Auth(),		//鉴权中间件
	)

	uploadGroup := router.Group("/upload")
	{
		uploadGroup.POST("/upload", controllers.Upload)
	}
	
	return router
}

=========================================================================

下面重点讲解下日志中间件,因为需要是从PHP转过来的老程序员,所以对PHP框架中的日志存储方式情有独钟,而gin原生的log是存储在一个文件内,很不习惯,因此,找到一个能够按照时间分割日志的包才安心。

1、将下面三个包拉到项目中

go get "github.com/lestrrat/go-file-rotatelogs"
go get "github.com/rifflock/lfshook"
go get "github.com/sirupsen/logrus"

2、中间件编写

package middlewares

import (
	"fmt"
	"github.com/gin-gonic/gin"
	rotatelogs "github.com/lestrrat/go-file-rotatelogs"
	"github.com/rifflock/lfshook"
	"github.com/sirupsen/logrus"
	"os"
	"time"
)

func Logger() gin.HandlerFunc {
	logClient := logrus.New()

	//禁止logrus输出
	src, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
	if err != nil {
		fmt.Println("err", err)
	}
	logClient.Out = src
	logClient.SetLevel(logrus.DebugLevel)
	apiLogPath := "logs/access.log"
	logWriter, err := rotatelogs.New(
		apiLogPath + ".%Y%m%d-%H%M.log",
		rotatelogs.WithLinkName(apiLogPath),			//生成软连接,指向新的日志文件
		rotatelogs.WithMaxAge(7*24*time.Hour),			//文件最大保存时间
		rotatelogs.WithRotationTime(24*time.Hour),		//日志切割时间间隔
	)
	writeMap := lfshook.WriterMap{
		logrus.InfoLevel: logWriter,
		logrus.FatalLevel:logWriter,
	}
	lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{})
	logClient.AddHook(lfHook)

	return func(c *gin.Context) {
		//开始时间
		start := time.Now()

        //执行逻辑
		c.Next()

		//结束时间
		end := time.Now()

		//执行时间
		execTime := end.Sub(start)

		path := c.Request.URL.Path		//请求路径
		clientIP := c.ClientIP()		//请求IP
		method := c.Request.Method		//请求方式
		statusCode := c.Writer.Status()	//请求状态

		logClient.Infof("|%3d | %13v | %15s | %s %s |",
			statusCode,
			execTime,
			clientIP,
			method,
			path,
		)
	}
}

上图中,最不可忽略的当属 c.next() ,表示载入后续的逻辑代码执行,执行结束后继续此中间件的后续部分。

这个方式,让我想起了TP5中的钩子。

3、创建日志目录

在根目录创建logs,否则会因为路径不存在报错,当然加一个目录判断会是种不错的选择。

4、修改路由器

package routers

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

func InitRouter() *gin.Engine {
	router := gin.Default()
	router.Use(
		middlewares.Cors(),		//跨域中间件
		middlewares.Auth(),		//鉴权中间件
		middlewares.Logger(),	//日志中间件
	)

	uploadGroup := router.Group("/upload")
	{
		uploadGroup.POST("/upload", controllers.Upload)
	}
	
	return router
}

你可能感兴趣的:(Golang,golang,开发语言,后端)