diff --git a/client.go b/client.go index f8f697f..afbb57b 100644 --- a/client.go +++ b/client.go @@ -60,23 +60,12 @@ func defaultParseError(err error) error { return err } -// Options 连接选项,百分之百兼容第三方包的选项 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 4:57 下午 2021/2/27 -type Options struct { - Conf *redisInstance.Options // 第三方包的选项 - Logger *LoggerConfig // 日志的配置 - LoggerFieldConfig *LogFieldConfig // 日志字段的配置 -} - // RealClient 包装好的 redis client type RealClient struct { - Flag string // redis 标识 - Instance *redisInstance.Client // redis 实例 - Logger *zap.Logger // 日志实例 - LoggerFieldConfig *LogFieldConfig // 日志字段的配置 + Flag string // redis 标识 + Master *redisInstance.Client // redis 实例 + Slave *redisInstance.Client // redis 实例 + Logger *zap.Logger // 日志实例 } // NewClient 获取redis client实例 @@ -110,6 +99,36 @@ type OwnClient struct { parseErrorFunc func(err error) error // 解析err的function,解析执行结果是否为失败,有的场景,执行成功,返回 redis:nil / redis: } +// AddClientWithCfgFile 使用具体配置文件初始化 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:57 2022/6/15 +func (c *OwnClient) AddClientWithCfgFile(cfgPath string) error { + var ( + err error + ) + if err = c.loadConfig(cfgPath); nil != err { + return err + } + return c.init() +} + +// AddClientWithCfgDir 使用配置目录进行初始化 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 20:58 2022/6/15 +func (c *OwnClient) AddClientWithCfgDir(cfgDir string) error { + var ( + err error + ) + if err = c.batchLoadConfig(cfgDir); nil != err { + return err + } + return c.init() +} + // loadConfig 载入配置文件 // // Author : go_developer@163.com<白茶清欢> @@ -148,7 +167,7 @@ func (c *OwnClient) loadConfig(cfgPath string) error { } flag = strings.Join(fileArr[0:len(fileArr)-1], ".") default: - return CfgFileFormatErr(fileArr[len(fileArr)-1]) + // 不支持的格式,跳过 } c.lock.Lock() @@ -178,33 +197,15 @@ func (c *OwnClient) batchLoadConfig(cfgDir string) error { // // Date : 5:31 下午 2021/2/27 func (c *OwnClient) init() error { - - for flag, _ := range c.confTable { + var err error + for flag, conf := range c.confTable { c.instanceTable[flag] = &RealClient{ - Flag: flag, - //Instance: redisInstance.NewClient(conf.Conf), - Logger: nil, - //LoggerFieldConfig: conf.LoggerFieldConfig, + Flag: flag, + Master: redisInstance.NewClient(Config2Options(conf.Master)), + Slave: redisInstance.NewClient(Config2Options(conf.Slave)), } - if nil == c.instanceTable[flag].LoggerFieldConfig { - c.instanceTable[flag].LoggerFieldConfig = &LogFieldConfig{ - Message: "", - UsedTimeField: "", - CommandField: "", - FlagField: "", - } - } - if len(c.instanceTable[flag].LoggerFieldConfig.Message) == 0 { - c.instanceTable[flag].LoggerFieldConfig.Message = defaultMessage - } - if len(c.instanceTable[flag].LoggerFieldConfig.CommandField) == 0 { - c.instanceTable[flag].LoggerFieldConfig.CommandField = defaultCommandField - } - if len(c.instanceTable[flag].LoggerFieldConfig.UsedTimeField) == 0 { - c.instanceTable[flag].LoggerFieldConfig.UsedTimeField = defaultUsedTimeField - } - if len(c.instanceTable[flag].LoggerFieldConfig.FlagField) == 0 { - c.instanceTable[flag].LoggerFieldConfig.FlagField = defaultFlagField + if c.instanceTable[flag].Logger, err = logger.GetLogInstanceFromInputConfig(conf.Logger); nil != err { + return InitLoggerErr(flag, err) } } return nil @@ -239,16 +240,17 @@ func (c *OwnClient) GetRedisClient(flag string) (*RealClient, error) { // Author : go_developer@163.com<白茶清欢> // // Date : 8:52 下午 2021/2/27 -func (c *OwnClient) log(ctx *Context, realClient *RealClient, cmdResult redisInstance.Cmder, startTime int64, finishTime int64) { +func (c *OwnClient) log(ctx *Context, realClient *RealClient, isMaster bool, cmdResult redisInstance.Cmder, startTime int64, finishTime int64) { if nil == realClient || nil == realClient.Logger { return } realClient.Logger.Info( "执行redis命令日志记录", - zap.Any(ctx.RequestIDField, ctx.RequestID), // 上下文串联的requestID - zap.String(realClient.LoggerFieldConfig.CommandField, cmdResult.String()), // 执行的命令 - zap.Float64(realClient.LoggerFieldConfig.UsedTimeField, float64(finishTime-startTime)/1e6), // 耗时,单位: ms - zap.Error(cmdResult.Err()), // 异常信息 + zap.Any(ctx.RequestIDField, ctx.RequestID), // 上下文串联的requestID + zap.String("exec_command", cmdResult.String()), // 执行的命令 + zap.Bool("use_master", isMaster), // 是否使用主节点 + zap.Float64("exec_used_time", float64(finishTime-startTime)/1e6), // 耗时,单位: ms + zap.Error(cmdResult.Err()), // 异常信息 ) } @@ -272,10 +274,19 @@ func (c *OwnClient) CommandProxy(ctx *Context, flag string, cmd string, param .. if realClient, err = c.GetRedisClient(ctx.Flag); nil != err { return "", err } + flagArr := strings.Split(flag, "#") + if len(flagArr) == 1 { + flagArr = append(flagArr, "r") + } + isMater := flagArr[1] == "w" + redisClient := realClient.Slave + if isMater { + redisClient = realClient.Master + } redisCmd := append([]interface{}{cmd}, param...) startTime := time.Now().Unix() - cmdResult := realClient.Instance.Do(ctx.Ctx, redisCmd...) - go c.log(ctx, realClient, cmdResult, startTime, time.Now().UnixNano()) + cmdResult := redisClient.Do(ctx.Ctx, redisCmd...) + go c.log(ctx, realClient, isMater, cmdResult, startTime, time.Now().UnixNano()) return fmt.Sprintf("%v", cmdResult.Val()), c.parseErrorFunc(cmdResult.Err()) } diff --git a/config.go b/config.go index 777ce89..d1965ba 100644 --- a/config.go +++ b/config.go @@ -22,9 +22,10 @@ import ( // // Date : 12:23 2022/6/15 type FullConfig struct { - Logger *logger.InputLogConfig `json:"logger" yaml:"logger"` // 日志配置 - Master *Config `json:"master" yaml:"master"` // 主节点 - Slave *Config `json:"slave" yaml:"slave"` // 从节点 + ExtraFieldList []string `json:"extra_field_list" yaml:"extra_field_list"` // 从上下文抽取的字段信息 + Logger *logger.InputLogConfig `json:"logger" yaml:"logger"` // 日志配置 + Master *Config `json:"master" yaml:"master"` // 主节点 + Slave *Config `json:"slave" yaml:"slave"` // 从节点 } // Config redis的配置 @@ -43,7 +44,6 @@ type Config struct { // Hook that is called when new connection is established. // OnConnect func(ctx context.Context, cn *redis.Conn) error - // Use the specified Username to authenticate the current connection // with one of the connections defined in the ACL list when connecting // to a Redis 6.0 instance, or greater, that is using the Redis ACL system. diff --git a/error.go b/error.go index 24bf644..79764b6 100644 --- a/error.go +++ b/error.go @@ -86,3 +86,12 @@ func CfgFilePathError() error { func CfgFileFormatErr(realFormat string) error { return errors.Errorf("非法的配置文件格式 : %s , 当前仅支持 yaml / yml / json", realFormat) } + +// InitLoggerErr 初始化日志失败 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 21:12 2022/6/15 +func InitLoggerErr(flag string, err error) error { + return errors.Wrapf(err, "%s 配置日志初始化失败", flag) +}