From 2280679053954c9c3447797edce595ed8fb19391 Mon Sep 17 00:00:00 2001 From: fallen-angle <1853633282@qq.com> Date: Mon, 17 Jan 2022 17:38:08 +0800 Subject: [PATCH] Commit --- .gitignore | 1 + config/config.go | 2 +- global/global.go | 9 ++++ go.mod | 2 + go.sum | 6 +++ initialize/config.go | 2 + initialize/initialize.go | 6 ++- initialize/logger.go | 25 +++++++++++ initialize/mysql.go | 2 +- initialize/router.go | 17 +++++++ main.go | 11 +++++ main/main.go | 9 ---- middleware/cors.go | 24 ++++++++++ middleware/gin_recovery.go | 55 +++++++++++++++++++++++ middleware/request_log.go | 54 ++++++++++++++++++++++ router/router.go | 19 +++++--- main/settings-dev.yml => settings-dev.yml | 4 +- utils/log.go | 45 +++++++++++++++++++ utils/time.go | 9 ++++ 19 files changed, 283 insertions(+), 19 deletions(-) create mode 100644 initialize/logger.go create mode 100644 initialize/router.go create mode 100644 main.go delete mode 100644 main/main.go create mode 100644 middleware/cors.go create mode 100644 middleware/gin_recovery.go create mode 100644 middleware/request_log.go rename main/settings-dev.yml => settings-dev.yml (82%) create mode 100644 utils/log.go create mode 100644 utils/time.go diff --git a/.gitignore b/.gitignore index e69de29..397b4a7 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +*.log diff --git a/config/config.go b/config/config.go index bccb037..f7abcc9 100644 --- a/config/config.go +++ b/config/config.go @@ -11,7 +11,7 @@ type ServerConfig struct { type MySQLConfig struct { Host string `yaml:"host"` - Port string `yaml:"port"` + Port int `yaml:"port"` Username string `yaml:"username"` Password string `yaml:"password"` Database string `yaml:"database"` diff --git a/global/global.go b/global/global.go index 188bd87..41009d0 100644 --- a/global/global.go +++ b/global/global.go @@ -1,12 +1,21 @@ package global import ( + "fmt" "nCovTrack-Backend/config" + "github.com/gin-gonic/gin" + "go.uber.org/zap" "gorm.io/gorm" ) var ( ServerSettings config.ServerConfig Db *gorm.DB + RootRouter *gin.RouterGroup + Logger *zap.SugaredLogger ) + +func GetListenOn() string { + return fmt.Sprintf("%s:%d", ServerSettings.Listen, ServerSettings.Port) +} diff --git a/go.mod b/go.mod index 15032dc..35e0652 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module nCovTrack-Backend go 1.18 require ( + github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-gonic/gin v1.7.7 // indirect @@ -17,6 +18,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/magiconair/properties v1.8.5 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect diff --git a/go.sum b/go.sum index 113980c..1c888ce 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -165,6 +167,9 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -367,6 +372,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/initialize/config.go b/initialize/config.go index 36419cc..19920c5 100644 --- a/initialize/config.go +++ b/initialize/config.go @@ -5,6 +5,7 @@ import ( "nCovTrack-Backend/config" "nCovTrack-Backend/global" + "github.com/fatih/color" "github.com/spf13/viper" ) @@ -20,4 +21,5 @@ func initConfig() { panic(err) } global.ServerSettings = serverConfig + color.Blue("Already read config from %s", v.ConfigFileUsed()) } diff --git a/initialize/initialize.go b/initialize/initialize.go index 854e272..7e71e40 100644 --- a/initialize/initialize.go +++ b/initialize/initialize.go @@ -1,6 +1,10 @@ package initialize -func Initialize() { +import "github.com/gin-gonic/gin" + +func Initialize() *gin.Engine { initConfig() + initLogger() initMySQL() + return initRouter() } diff --git a/initialize/logger.go b/initialize/logger.go new file mode 100644 index 0000000..2f9791d --- /dev/null +++ b/initialize/logger.go @@ -0,0 +1,25 @@ +package initialize + +import ( + "fmt" + "nCovTrack-Backend/global" + "nCovTrack-Backend/utils" + "time" + + "go.uber.org/zap" +) + +func initLogger() { + zapConfig := zap.NewProductionConfig() + zapConfig.OutputPaths = []string{ + fmt.Sprintf("%slog_%s.log", global.ServerSettings.LogPath, utils.FormateDate(time.Now())), + "stdout", + } + logger, err := zapConfig.Build() + if err != nil { + panic(err) + } + sLogger := logger.Sugar() + zap.ReplaceGlobals(sLogger.Desugar()) + global.Logger = sLogger +} diff --git a/initialize/mysql.go b/initialize/mysql.go index 5f77b77..1698f8a 100644 --- a/initialize/mysql.go +++ b/initialize/mysql.go @@ -10,7 +10,7 @@ import ( func initMySQL() { mysqlConf := global.ServerSettings.MySQL - dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%scharset=utf8mb4&parseTime=True&loc=Local", mysqlConf.Username, mysqlConf.Password, mysqlConf.Host, mysqlConf.Port, mysqlConf.Database) + dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", mysqlConf.Username, mysqlConf.Password, mysqlConf.Host, mysqlConf.Port, mysqlConf.Database) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { panic(err) diff --git a/initialize/router.go b/initialize/router.go new file mode 100644 index 0000000..7a572ac --- /dev/null +++ b/initialize/router.go @@ -0,0 +1,17 @@ +package initialize + +import ( + "nCovTrack-Backend/global" + "nCovTrack-Backend/middleware" + "nCovTrack-Backend/router" + + "github.com/gin-gonic/gin" +) + +func initRouter() *gin.Engine { + r := gin.New() + r.Use(middleware.Cors(), middleware.RequestLog(), middleware.GinRecovery(false)) + global.RootRouter = r.Group(global.ServerSettings.UrlPrefix) + router.BusiRouter() + return r +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..e3c4d76 --- /dev/null +++ b/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "nCovTrack-Backend/global" + "nCovTrack-Backend/initialize" +) + +func main() { + gin := initialize.Initialize() + gin.Run(global.GetListenOn()) +} diff --git a/main/main.go b/main/main.go deleted file mode 100644 index 17659e2..0000000 --- a/main/main.go +++ /dev/null @@ -1,9 +0,0 @@ -package main - -import ( - "nCovTrack-Backend/initialize" -) - -func main() { - initialize.Initialize() -} diff --git a/middleware/cors.go b/middleware/cors.go new file mode 100644 index 0000000..f9c4f5c --- /dev/null +++ b/middleware/cors.go @@ -0,0 +1,24 @@ +package middleware + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func Cors() gin.HandlerFunc { + return func(c *gin.Context) { + method := c.Request.Method + origin := c.Request.Header.Get("Origin") + 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") + + if method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + } + c.Next() + } +} diff --git a/middleware/gin_recovery.go b/middleware/gin_recovery.go new file mode 100644 index 0000000..94d5e02 --- /dev/null +++ b/middleware/gin_recovery.go @@ -0,0 +1,55 @@ +package middleware + +import ( + "nCovTrack-Backend/utils" + "net" + "net/http" + "net/http/httputil" + "os" + "runtime/debug" + "strings" + + "github.com/gin-gonic/gin" +) + +func GinRecovery(stack bool) gin.HandlerFunc { + return func(c *gin.Context) { + defer func() { + if err := recover(); err != nil { + 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, true) + var logParams []interface{} + logParams = append(logParams, + "uri", c.Request.RequestURI, + "method", c.Request.Method, + "request", string(httpRequest), + "error", interface{}(err), + ) + if brokenPipe { + utils.RequestLogPanic(logParams...) + c.Error(err.(error)) + c.Abort() + return + } + logParams = append(logParams, + "status", "recovery from panic", + ) + if stack { + logParams = append(logParams, + "stack", string(debug.Stack()), + ) + } + utils.RequestLogPanic(logParams...) + c.AbortWithStatus(http.StatusInternalServerError) + } + }() + c.Next() + } +} diff --git a/middleware/request_log.go b/middleware/request_log.go new file mode 100644 index 0000000..72889be --- /dev/null +++ b/middleware/request_log.go @@ -0,0 +1,54 @@ +package middleware + +import ( + "nCovTrack-Backend/utils" + "net/http" + "time" + + "github.com/gin-gonic/gin" +) + +func RequestLog() gin.HandlerFunc { + return func(c *gin.Context) { + var logParams []interface{} + + // All requests' log; + logParams = append(logParams, + "uri", c.Request.RequestURI, + "mothod", c.Request.Method, + ) + startTime := time.Now() + + c.Next() + + cost := time.Since(startTime) + logParams = append(logParams, "cost", cost.String()) + + // Log while request is allright; + if c.Writer.Status() == http.StatusOK && cost.Milliseconds() < 800 { + utils.RequestLogInfo(logParams...) + return + } + + // Log while request cost an unexpected time; + if cost >= 800 { + logParams = append(logParams, + "status", c.Writer.Status(), + "query", c.Request.URL.Query(), + "header", c.Request.Header, + "body", c.Request.Body, + "ip", c.ClientIP(), + ) + utils.RequestLogWarn(logParams...) + return + } + + // Log while response occurred some error; + if c.Writer.Status() != http.StatusOK { + logParams = append(logParams, + "error", c.Errors.ByType(gin.ErrorTypePrivate).String(), + ) + utils.RequestLogError(logParams...) + } + } +} diff --git a/router/router.go b/router/router.go index bb5a8c4..5afe3e6 100644 --- a/router/router.go +++ b/router/router.go @@ -2,13 +2,22 @@ package router import ( "nCovTrack-Backend/global" + "net/http" + "time" "github.com/gin-gonic/gin" ) -func initRouter() { - r := gin.Default() - r.Use() - apiGroup := r.Group(global.ServerSettings.UrlPrefix) - router.UserRouter(apiGroup) +func BusiRouter() { + userRouter := global.RootRouter.Group("/user") + { + userRouter.GET("/count", func(c *gin.Context) { + panic("count err") + time.Sleep(800 * time.Millisecond) + c.String(http.StatusOK, "OK") + }) + userRouter.GET("/test", func(c *gin.Context) { + c.String(http.StatusOK, "OK") + }) + } } diff --git a/main/settings-dev.yml b/settings-dev.yml similarity index 82% rename from main/settings-dev.yml rename to settings-dev.yml index 035b968..491b56e 100644 --- a/main/settings-dev.yml +++ b/settings-dev.yml @@ -1,5 +1,5 @@ name: nConvTrack -port: 8080 +port: 8081 host: 0.0.0.0 urlPrefix: /v1/ logPath: ./logs/ @@ -9,4 +9,4 @@ mysql: port: 3306 username: root password: 13291004986@lm - database: nConvTrack + database: nCovTrack diff --git a/utils/log.go b/utils/log.go new file mode 100644 index 0000000..2a374a1 --- /dev/null +++ b/utils/log.go @@ -0,0 +1,45 @@ +package utils + +import "nCovTrack-Backend/global" + +func RequestLogInfo(args ...interface{}) { + logInfo("request", args...) +} + +func RequestLogError(args ...interface{}) { + logError("request", args...) +} + +func RequestLogWarn(args ...interface{}) { + logWarn("request", args...) +} + +func RequestLogPanic(args ...interface{}) { + logPanic("request", args...) +} + +func InitLogPanic(component string, args ...interface{}) { + args = append(args, "component", component) + logPanic("initialize", args...) +} + +func InitLogInfo(component string, args ...interface{}) { + args = append(args, "component", component) + logInfo("initialize", args...) +} + +func logInfo(msg string, args ...interface{}) { + global.Logger.Infow(msg, args...) +} + +func logError(msg string, args ...interface{}) { + global.Logger.Errorw(msg, args...) +} + +func logWarn(msg string, args ...interface{}) { + global.Logger.Warnw(msg, args...) +} + +func logPanic(msg string, args ...interface{}) { + global.Logger.Panicw("", args...) +} diff --git a/utils/time.go b/utils/time.go new file mode 100644 index 0000000..9434fb2 --- /dev/null +++ b/utils/time.go @@ -0,0 +1,9 @@ +package utils + +import ( + "time" +) + +func FormateDate(date time.Time) string { + return date.Format("06-01-02") +}