【代码片段】我使用的Gin中间处理器(自定义异常处理、日志打印、traceId、跨域配置)
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"net"
"net/http"
"os"
"soul_station/src/common/response"
"soul_station/src/global"
"soul_station/src/startup/initialize/router"
"strings"
)
func Router() {
gin.SetMode(gin.ReleaseMode)
apiEngine := newEngine()
// API group
api := apiEngine.Group("/api")
//管理端
router.AdminClient(api)
//用户端
router.UserClient(api)
// 启动、监听端口
_ = apiEngine.Run(fmt.Sprintf("localhost:%s", global.Config.Server.Port))
}
func newEngine() *gin.Engine {
engine := gin.Default()
//去掉默认handlers,去掉gin自带的日志打印
engine.Handlers = nil
//拼接TraceId
engine.Use(traceId)
//自定义日志打印
engine.Use(preLog)
engine.Use(afterLog)
engine.Use(customRecovery)
// 开启跨域
engine.Use(cors)
//404
engine.NoRoute(func(c *gin.Context) {
c.String(http.StatusNotFound, "404 not found")
})
return engine
}
// Cors 处理跨域请求
func cors(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("*.dra-m.com")
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
// 放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
func preLog(c *gin.Context) {
value, _ := c.Get("Trace")
remoteIp := c.GetHeader("X-Real-IP")
if remoteIp == "" {
remoteIp = c.Request.RemoteAddr
}
global.Log.Infof("[%s] >>>>>>>>>>> [%s] %s From %s", value, c.Request.Method, c.Request.RequestURI, remoteIp)
c.Next()
}
func afterLog(c *gin.Context) {
defer func() {
value, _ := c.Get("Trace")
remoteIp := c.GetHeader("X-Real-IP")
if remoteIp == "" {
remoteIp = c.Request.RemoteAddr
}
global.Log.Infof("[%s] <<<<< [%3d] [%s] %s To %s", value, c.Writer.Status(), c.Request.Method, c.Request.RequestURI, remoteIp)
}()
c.Next()
}
func customRecovery(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 {
var se *os.SyscallError
if errors.As(ne, &se) {
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
brokenPipe = true
}
}
}
value, _ := c.Get("Trace")
// 打印错误日志
_, file, line, _ := runtime.Caller(2)
for i := len(file) - 1; i > 0; i-- {
if file[i] == '/' {
file = file[i+1:]
break
}
}
g.Log.Errorf("[%s] %s (%s:%d)", value, err, file, line)
if brokenPipe {
// If the connection is dead, we can't write a status to it.
c.Error(err.(error)) // nolint:
c.Abort()
} else {
switch err.(type) {
case string:
response.ErrorWithInfo(err.(string)).Write(c)
break
case error:
response.ErrorWithInfo(err.(error).Error()).Write(c)
break
default:
response.ErrorWithInfo("发生不明错误").Write(c)
break
}
}
}
}()
c.Next()
}
func traceId(c *gin.Context) {
trace := uuid.NewV4().String()
c.Set("Trace", trace)
c.Header("Trace", trace)
c.Next()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
上次更新: 10/23/2024