diff --git a/go.mod b/go.mod index 142e69b..133191e 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,12 @@ require ( github.com/google/uuid v1.6.0 github.com/imdario/mergo v0.3.16 github.com/json-iterator/go v1.1.12 + github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/nsqio/go-nsq v1.1.0 github.com/robfig/cron/v3 v3.0.1 github.com/spf13/cast v1.6.0 go.uber.org/zap v1.27.0 + golang.org/x/text v0.14.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 gorm.io/gorm v1.25.9 ) @@ -63,7 +65,6 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -82,7 +83,6 @@ require ( golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.20.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 2462343..b023323 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= diff --git a/sdk/i18n/example/accept_language.go b/sdk/i18n/example/accept_language.go index 06001dd..37b7d43 100644 --- a/sdk/i18n/example/accept_language.go +++ b/sdk/i18n/example/accept_language.go @@ -1,7 +1,6 @@ package example import ( - "fmt" "github.com/MrKrisYu/koi-go-common/sdk/api/header" "github.com/gin-gonic/gin" "golang.org/x/text/language" @@ -18,7 +17,7 @@ func GetLang(ctx *gin.Context) language.Tag { acceptLanguage, _ = ctx.GetQuery(LanguageReqQueryKey) } if len(acceptLanguage) == 0 { - fmt.Printf("[Middleware-AcceptLanguage] got lang=%s, match=%s \n\n", acceptLanguage, matchedTag.String()) + //fmt.Printf("[Middleware-AcceptLanguage] got lang=%s, match=%s \n\n", acceptLanguage, matchedTag.String()) return matchedTag } matcher := language.NewMatcher(AllowedLanguage) @@ -26,7 +25,7 @@ func GetLang(ctx *gin.Context) language.Tag { if confidence != language.No { matchedTag = AllowedLanguage[index] } - fmt.Printf("[Middleware-AcceptLanguage] got lang=%s, match=%s \n\n", acceptLanguage, matchedTag.String()) + //fmt.Printf("[Middleware-AcceptLanguage] got lang=%s, match=%s \n\n", acceptLanguage, matchedTag.String()) return matchedTag } diff --git a/sdk/i18n/example/default.go b/sdk/i18n/example/default.go index a7e5ee3..1fa31fa 100644 --- a/sdk/i18n/example/default.go +++ b/sdk/i18n/example/default.go @@ -37,12 +37,12 @@ func initialI18nBundle(bundle *i18n.Bundle, matcher language.Matcher) (map[langu // 检查是否为允许的语言 _, i, c := matcher.Match(language.Make(langStr)) if c == language.No { - fmt.Printf("[initialI18nBundle] load message file failed, langStr = %s does not match any of the allowed tags(%+v) \n\n", langStr, AllowedLanguage) + //fmt.Printf("[initialI18nBundle] load message file failed, langStr = %s does not match any of the allowed tags(%+v) \n\n", langStr, AllowedLanguage) continue } bindTag := AllowedLanguage[i] if _, ok := localizers[bindTag]; ok { - fmt.Printf("[initialI18nBundle] localizer of tag=%s already exists, langStr = %s\n\n", bindTag.String(), langStr) + //fmt.Printf("[initialI18nBundle] localizer of tag=%s already exists, langStr = %s\n\n", bindTag.String(), langStr) continue } // 加载语言资源 @@ -115,7 +115,7 @@ func (d *DefaultTranslator) GetLocalizer(lang language.Tag) *i18n.Localizer { func (d *DefaultTranslator) Tr(lang language.Tag, message i18n2.Message) string { localizer := d.GetLocalizer(lang) if localizer == nil { - fmt.Printf("[Tr] %s does not match any locaizer, using default lang:%s \n", lang.String(), DefaultLanguage.String()) + //fmt.Printf("[Tr] %s does not match any locaizer, using default lang:%s \n", lang.String(), DefaultLanguage.String()) localizer = d.GetLocalizer(DefaultLanguage) } msg, err := localizer.Localize(&i18n.LocalizeConfig{ @@ -130,7 +130,7 @@ func (d *DefaultTranslator) Tr(lang language.Tag, message i18n2.Message) string func (d *DefaultTranslator) TrWithData(lang language.Tag, message i18n2.Message) string { localizer := d.GetLocalizer(lang) if localizer == nil { - fmt.Printf("%s does not match any locaizer, using default lang:%s \n", lang.String(), DefaultLanguage.String()) + //fmt.Printf("%s does not match any locaizer, using default lang:%s \n", lang.String(), DefaultLanguage.String()) localizer = d.GetLocalizer(DefaultLanguage) } msg, err := localizer.Localize(&i18n.LocalizeConfig{ diff --git a/sdk/middleware/gin_logger.go b/sdk/middleware/gin_logger.go index 2ed6e12..208515d 100644 --- a/sdk/middleware/gin_logger.go +++ b/sdk/middleware/gin_logger.go @@ -16,6 +16,11 @@ import ( func GinLogger(trafficKey string) gin.HandlerFunc { return func(c *gin.Context) { requestLogger := api.GetRequestLogger(c) + requestId := c.Request.Header.Get(trafficKey) + // 获取 handler 名称 + handlerName := runtime.FuncForPC(reflect.ValueOf(c.Handler()).Pointer()).Name() + // 请求来源的IP地址 + clientIP := c.ClientIP() // 获取请求地址和方法 requestPath := c.Request.URL.String() requestMethod := c.Request.Method @@ -50,6 +55,24 @@ func GinLogger(trafficKey string) gin.HandlerFunc { // 处理请求前记录时间 start := time.Now() + + logTemplate := "X-Request-Id:%s" + + "\n---------------------------请求开始-----------------------------\n" + + "CLASS METHOD: %s\n" + + "请求地址: %s\n" + + "请求参数: %+v\n" + + "HTTP METHOD: %s\n" + + "IP: %s\n" + logStr := fmt.Sprintf(logTemplate, + requestId, + handlerName, + requestPath, + reqParams, + requestMethod, + clientIP, + ) + requestLogger.Info(logStr) + // 处理请求 c.Next() // 处理请求后记录时间 @@ -78,38 +101,24 @@ func GinLogger(trafficKey string) gin.HandlerFunc { responseData = fmt.Sprintf("[UNSUPPORTED CONTENT TYPE: %s]", contentTypeWithoutParams) } - clientIP := c.ClientIP() - // 获取 handler 名称 - handlerName := runtime.FuncForPC(reflect.ValueOf(c.Handler()).Pointer()).Name() + // 响应错误信息 errorMessage := c.Errors.ByType(gin.ErrorTypePrivate).String() - requestId := c.Request.Header.Get(trafficKey) - logTemplate := "\n---------------------------请求开始-----------------------------\n" + - "X-Request-Id: %s\n" + - "CLASS METHOD: %s\n" + - "请求地址: %s\n" + - "请求参数: %+v\n" + - "HTTP METHOD: %s\n" + - "IP: %s\n" + + responseTemplate := "X-Request-Id:%s\n" + "HTTP STATUS: %d\n" + "Error Messages: %s\n" + "响应数据: %s\n" + "响应大小: %d\n" + "耗时: %s\n" + "---------------------------请求结束-----------------------------\n" - logStr := fmt.Sprintf(logTemplate, + respLogStr := fmt.Sprintf(responseTemplate, requestId, - handlerName, - requestPath, - reqParams, - requestMethod, - clientIP, responseStatus, errorMessage, responseData, recorder.Body.Len(), cost.String(), ) - requestLogger.Info(logStr) + requestLogger.Info(respLogStr) } } diff --git a/storage/cache/redis.go b/storage/cache/redis.go new file mode 100644 index 0000000..104a9d9 --- /dev/null +++ b/storage/cache/redis.go @@ -0,0 +1,82 @@ +package cache + +import ( + "context" + "github.com/go-redis/redis/v9" + "time" +) + +// NewRedis redis模式 +func NewRedis(client *redis.Client, options *redis.Options) (*Redis, error) { + if client == nil { + client = redis.NewClient(options) + } + r := &Redis{ + client: client, + } + err := r.connect() + if err != nil { + return nil, err + } + return r, nil +} + +// Redis cache implement +type Redis struct { + client *redis.Client +} + +func (*Redis) String() string { + return "redis" +} + +// connect connect test +func (r *Redis) connect() error { + var err error + _, err = r.client.Ping(context.TODO()).Result() + return err +} + +// Get from key +func (r *Redis) Get(key string) (string, error) { + return r.client.Get(context.TODO(), key).Result() +} + +// Set value with key and expire time +func (r *Redis) Set(key string, val interface{}, expire int) error { + return r.client.Set(context.TODO(), key, val, time.Duration(expire)*time.Second).Err() +} + +// Del delete key in redis +func (r *Redis) Del(key string) error { + return r.client.Del(context.TODO(), key).Err() +} + +// HashGet from key +func (r *Redis) HashGet(hk, key string) (string, error) { + return r.client.HGet(context.TODO(), hk, key).Result() +} + +// HashDel delete key in specify redis's hashtable +func (r *Redis) HashDel(hk, key string) error { + return r.client.HDel(context.TODO(), hk, key).Err() +} + +// Increase +func (r *Redis) Increase(key string) error { + return r.client.Incr(context.TODO(), key).Err() +} + +func (r *Redis) Decrease(key string) error { + return r.client.Decr(context.TODO(), key).Err() +} + +// Set ttl +func (r *Redis) Expire(key string, dur time.Duration) error { + return r.client.Expire(context.TODO(), key, dur).Err() +} + +// GetClient 暴露原生client +func (r *Redis) GetClient() *redis.Client { + return r.client +} diff --git a/storage/locker/redis.go b/storage/locker/redis.go new file mode 100644 index 0000000..5822245 --- /dev/null +++ b/storage/locker/redis.go @@ -0,0 +1,32 @@ +package locker + +import ( + "context" + "github.com/go-redis/redis/v9" + "time" + + "github.com/bsm/redislock" +) + +// NewRedis 初始化locker, redis分布锁 +func NewRedis(c *redis.Client) *Redis { + return &Redis{ + client: c, + } +} + +type Redis struct { + client *redis.Client + mutex *redislock.Client +} + +func (Redis) String() string { + return "redis" +} + +func (r *Redis) Lock(key string, ttl int64, options *redislock.Options) (*redislock.Lock, error) { + if r.mutex == nil { + r.mutex = redislock.New(r.client) + } + return r.mutex.Obtain(context.TODO(), key, time.Duration(ttl)*time.Second, options) +} diff --git a/test/application.yaml b/test/application.yaml index b35ffad..87eade2 100644 --- a/test/application.yaml +++ b/test/application.yaml @@ -9,6 +9,7 @@ settings: demoMsg: "" log: + enable: true # 日志框架 driver: "zap" # 日志等级, 可用等级参考 logger/level包下的 Level.String() diff --git a/test/main_test.go b/test/main_test.go index 4e73dbc..5a0dd5b 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -27,7 +27,9 @@ func TestGinLogger(t *testing.T) { translator := example.NewDefaultTranslator(example.DefaultLanguage, example.AllowedLanguage) engine := gin.Default() - engine.Use(middleware.GinLogger("X-Request-Id")).Use(example.AcceptLanguage()) + engine.Use(middleware.RequestId("X-Request-Id")). + Use(middleware.GinLogger("X-Request-Id")). + Use(example.AcceptLanguage()) engine.POST("/testJson", func(c *gin.Context) { var req JsonRequest