package middleware import ( "bytes" "io/ioutil" "log" "net" "net/http" "net/http/httputil" "os" "runtime/debug" "strings" "time" "github.com/gin-gonic/gin" ) func NewLogger() gin.HandlerFunc { //lg := logger.Logger() return func(c *gin.Context) { // 开始时间 startTime := time.Now() // 处理请求 endTime := time.Now() // 执行时间 latencyTime := endTime.Sub(startTime) // 请求方式 path := c.Request.URL.Path query := c.Request.URL.RawQuery data, _ := ioutil.ReadAll(c.Request.Body) log.Printf("[%s] %s %d %s %s %s %s %s %s", path, c.Request.Method, c.Writer.Status(), query, string(data), c.ClientIP(), c.Request.UserAgent(), c.Errors.ByType(gin.ErrorTypePrivate).String(), latencyTime.String()) c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data)) c.Next() } } // GinRecovery recover掉项目可能出现的panic,并记录日志 func GinRecovery(stack bool) gin.HandlerFunc { //logger := logger.Logger() return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // Check for a broken connection, as it is not really a // condition that warrants a panic stack trace. var brokenPipe bool if ne, ok := err.(*net.OpError); ok { if se, ok := ne.Err.(*os.SyscallError); ok { if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") { brokenPipe = true } } } httpRequest, _ := httputil.DumpRequest(c.Request, false) if brokenPipe { log.Printf("[%s] %s %s", c.Request.URL.Path, err, string(httpRequest)) // If the connection is dead, we can't write a status to it. c.Error(err.(error)) // nolint: errcheck c.Abort() return } log.Printf("[%s] %s %s %s", "[Recovery from panic]", err, string(httpRequest), string(debug.Stack())) c.AbortWithStatus(http.StatusInternalServerError) } }() c.Next() } }