specifications

  1. Record all changes, additions and deletions in the management background
  2. Operation log statistics do not affect the performance of the main program

Demand analysis

  1. Package the related code into middleware and use it independently
  2. Proper use of Goroutine does not affect the performance of the main thread

documentation

  1. Developed based on golang language
  2. Developed based on GIN network framework
  3. Developed based on MySQL5.8
  4. The operation log section is packaged as middleware and referenced in the Rourter file
  5. Non-core code has been omitted, with three vertical dots. said

Set the database table structure

Operation log table

code

Middleware code

The code analysis

  1. We can use the context directly to get the request method and the requested URL
  2. If we can’t get the ResponseWriter directly, we can use the ResponseWriter idea to intercept the ResponseWriter and then pass it down
  3. Methods such as obtaining client IP are wrapped in util for easy invocation
  4. We cannot set the adminLogs() method as a whole to Goroutine because this will pass the context’s events in the new coroutine and will not pass properly.
  5. So after the c.ext () event is passed, parse the JSON into a structure and save the operation log to the database to use the Goroutine operation
  6. The operation log does not compare the query operation, so we filter out the request mode of GET
Package Middleware //amdin Operation log import (.... "bytes" "encoding/json" "FMT" "github.com/gin-gonic/gin" "strings") type bodyLogWriter struct { gin.ResponseWriter bodyBuf *bytes.Buffer } func (w bodyLogWriter) Write(b []byte) (int, error) { w.bodyBuf.Write(b) return w.ResponseWriter.Write(b) } var CommonLogInterceptor = commonLogInterceptor() /* 1 Use Goroutine and channel to implement operation log storage, as far as possible does not affect the main program 2 Goroutine coroutine, 3 Channel */ func commonLogInterceptor() gin.HandlerFunc {return func(c *gin.Context) {adminLogs(c)}} // Get the code and message func adminLogs(c *gin.Context) {if admin, _ := c.net ("admin"); admin ! = nil { method := c.Request.Method url := c.Request.URL.Path strBody := "" var blw bodyLogWriter blw = bodyLogWriter{bodyBuf: bytes.NewBufferString(""), ResponseWriter: c.Writer} c.Writer = blw c.Next() if method ! = "GET" { strBody = strings.Trim(blw.bodyBuf.String(), "\n") go func(strBody string) { var returnJson api.ReturnJson json.Unmarshal([]byte(strBody), &returnJson) message := fmt.Sprintf("%v", returnJson.Message) adminInfo := admin.(**service.RunningClaims) adminId := (*adminInfo).ID adminName := (*adminInfo).Account var log = model.AdminLog{ AdminId: adminId, AdminName: adminName, Method: method, Url: url, Ip: util.RemoteIP(c.Request), Code: returnJson.Code, Message: message, } model.CreateLog(log) }(strBody) } } }Copy the code

The model layer code

package model

type AdminLog struct {
	ID int `json:"id"`
	AdminId uint `json:"admin_id"`
	AdminName string `json:"admin_name"`
	Method string `json:"method"`
	Ip string `json:"ip"`
	Url string `json:"url"`
	Code int `json:"code"`
	Message string `json:"message"`
}

func CreateLog(log AdminLog)  {
	DB.Create(&log)
}
Copy the code

The routing code

Package Server import (.... "OS" "github.com/gin-gonic/gin") // NewRouter Route configuration func NewRouter() *gin.Engine {r := Gin. Default () / / other middleware. R. gutierrez roup.. / / routing v1: = ("/API/v1 ") {v1. POST (" login ", Api.login) auth := v1.group ("") // Use(middleware.authRequired ()) Role permission check auth. Use (middleware. AuthCheckMiddleware) / / operation log auth. Use monLogInterceptor (middleware.Com) {... / / for all schools { auth.GET("/school/", api.GetSchoolInfo) } . . . } } return r }Copy the code

conclusion

  1. The above is my implementation idea
  2. Another way to think about it is to schedule message queues and send notifications for logging errors

Related articles

  1. The GO section is intended to be a series that will eventually open source the packaged code
  2. Go Gin Framework encapsulates middleware 1: User role permission Management middleware

To contact me

If you have better ideas or project cooperation, you can send me a private message or leave a comment at the bottom of the article.