Project
目錄創建
mxshop-api
user-web
api ---- 服務接口
config ---- 配置信息
forms ---- 表單驗證信息
global ---- 全局信息
initialize ---- 初始化信息
middlewares ---- 中間件信息
proto ---- 數據信息
router ---- 路由信息
utils ---- 公用工具信息
validator ---- 表單校驗器
ZAP 高性能日志庫
ZAP 是 urban 開源的高性能日志庫
ZAP 日志的簡單使用
ZAP 日志框架有 sugar 模式以及 logger 模式兩種,sugar 有更加便捷的使用方式,但會在一定程度上降低性能,logger則正好相反。但是,無論是 sugar 模式 還是logger傳統模式,其性能都要比其他日志庫的性能高很多。
package mainimport ("go.uber.org/zap"
)func main() {logger, _ := zap.NewProduction()defer logger.Sync()url := "http://test.com"// 開啟 sugar 模式,這種模式會給予極簡便的日志打印方式,但會在一定程度上降低效率// 我們可以不使用 Sugar ,直接進行 logger,這樣會得到極致的性能sugar := logger.Sugar()// 使用 sugar 格式進行輸出(利用了反射機制)sugar.Infow("This is my msg", "url", url, "attempt", 3)sugar.Infof("This is my msg %s", url)// 使用 logger 進行打印,和 Sugar 有相同效果,在添加 JSON 時會略微麻煩logger.Info("This is my msg", zap.String("url", url))
}
如何將日志輸出到文件中
package mainimport ("go.uber.org/zap""time"
)func NewLogger() (*zap.Logger, error) {cfg := zap.NewProductionConfig()cfg.OutputPaths = []string{"./myproject.log", // 日志輸出,若只有這一個則只輸出日志,默認不配置的話會使用控制臺輸出"stderr", // 本地控制臺輸出,錯誤的紅色"stdout", // 本地控制臺輸出,輸出常規的黑色}return cfg.Build()
}func main() {logger, err := NewLogger()if err != nil {panic(err)}su := logger.Sugar()defer su.Sync()url := "https://6555555555555555.com"su.Info("failed to fetch URL",zap.String("url", url),zap.Int("attempt", 3),zap.Duration("backoff", time.Second), // 持續時間?)
}
基礎操作的創建流程
main文件的創建
在主文件夾 user-web 下創建一個 main.go,配置基礎的 gin 框架信息
package mainimport ("github.com/gin-gonic/gin"
)func main() {router := gin.Default()router.GET("/ping")
}
接口創建測試
在 api 目錄下創建 user.go :
package apiimport "github.com/gin-gonic/gin"func GetUserList(ctx *gin.Context) {}
路由的配置
在 router 目錄下創建user模塊的路由:user.go:
package routerimport ("github.com/gin-gonic/gin""mxshop-api/user-web/api"
)func InitUserRouter(Router *gin.RouterGroup) {// 這樣就需要 /user/list 才可以進行訪問了UserRouter := Router.Group("user"){UserRouter.GET("list", api.GetUserList)}
}
將路由配置到 main 中
package mainimport ("github.com/gin-gonic/gin"router2 "mxshop-api/user-web/router"
)func main() {router := gin.Default()ApiGroup := router.Group("/v1")router2.InitUserRouter(ApiGroup)
}
將 配置Router和Logger的初始化工作交給 Initialize 做
在 Initialize 目錄下創建一個 router.go:
并將創建 router 相關的工作交給 initialize去做,而不在 main 中做
package initializeimport ("github.com/gin-gonic/gin"router2 "mxshop-api/user-web/router"
)func Routers() *gin.Engine {Router := gin.Default()ApiGroup := Router.Group("/v1")router2.InitUserRouter(ApiGroup)return Router
}
在 main 中調用這個 Routers 函數用于創建 gin 以及路由
package mainimport ("fmt""go.uber.org/zap""mxshop-api/user-web/initialize"
)func main() {// 調用自己的 initlize 創建 RouterRouter := initialize.Routers()port := 8021// 若配置為 zap.NewDevelopment() 則為 開發環境級別的日志,其會打印 Debug、Info 的信息logger, _ := zap.NewProduction() // 配置為 NewProduction 視為 生產環境,不會打印 Debug 級別的日志zap.ReplaceGlobals(logger)// 打印日志// 這里的 S() 和 L() 方法的主要用途是:在底層創建安全的日志情況,否則我們自己寫的話需要自己考慮加鎖的問題zap.L().Info(fmt.Sprintf("啟動服務器,端口:%d", port))if err := Router.Run(fmt.Sprintf(":%d", port)); err != nil {zap.L().Panic("啟動失敗:", zap.Error(err))}}
另外的,我們的日志也可以交給 Initialize做:
Initialize/logger.go
package initializeimport "go.uber.org/zap"func InitLogger() {// 若配置為 zap.NewDevelopment() 則為 開發環境級別的日志,其會打印 Debug、Info 的信息logger, _ := zap.NewProduction() // 配置為 NewProduction 視為 生產環境,不會打印 Debug 級別的日志zap.ReplaceGlobals(logger)
}