Dra-M Dra-M
首页
技术
冥思
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

莫小龙

保持理智,相信未来。
首页
技术
冥思
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java基础

  • Spring

  • 微服务

  • Elasticsearch

  • Golang

    • GitLab私服+Go Modules踩坑经验(SSH自定义端口)
    • 【代码片段】我使用的Gin中间处理器(自定义异常处理、日志打印、traceId、跨域配置)
    • 【Java转Go】如何理解Go中的值类型、引用类型、nil
    • 【Java转Go】如何理解面向对象,怎么把Golang用成面向对象的样子
  • 实用工具

  • Bash

  • DevOps系列

  • 技术
  • Golang
莫小龙
2022-12-03

【代码片段】我使用的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")
			global.Log.Warnf("[%s] %s", value, err)

			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

#Golang#Gin
上次更新: 1/5/2023
GitLab私服+Go Modules踩坑经验(SSH自定义端口)
【Java转Go】如何理解Go中的值类型、引用类型、nil

← GitLab私服+Go Modules踩坑经验(SSH自定义端口) 【Java转Go】如何理解Go中的值类型、引用类型、nil→

最近更新
01
【Java转Go】如何理解Go中的值类型、引用类型、nil
12-03
02
【Java转Go】如何理解面向对象,怎么把Golang用成面向对象的样子
12-02
03
GitLab私服+Go Modules踩坑经验(SSH自定义端口)
08-31
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Dra-M | 冀ICP备2021002204号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式