Commit
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -0,0 +1 @@
|
||||
*.log
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
2
go.mod
2
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
|
||||
|
||||
6
go.sum
6
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=
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package initialize
|
||||
|
||||
func Initialize() {
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
func Initialize() *gin.Engine {
|
||||
initConfig()
|
||||
initLogger()
|
||||
initMySQL()
|
||||
return initRouter()
|
||||
}
|
||||
|
||||
25
initialize/logger.go
Normal file
25
initialize/logger.go
Normal file
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
17
initialize/router.go
Normal file
17
initialize/router.go
Normal file
@@ -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
|
||||
}
|
||||
11
main.go
Normal file
11
main.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/initialize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gin := initialize.Initialize()
|
||||
gin.Run(global.GetListenOn())
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/initialize"
|
||||
)
|
||||
|
||||
func main() {
|
||||
initialize.Initialize()
|
||||
}
|
||||
24
middleware/cors.go
Normal file
24
middleware/cors.go
Normal file
@@ -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()
|
||||
}
|
||||
}
|
||||
55
middleware/gin_recovery.go
Normal file
55
middleware/gin_recovery.go
Normal file
@@ -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()
|
||||
}
|
||||
}
|
||||
54
middleware/request_log.go
Normal file
54
middleware/request_log.go
Normal file
@@ -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...)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
45
utils/log.go
Normal file
45
utils/log.go
Normal file
@@ -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...)
|
||||
}
|
||||
9
utils/time.go
Normal file
9
utils/time.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func FormateDate(date time.Time) string {
|
||||
return date.Format("06-01-02")
|
||||
}
|
||||
Reference in New Issue
Block a user