1 Star 0 Fork 0

szmaozi / go-utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
middleware.go 6.90 KB
一键复制 编辑 原始数据 按行查看 历史
szmaozi 提交于 2021-09-02 13:41 . wip: merge biob-v1
/*
* @Descripttion:
* @version:
* @Author: moo
* @Date: 2020-10-23 12:01:31
* @LastEditors: moo
* @LastEditTime: 2021-05-27 19:13:23
*/
package middleware
import (
"bytes"
"fmt"
"io/ioutil"
"net"
"os"
"runtime/debug"
"strings"
"time"
"gitee.com/szmaozi/go-utils/e"
"net/http/httputil"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
const MAX_INPUT_FORM_SIZE int64 = 1024
// var logger = logbase.MustGetLogger("middleware")
// var zaplogger = logger.GetZapLogger()
// var loggerSkip = logger.GetZapLogger().WithOptions(zap.AddCallerSkip(1))
// bodyLogWriter是为了记录返回数据到log中进行了双写
type bodyLogWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (w bodyLogWriter) Write(b []byte) (int, error) {
w.body.Write(b)
return w.ResponseWriter.Write(b)
}
func CoreHandleZap(logger *zap.Logger, timeFormat string, utc bool, debug bool) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
// some evil middlewares modify this values
path := c.Request.URL.Path
query := c.Request.URL.RawQuery
postForm, _ := ioutil.ReadAll(c.Request.Body)
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(postForm))
// print header
fmt.Println("-----------header-------------")
for k, v := range c.Request.Header {
fmt.Println(k, v)
}
fmt.Println("ip", c.ClientIP())
// fmt.Println("------------------------------")
fmt.Println("-----------request-------------")
fmt.Println("method", c.Request.Method)
fmt.Println("path", path)
fmt.Println("query", query)
fmt.Println("post-form", string(postForm))
// fmt.Println("post-form:")
// for k, v := range postForm {
// fmt.Println(" ", k, v)
// }
fmt.Println("------------------------------")
c.Next()
end := time.Now()
latency := end.Sub(start)
if utc {
end = end.UTC()
}
// if c.Writer.Written() {
// status := c.Writer.Status()
// if status == http.StatusOK || status == http.StatusCreated {
// logger.Debug(blw.body.String())
// } else {
// logger.Error(blw.body.String())
// }
// }
// c.Writer.Write([]byte("append data"))
if len(c.Errors) > 0 {
// Append error field if this is an erroneous request.
for _, e := range c.Errors.Errors() {
logger.Error(e)
}
} else {
logger.Debug("record",
zap.Duration("latency", latency),
)
// httpRequest, _ := httputil.DumpRequest(c.Request, false)
/*
logger.Debug("record",
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.String("query", query),
zap.String("post-form", string(postForm)),
zap.String("ip", c.ClientIP()),
zap.String("user-agent", c.Request.UserAgent()),
zap.String("time", end.Format(timeFormat)),
zap.Duration("latency", latency),
// zap.String("request", string(httpRequest)),
zap.Int("status", c.Writer.Status()),
// zap.Any("response-head", c.Writer.Header()),
)
*/
}
}
}
/**
* @name: CoreHandle
* @description:
* Ginzap returns a gin.HandlerFunc (middleware) that logs requests using uber-go/zap.
* Requests with errors are logged using zap.Error().
* Requests without errors are logged using zap.Info()
* @warning: 针对c.String() 之类的写法,response目前写法获取不到
* @msg:
* @param {*zap.Logger} logger
* @param {string} timeFormat: A time package format string (e.g. time.RFC3339).
* @param {bool} utc: A boolean stating whether to use UTC time zone or local.
* @param {bool} debug
* @return {*}
*/
func DebugHandleWithResp(logger *zap.Logger, timeFormat string, utc bool, debug bool) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
// some evil middlewares modify this values
path := c.Request.URL.Path
query := c.Request.URL.RawQuery
postForm, _ := ioutil.ReadAll(c.Request.Body)
// 获取response的body
blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
c.Writer = blw
c.Next()
end := time.Now()
latency := end.Sub(start)
if utc {
end = end.UTC()
}
// if c.Writer.Written() {
// status := c.Writer.Status()
// if status == http.StatusOK || status == http.StatusCreated {
// logger.Debug(blw.body.String())
// } else {
// logger.Error(blw.body.String())
// }
// }
// c.Writer.Write([]byte("append data"))
if len(c.Errors) > 0 {
// Append error field if this is an erroneous request.
for _, e := range c.Errors.Errors() {
logger.Error(e)
}
} else {
// httpRequest, _ := httputil.DumpRequest(c.Request, false)
logger.Debug("request",
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Duration("latency", latency),
zap.String("query", query),
zap.String("post-form", string(postForm)),
// zap.String("ip", c.ClientIP()),
// zap.String("user-agent", c.Request.UserAgent()),
// zap.String("time", end.Format(timeFormat)),
// zap.String("request", string(httpRequest)),
)
logger.Debug("response",
zap.Int("status", c.Writer.Status()),
// zap.Any("response-head", c.Writer.Header()),
zap.String("response-body", blw.body.String()),
)
}
}
}
// RecoveryWithZap returns a gin.HandlerFunc (middleware)
// that recovers from any panics and logs requests using uber-go/zap.
// All errors are logged using zap.Error().
// stack means whether output the stack info.
// The stack info is easy to find where the error occurs but the stack info is too large.
func Recovery(logger *zap.Logger, stack bool) gin.HandlerFunc {
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 {
logger.Error(c.Request.URL.Path,
zap.Any("error", err),
zap.String("request", string(httpRequest)),
)
// If the connection is dead, we can't write a status to it.
c.Error(err.(error)) // nolint: errcheck
c.Abort()
return
}
if stack {
debug.PrintStack()
logger.Error("[Recovery from panic]",
zap.Time("time", time.Now()),
zap.Any("error", err),
zap.String("request", string(httpRequest)),
zap.String("stack", string(debug.Stack())),
)
} else {
logger.Error("[Recovery from panic]",
zap.Time("time", time.Now()),
zap.Any("error", err),
zap.String("request", string(httpRequest)),
)
}
code := e.SERVER_ERROR
c.JSON(e.GetStatus(code), gin.H{
"code": code,
"msg": e.GetMsg(code),
})
// c.AbortWithStatus(http.StatusInternalServerError)
c.Abort()
}
}()
c.Next()
}
}
Go
1
https://gitee.com/szmaozi/go-utils.git
git@gitee.com:szmaozi/go-utils.git
szmaozi
go-utils
go-utils
29e02a007caf

搜索帮助