Skip to content

Commit cfa54ba

Browse files
authored
Create zap_log_middleware.go
1 parent ba8568d commit cfa54ba

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

golang/zap_log_middleware.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package middware
2+
3+
import (
4+
"fmt"
5+
"github.com/gin-gonic/gin"
6+
"go.uber.org/zap"
7+
"math"
8+
"net"
9+
"net/http"
10+
"net/http/httputil"
11+
"os"
12+
"runtime/debug"
13+
"strings"
14+
"time"
15+
)
16+
17+
// LoggerMiddleware 接收gin框架默认的日志
18+
func LoggerMiddleware() gin.HandlerFunc {
19+
return func(c *gin.Context) {
20+
zapLogFields := make([]zap.Field, 0)
21+
startTime := time.Now()
22+
c.Next() // 调用该请求的剩余处理程序
23+
stopTime := time.Since(startTime)
24+
spendTime := fmt.Sprintf("%d ms", int(math.Ceil(float64(stopTime.Nanoseconds()/1000000))))
25+
statusCode := c.Writer.Status()
26+
dataSize := c.Writer.Size()
27+
if dataSize < 0 {
28+
dataSize = 0
29+
}
30+
method := c.Request.Method
31+
url := c.Request.RequestURI
32+
zapLogFields = append(zapLogFields, zap.String("SpendTime", spendTime))
33+
zapLogFields = append(zapLogFields, zap.String("path", url))
34+
zapLogFields = append(zapLogFields, zap.String("Method", method))
35+
zapLogFields = append(zapLogFields, zap.Int("status", statusCode))
36+
37+
opts := zap.Fields(zapLogFields...)
38+
log := zap.L()
39+
log.WithOptions(opts)
40+
if len(c.Errors) > 0 { // 创建内部错误
41+
c.Errors.ByType(gin.ErrorTypePrivate)
42+
}
43+
if statusCode >= 500 {
44+
log.Error("[Error]")
45+
} else if statusCode >= 400 {
46+
log.Warn("[Warning]")
47+
} else {
48+
log.Info("[Info]")
49+
}
50+
}
51+
}
52+
53+
func RecoveryLog() gin.HandlerFunc {
54+
return func(c *gin.Context) {
55+
defer func() {
56+
if err := recover(); err != nil {
57+
// Check for a broken connection, as it is not really a
58+
// condition that warrants a panic stack trace.
59+
var brokenPipe bool
60+
if ne, ok := err.(*net.OpError); ok {
61+
if se, ok := ne.Err.(*os.SyscallError); ok {
62+
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
63+
brokenPipe = true
64+
}
65+
}
66+
}
67+
log := zap.L()
68+
httpRequest, _ := httputil.DumpRequest(c.Request, false)
69+
if brokenPipe {
70+
log.Error(c.Request.URL.Path,
71+
zap.Any("[Error]", err),
72+
zap.String("[Request]", string(httpRequest)),
73+
)
74+
// If the connection is dead, we can't write a status to it.
75+
c.Error(err.(error)) // nolint: errcheck
76+
c.Abort()
77+
return
78+
}
79+
80+
log.Error("[Recovery from panic]",
81+
zap.Any("[Error]", err),
82+
zap.String("[Request}", string(httpRequest)),
83+
zap.String("[Stack]", string(debug.Stack())),
84+
)
85+
86+
c.AbortWithStatus(http.StatusInternalServerError)
87+
}
88+
}()
89+
c.Next()
90+
}
91+
}

0 commit comments

Comments
 (0)