gin 记录输入输出中间件
// Author: Mjy
// Create Date: 2018-12-18
package middleware
import (
"b.com/dsers/components"
"b.com/dsers/handler"
"bytes"
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/willf/pad"
"io/ioutil"
"time"
)
type bodyLogWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (this bodyLogWriter) Write(b []byte) (int, error) {
this.body.Write(b)
return this.ResponseWriter.Write(b)
}
func Logging(tag string) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now().UTC()
path := c.Request.URL.Path
var bodyBytes []byte
if c.Request.Body != nil {
bodyBytes, _ = ioutil.ReadAll(c.Request.Body)
}
// 恢复 body
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
method := c.Request.Method
ip := c.ClientIP()
blw := &bodyLogWriter{
body: bytes.NewBufferString(""),
ResponseWriter: c.Writer,
}
c.Writer = blw
c.Next()
end := time.Now().UTC()
latency := end.Sub(start)
var response handler.JsonResponse
if err := json.Unmarshal(blw.body.Bytes(), &response); err != nil {
components.Logger.Errorf("response body can not unmarshal to model.Response struct, body: '%s', err:%v", blw.body.Bytes, err)
}
components.Logger.Infof("%s |%-13s | %-12s | %s %s | %v | %v", tag, latency, ip, pad.Right(method, 5, ""), path, string(bodyBytes), blw.body.String())
}
}