specifications
- Record all changes, additions and deletions in the management background
- Operation log statistics do not affect the performance of the main program
Demand analysis
- Package the related code into middleware and use it independently
- Proper use of Goroutine does not affect the performance of the main thread
documentation
- Developed based on golang language
- Developed based on GIN network framework
- Developed based on MySQL5.8
- The operation log section is packaged as middleware and referenced in the Rourter file
- 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
- We can use the context directly to get the request method and the requested URL
- If we can’t get the ResponseWriter directly, we can use the ResponseWriter idea to intercept the ResponseWriter and then pass it down
- Methods such as obtaining client IP are wrapped in util for easy invocation
- 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.
- 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
- 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
- The above is my implementation idea
- Another way to think about it is to schedule message queues and send notifications for logging errors
Related articles
- The GO section is intended to be a series that will eventually open source the packaged code
- 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.