From 3dbc060d655b22c604d32a9104186fa0eb8f95b8 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 11:08:23 +0800 Subject: [PATCH 01/39] modify log --- src/v1/log/log.go | 3 +- src/v1/log/log_null.go | 67 +-------------------------------- src/v1/log/log_writer.go | 80 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 68 deletions(-) create mode 100644 src/v1/log/log_writer.go diff --git a/src/v1/log/log.go b/src/v1/log/log.go index a22a93c..20cc5c5 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -38,7 +38,7 @@ type ILog interface { Ctl(bool) ILog //控制是否打印,如 Ctl(true).Warn(...) } -//InvokeLog fast use log +// InvokeLog fast use log in struct type InvokeLog struct { logger ILog } @@ -69,7 +69,6 @@ func (ink *InvokeLog) Log(level int8, msg string) { case PanicLog: ink.logger.Panic(msg) } - } func (ink *InvokeLog) Debug(log string, params ...interface{}) { diff --git a/src/v1/log/log_null.go b/src/v1/log/log_null.go index d4a8fd4..1ae71a2 100644 --- a/src/v1/log/log_null.go +++ b/src/v1/log/log_null.go @@ -1,73 +1,8 @@ package log -import ( - "fmt" - "io" - "time" -) - -//空日志 +// 空日志 var _nullLog = NewNullLog() func NewNullLog() *writerLog { return NewWriterLog(nil, DebugLog) } - -//指定writer的日志打印 -type writerLog struct { - w io.Writer - level int -} - -func NewWriterLog(w io.Writer, level int) *writerLog { - return &writerLog{ - w: w, - level: level, - } -} - -func (l writerLog) Debug(format string, params ...interface{}) { - l.logItem(DebugLog, format, params...) -} -func (l writerLog) Info(format string, params ...interface{}) { - l.logItem(InfoLog, format, params...) -} -func (l writerLog) Warn(format string, params ...interface{}) { - l.logItem(WarnLog, format, params...) -} -func (l writerLog) Error(format string, params ...interface{}) { - l.logItem(ErrorLog, format, params...) -} -func (l writerLog) Panic(format string, params ...interface{}) { - l.logItem(PanicLog, format, params...) -} -func (l writerLog) Fatal(format string, params ...interface{}) { - l.logItem(FatalLog, format, params...) -} - -func (l writerLog) logItem(level int, format string, params ...interface{}) { - if level < l.level { - return - } - if l.w == nil { - return - } - if len(params) <= 0 { - s := LogLevelMap[level] - a := fmt.Sprintf("[%s]%s: %s\n", s, time.Now().Format(time.RFC3339), format) - l.w.Write([]byte(a)) - return - } - l.logItem(level, fmt.Sprintf(format, params...)) -} - -func (l writerLog) Write(p []byte) (n int, err error){ - return l.w.Write(p) -} - -func (l writerLog) Ctl(t bool) ILog { - if !t { - return _nullLog - } - return l -} diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go new file mode 100644 index 0000000..c7d1bf1 --- /dev/null +++ b/src/v1/log/log_writer.go @@ -0,0 +1,80 @@ +package log + +import ( + "fmt" + "io" + "time" +) + +// 指定writer的日志打印 +type writerLog struct { + w io.Writer + level int + caller int +} + +func NewWriterLog(w io.Writer, level int) *writerLog { + return &writerLog{ + w: w, + level: level, + } +} + +func (l *writerLog) Debug(format string, params ...interface{}) { + l.logItem(DebugLog, format, params...) +} + +func (l *writerLog) Info(format string, params ...interface{}) { + l.logItem(InfoLog, format, params...) +} + +func (l *writerLog) Warn(format string, params ...interface{}) { + l.logItem(WarnLog, format, params...) +} + +func (l *writerLog) Error(format string, params ...interface{}) { + l.logItem(ErrorLog, format, params...) +} + +func (l *writerLog) Panic(format string, params ...interface{}) { + l.logItem(PanicLog, format, params...) +} + +func (l *writerLog) Fatal(format string, params ...interface{}) { + l.logItem(FatalLog, format, params...) +} + +func (l *writerLog) logItem(level int, format string, params ...interface{}) { + if level < l.level { + return + } + if l.w == nil { + return + } + if len(params) <= 0 { + s := LogLevelMap[level] + a := fmt.Sprintf("[%s]%s: %s\n", s, time.Now().Format(time.RFC3339), format) + l.w.Write([]byte(a)) + return + } + l.logItem(level, fmt.Sprintf(format, params...)) +} + +func (l *writerLog) Write(p []byte) (n int, err error) { + return l.w.Write(p) +} + +func (l *writerLog) Ctl(t bool) ILog { + if !t { + return _nullLog + } + return l +} + +func (l *writerLog) Caller(offset int) *writerLog { + return &writerLog{ + w: l.w, + level: l.level, + caller: offset, + } +} -- Gitee From 6039e05a01b6c6fed9c70782d981c51d84e98d4a Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 12:00:50 +0800 Subject: [PATCH 02/39] add log --- src/v1/config/log.go | 48 +++++++++++++++---- src/v1/log/log.go | 77 ++++++++++++++++++++++++++++- src/v1/log/log_default.go | 88 +++++++++++++++++----------------- src/v1/log/log_default_test.go | 7 ++- src/v1/log/log_null_test.go | 10 ++-- src/v1/log/log_writer.go | 19 ++++---- src/v1/log/log_zap.go | 88 +++++++++++++++------------------- 7 files changed, 216 insertions(+), 121 deletions(-) diff --git a/src/v1/config/log.go b/src/v1/config/log.go index 64fec33..d651850 100644 --- a/src/v1/config/log.go +++ b/src/v1/config/log.go @@ -1,7 +1,26 @@ package config -//日志配置 +// 日志配置 type LogConfig struct { + //部分还是使用老配置 + pastLogConfig + + //日志路径 + LPath string `default:"./runtime/logs/app.log" yaml:"LPath"` + + //是否包含文件路径 + // 0: 不包含,1:短文件名,2:完整路径 + LFilepath int `default:"0" yaml:"LFilepath"` + + //日志等级,与LogLevel一致 + LLevel string `default:"debug" yaml:"LLoglevel"` + + //对应 runtime.Caller + LCallerSkip int `default:"0" yaml:"LCallerSkip"` +} + +// pastLogConfig 之前的配置 +type pastLogConfig struct { LogPath string `default:"" yaml:"LogPath"` LogLevel string `default:"debug" yaml:"LogLevel"` @@ -13,14 +32,23 @@ type LogConfig struct { LogCompress bool `default:"false" yaml:"LogCompress"` } -//默认日志配置 -var DefaultLogConfig = &LogConfig{ - LogPath: "./runtime/logs/app.log", - LogMaxSize: 128, // 每个日志文件保存的大小 单位:M - LogMaxAge: 7, // 文件最多保存多少天 - LogMaxBackups: 30, // 日志文件最多保存多少个备份 - LogCompress: false, // 是否压缩 +// DefiLogConfig 默认日志配置 +func DefiLogConfig() *LogConfig { + return &LogConfig{ + pastLogConfig: pastLogConfig{ + LogPath: "./runtime/logs/app.log", + LogMaxSize: 128, // 每个日志文件保存的大小 单位:M + LogMaxAge: 7, // 文件最多保存多少天 + LogMaxBackups: 30, // 日志文件最多保存多少个备份 + LogCompress: false, // 是否压缩 + + LogSyncStdOut: true, + LogLevel: "Debug", + }, - LogSyncStdOut: true, - LogLevel: "Debug", + LPath: "./runtime/logs/app.log", + LFilepath: 1, + LLevel: "debug", + LCallerSkip: 0, + } } diff --git a/src/v1/log/log.go b/src/v1/log/log.go index 20cc5c5..4cf074b 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -2,6 +2,9 @@ package log import ( "fmt" + "gitee.com/scottq/go-framework/src/v1/config" + "runtime" + "strings" ) const ( @@ -14,7 +17,7 @@ const ( FatalLog ) -var LogLevelMap = map[int]string{ +var LevelMap = map[int]string{ TraceLog: "Trace", DebugLog: "Debug", InfoLog: "Info", @@ -23,6 +26,15 @@ var LogLevelMap = map[int]string{ FatalLog: "Fatal", PanicLog: "Panic", } +var LevelMapReverse = map[string]int{} + +var LogLevelMap = LevelMap + +func init() { + for k, v := range LevelMap { + LevelMapReverse[v] = k + } +} const DefaultLogPath = "./runtime/logs/app.log" @@ -146,3 +158,66 @@ func (ink *InvokeLog) Fatal(log string, params ...interface{}) { ink.logger.Fatal(fmt.Sprintf(log, params...)) return } + +type logHelper struct { +} + +func (l logHelper) lFilepath(c *config.LogConfig) string { + if c == nil { + return "" + } + + switch c.LFilepath { + case 1: + //短文件名 + _, file, line, _ := runtime.Caller(l.lCallerSkip(c)) + if index := strings.LastIndex(file, "/"); index >= 0 { + file = file[index+1:] + } else if index = strings.LastIndex(file, "\\"); index >= 0 { + file = file[index+1:] + } + return fmt.Sprintf("%s:%d", file, line) + case 2: + //完整文件名 + _, file, line, _ := runtime.Caller(l.lCallerSkip(c)) + return fmt.Sprintf("%s:%d", file, line) + default: + return "" + } +} + +func (l logHelper) lCallerSkip(c *config.LogConfig) int { + if c == nil { + return 0 + } + + return c.LCallerSkip +} + +func (l logHelper) lLogPath(c *config.LogConfig) string { + if c == nil { + return "" + } + if len(c.LPath) > 0 { + return c.LPath + } + return c.LogPath +} + +func (l logHelper) lLogLevel(c *config.LogConfig) string { + if c == nil { + return "debug" + } + if len(c.LLevel) > 0 { + return c.LLevel + } + return c.LogLevel +} + +func (l logHelper) lLogLevelInt(c *config.LogConfig) int { + a, exist := LevelMapReverse[l.lLogLevel(c)] + if !exist { + return 0 + } + return a +} diff --git a/src/v1/log/log_default.go b/src/v1/log/log_default.go index a8db6fa..8ef66b8 100644 --- a/src/v1/log/log_default.go +++ b/src/v1/log/log_default.go @@ -13,28 +13,30 @@ import ( "time" ) -//MyLogger 日志 +// MyLogger 日志 type MyLogger struct { name string logger *log.Logger cnf *config.LogConfig + + logHelper } -func (logger *MyLogger) Write(p []byte) (int, error) { +func (l *MyLogger) Write(p []byte) (int, error) { arr := strings.Split(string(p), "\n") level := arr[len(arr)-2] content := strings.Join(arr[0:len(arr)-2], "") - l, err := strconv.Atoi(level) + tmp, err := strconv.Atoi(level) if err != nil { return 0, err } - levelStr, ok := LogLevelMap[l] + levelStr, ok := LogLevelMap[tmp] if !ok { - return 0, fmt.Errorf("log level not exists : %d", l) + return 0, fmt.Errorf("log level not exists : %d", tmp) } - file, err := os.OpenFile(logger.LogPath(), os.O_CREATE|os.O_RDWR|os.O_APPEND, 0777) + file, err := os.OpenFile(l.LogPath(), os.O_CREATE|os.O_RDWR|os.O_APPEND, 0777) if err != nil { return 0, err } @@ -42,21 +44,16 @@ func (logger *MyLogger) Write(p []byte) (int, error) { pl := []byte(fmt.Sprintf("%s %s\n", levelStr, content)) - if logger.cnf.LogSyncStdOut { + if l.cnf.LogSyncStdOut { fmt.Print(string(pl)) } return file.Write(pl) } -//设置的path -func (logger *MyLogger) Path() string { - return logger.cnf.LogPath -} - -func (logger *MyLogger) checkLogPath() error { +func (l *MyLogger) checkLogPath() error { var err error - p := logger.LogPath() + p := l.LogPath() absPath, err := filepath.Abs(filepath.Dir(p)) if err != nil { return err @@ -79,9 +76,10 @@ func (logger *MyLogger) checkLogPath() error { return nil } -//LogPath 最终日志path -func (logger *MyLogger) LogPath() string { - p := logger.cnf.LogPath +// LogPath 最终日志path +func (l *MyLogger) LogPath() string { + p := l.lLogPath(l.cnf) + if p == "" { p = "default.log" } @@ -98,70 +96,70 @@ func (logger *MyLogger) LogPath() string { return fmt.Sprintf("%s-%s.log", p[:pos], t) } -func (logger *MyLogger) Debug(format string, params ...interface{}) { +func (l *MyLogger) Debug(format string, params ...interface{}) { if len(params) <= 0 { - logger.logItem(DebugLog, format) + l.logItem(DebugLog, format) return } - logger.Debug(fmt.Sprintf(format, params...)) + l.Debug(fmt.Sprintf(format, params...)) return } -func (logger *MyLogger) Info(format string, params ...interface{}) { +func (l *MyLogger) Info(format string, params ...interface{}) { if len(params) <= 0 { - logger.logItem(InfoLog, format) + l.logItem(InfoLog, format) return } - logger.Info(fmt.Sprintf(format, params...)) + l.Info(fmt.Sprintf(format, params...)) return } -func (logger *MyLogger) Warn(format string, params ...interface{}) { +func (l *MyLogger) Warn(format string, params ...interface{}) { if len(params) <= 0 { - logger.logItem(WarnLog, format) + l.logItem(WarnLog, format) return } - logger.Warn(fmt.Sprintf(format, params...)) + l.Warn(fmt.Sprintf(format, params...)) return } -func (logger *MyLogger) Error(format string, params ...interface{}) { +func (l *MyLogger) Error(format string, params ...interface{}) { if len(params) <= 0 { - logger.logItem(ErrorLog, format) + l.logItem(ErrorLog, format) return } - logger.Error(fmt.Sprintf(format, params...)) + l.Error(fmt.Sprintf(format, params...)) return } -func (logger *MyLogger) Fatal(format string, params ...interface{}) { +func (l *MyLogger) Fatal(format string, params ...interface{}) { if len(params) <= 0 { - logger.logItem(FatalLog, format) + l.logItem(FatalLog, format) return } - logger.Fatal(fmt.Sprintf(format, params...)) + l.Fatal(fmt.Sprintf(format, params...)) return } -func (logger *MyLogger) Panic(format string, params ...interface{}) { +func (l *MyLogger) Panic(format string, params ...interface{}) { if len(params) <= 0 { - logger.logItem(PanicLog, format) + l.logItem(PanicLog, format) return } - logger.Panic(fmt.Sprintf(format, params...)) + l.Panic(fmt.Sprintf(format, params...)) return } -func (logger *MyLogger) Ctl(t bool) ILog { +func (l *MyLogger) Ctl(t bool) ILog { if !t { return _nullLog } - return logger + return l } -func (logger *MyLogger) logItem(level int, s string) { +func (l *MyLogger) logItem(level int, s string) { sl := fmt.Sprintf("%s\n%d\n", s, level) - err := logger.logger.Output(3, sl) + err := l.logger.Output(3, sl) if err != nil { panic(err) return @@ -169,15 +167,17 @@ func (logger *MyLogger) logItem(level int, s string) { return } -func (logger *MyLogger) logItemf(level int, format string, params ...interface{}) error { +func (l *MyLogger) logItemf(level int, format string, params ...interface{}) error { sl := fmt.Sprintf("%s\n%d\n", fmt.Sprintf(format, params...), level) - return logger.logger.Output(3, sl) + return l.logger.Output(3, sl) } -func NewDefaultLogger(name string, c *config.LogConfig) ILog { - if c == nil { - c = &config.LogConfig{} +func NewDefaultLogger(name string, cs ...*config.LogConfig) ILog { + c := config.DefiLogConfig() + if len(cs) > 0 && cs[0] != nil { + c = cs[0] } + myLogger := &MyLogger{ cnf: c, } diff --git a/src/v1/log/log_default_test.go b/src/v1/log/log_default_test.go index 0cc6240..d60c76a 100644 --- a/src/v1/log/log_default_test.go +++ b/src/v1/log/log_default_test.go @@ -9,10 +9,9 @@ const TestRuntimePath = "../../../examples/runtime" func TestNewDefaultLoggerInfo(t *testing.T) { - c := &v1config.LogConfig{ - LogPath: TestRuntimePath + "/logs/test.log", - LogSyncStdOut: true, - } + c := v1config.DefiLogConfig() + c.LogPath = TestRuntimePath + "/logs/test.log" + c.LogSyncStdOut = true logger := NewDefaultLogger("test", c) logger.Info("hello world") diff --git a/src/v1/log/log_null_test.go b/src/v1/log/log_null_test.go index ae358d9..c2a299a 100644 --- a/src/v1/log/log_null_test.go +++ b/src/v1/log/log_null_test.go @@ -1,9 +1,11 @@ package log -import "testing" +import ( + "testing" +) -func TestNullLog(t *testing.T){ - l:=NewNullLog() +func TestNullLog(t *testing.T) { + l := NewNullLog() l.Warn("") -} +} diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index c7d1bf1..4ec50a9 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -2,6 +2,7 @@ package log import ( "fmt" + "gitee.com/scottq/go-framework/src/v1/config" "io" "time" ) @@ -11,12 +12,20 @@ type writerLog struct { w io.Writer level int caller int + + cnf *config.LogConfig } -func NewWriterLog(w io.Writer, level int) *writerLog { +func NewWriterLog(w io.Writer, level int, cs ...*config.LogConfig) *writerLog { + c := config.DefiLogConfig() + if len(cs) > 0 && cs[0] != nil { + c = cs[0] + } + return &writerLog{ w: w, level: level, + cnf: c, } } @@ -70,11 +79,3 @@ func (l *writerLog) Ctl(t bool) ILog { } return l } - -func (l *writerLog) Caller(offset int) *writerLog { - return &writerLog{ - w: l.w, - level: l.level, - caller: offset, - } -} diff --git a/src/v1/log/log_zap.go b/src/v1/log/log_zap.go index d5be230..016c111 100644 --- a/src/v1/log/log_zap.go +++ b/src/v1/log/log_zap.go @@ -7,18 +7,18 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" - "strings" ) -//DefaultZapLog default logger +// DefaultZapLog default logger type DefaultZapLog struct { - logPath string - config *ZapLogConfig //已废弃,请使用cnf - cnf *config.LogConfig - zapLog *zap.Logger + config *ZapLogConfig //已废弃,请使用cnf + cnf *config.LogConfig + zapLog *zap.Logger + + logHelper } -//ZapLogConfig 日志配置,已经废弃,请使用config.LogConfig +// ZapLogConfig 日志配置,已经废弃,请使用config.LogConfig type ZapLogConfig struct { SyncStdOut bool //是否同步输出至标准输出 MaxSize int // 每个日志文件保存的大小 单位:M @@ -29,21 +29,22 @@ type ZapLogConfig struct { LogLevel string //日志级别 } -func NewZapLog(name string, logPath string, c *config.LogConfig) *DefaultZapLog { - if c == nil { - c = config.DefaultLogConfig +func NewZapLog(name string, logPath string, cs ...*config.LogConfig) *DefaultZapLog { + c := config.DefiLogConfig() + if len(cs) > 0 && cs[0] != nil { + c = cs[0] } - if logPath == "" { - logPath = c.LogPath + + l := &DefaultZapLog{ + cnf: c, } - c.LogPath = logPath hook := lumberjack.Logger{ - Filename: logPath, // 日志文件路径 - MaxSize: c.LogMaxSize, // 每个日志文件保存的大小 单位:M - MaxAge: c.LogMaxAge, // 文件最多保存多少天 - MaxBackups: c.LogMaxBackups, // 日志文件最多保存多少个备份 - Compress: c.LogCompress, // 是否压缩 + Filename: l.lLogPath(l.cnf), // 日志文件路径 + MaxSize: c.LogMaxSize, // 每个日志文件保存的大小 单位:M + MaxAge: c.LogMaxAge, // 文件最多保存多少天 + MaxBackups: c.LogMaxBackups, // 日志文件最多保存多少个备份 + Compress: c.LogCompress, // 是否压缩 } encoderConfig := zapcore.EncoderConfig{ MessageKey: "msg", @@ -75,37 +76,27 @@ func NewZapLog(name string, logPath string, c *config.LogConfig) *DefaultZapLog ) // 构造日志 - zapLogger := zap.New(core, - zap.AddCaller(), // 开启开发模式,堆栈跟踪 - zap.AddCallerSkip(2), //二次封装后需要修改调用堆栈文件位置 - zap.Development(), // 开启文件及行号 - zap.Fields(zap.String("Name", name)), // 设置初始化字段 + l.zapLog = zap.New(core, + zap.AddCaller(), // 开启开发模式,堆栈跟踪 + zap.AddCallerSkip(2+l.lCallerSkip(c)), //二次封装后需要修改调用堆栈文件位置 + zap.Development(), // 开启文件及行号 + zap.Fields(zap.String("Name", name)), // 设置初始化字段 ) - logger := &DefaultZapLog{ - logPath: logPath, - zapLog: zapLogger, - cnf: c, - } - logger.Info("log init success") - return logger + l.Info("log init success") + return l +} + +var ZapLogLevelMap = map[int]zapcore.Level{ + DebugLog: zapcore.DebugLevel, + InfoLog: zapcore.InfoLevel, + WarnLog: zapcore.WarnLevel, + ErrorLog: zapcore.ErrorLevel, + PanicLog: zapcore.PanicLevel, + FatalLog: zapcore.FatalLevel, } func levelToZapLevel(level string) zapcore.Level { - switch strings.ToUpper(level) { - case "DEBUG": - return zapcore.DebugLevel - case "INFO": - return zapcore.InfoLevel - case "WARN": - return zapcore.WarnLevel - case "ERROR": - return zapcore.ErrorLevel - case "PANIC": - return zapcore.PanicLevel - case "FATAL": - return zapcore.FatalLevel - } - return zapcore.DebugLevel + return ZapLogLevelMap[LevelMapReverse[level]] } func (l DefaultZapLog) Write(p []byte) (n int, err error) { @@ -115,10 +106,9 @@ func (l DefaultZapLog) Write(p []byte) (n int, err error) { func (l *DefaultZapLog) Caller(offset int) *DefaultZapLog { return &DefaultZapLog{ - l.cnf.LogPath, - l.config, - l.cnf, - l.zapLog.WithOptions( + config: l.config, + cnf: l.cnf, + zapLog: l.zapLog.WithOptions( zap.AddCallerSkip(offset), //二次封装后需要修改调用堆栈文件位置 ), } -- Gitee From a7d794c4615797220e2d0287bdba341ec60f9e35 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 12:04:06 +0800 Subject: [PATCH 03/39] add write --- src/v1/log/log.go | 11 ++++++++--- src/v1/log/log_writer.go | 5 +++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/v1/log/log.go b/src/v1/log/log.go index 4cf074b..ab607ac 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -162,6 +162,11 @@ func (ink *InvokeLog) Fatal(log string, params ...interface{}) { type logHelper struct { } +func (l logHelper) initConfig(c *config.LogConfig) { + c.LLevel = strings.ToUpper(c.LLevel) + c.LogLevel = strings.ToUpper(c.LLevel) +} + func (l logHelper) lFilepath(c *config.LogConfig) string { if c == nil { return "" @@ -206,12 +211,12 @@ func (l logHelper) lLogPath(c *config.LogConfig) string { func (l logHelper) lLogLevel(c *config.LogConfig) string { if c == nil { - return "debug" + return "DEBUG" } if len(c.LLevel) > 0 { - return c.LLevel + return strings.ToUpper(c.LLevel) } - return c.LogLevel + return strings.ToUpper(c.LogLevel) } func (l logHelper) lLogLevelInt(c *config.LogConfig) int { diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index 4ec50a9..e1567ee 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -14,6 +14,8 @@ type writerLog struct { caller int cnf *config.LogConfig + + logHelper } func NewWriterLog(w io.Writer, level int, cs ...*config.LogConfig) *writerLog { @@ -61,8 +63,7 @@ func (l *writerLog) logItem(level int, format string, params ...interface{}) { return } if len(params) <= 0 { - s := LogLevelMap[level] - a := fmt.Sprintf("[%s]%s: %s\n", s, time.Now().Format(time.RFC3339), format) + a := fmt.Sprintf("[%s]%s %s: %s\n", l.lLogLevel(l.cnf), l.lFilepath(l.cnf), time.Now().Format(time.RFC3339), format) l.w.Write([]byte(a)) return } -- Gitee From 69a972cb6eecf331b4837bd994a828c4e43dc568 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 13:44:11 +0800 Subject: [PATCH 04/39] modify skip --- src/v1/log/log.go | 6 +++--- src/v1/log/log_writer.go | 2 +- src/v1/log/log_writer_test.go | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/v1/log/log_writer_test.go diff --git a/src/v1/log/log.go b/src/v1/log/log.go index ab607ac..354df4f 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -167,7 +167,7 @@ func (l logHelper) initConfig(c *config.LogConfig) { c.LogLevel = strings.ToUpper(c.LLevel) } -func (l logHelper) lFilepath(c *config.LogConfig) string { +func (l logHelper) lFilepath(c *config.LogConfig, skip int) string { if c == nil { return "" } @@ -175,7 +175,7 @@ func (l logHelper) lFilepath(c *config.LogConfig) string { switch c.LFilepath { case 1: //短文件名 - _, file, line, _ := runtime.Caller(l.lCallerSkip(c)) + _, file, line, _ := runtime.Caller(l.lCallerSkip(c) + skip) if index := strings.LastIndex(file, "/"); index >= 0 { file = file[index+1:] } else if index = strings.LastIndex(file, "\\"); index >= 0 { @@ -184,7 +184,7 @@ func (l logHelper) lFilepath(c *config.LogConfig) string { return fmt.Sprintf("%s:%d", file, line) case 2: //完整文件名 - _, file, line, _ := runtime.Caller(l.lCallerSkip(c)) + _, file, line, _ := runtime.Caller(l.lCallerSkip(c) + skip) return fmt.Sprintf("%s:%d", file, line) default: return "" diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index e1567ee..d640885 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -63,7 +63,7 @@ func (l *writerLog) logItem(level int, format string, params ...interface{}) { return } if len(params) <= 0 { - a := fmt.Sprintf("[%s]%s %s: %s\n", l.lLogLevel(l.cnf), l.lFilepath(l.cnf), time.Now().Format(time.RFC3339), format) + a := fmt.Sprintf("[%s] %s %s: %s\n", l.lLogLevel(l.cnf), l.lFilepath(l.cnf, 3), time.Now().Format(time.RFC3339), format) l.w.Write([]byte(a)) return } diff --git a/src/v1/log/log_writer_test.go b/src/v1/log/log_writer_test.go new file mode 100644 index 0000000..0250553 --- /dev/null +++ b/src/v1/log/log_writer_test.go @@ -0,0 +1,19 @@ +package log + +import ( + "os" + "testing" + "time" +) + +func TestWriterLog(t *testing.T) { + l := NewWriterLog(os.Stdout, 0) + + time.Local, _ = time.LoadLocation("Asia/Seoul") + + l.Debug("hello") + l.Info("hello") + l.Warn("hello") + l.Error("hello") + l.Fatal("hello") +} -- Gitee From e0230059312c88de87245529cac3126c33f4f5a3 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 13:50:57 +0800 Subject: [PATCH 05/39] modify log --- src/v1/log/log.go | 3 ++- src/v1/log/log_default.go | 2 +- src/v1/log/log_writer.go | 7 ++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/v1/log/log.go b/src/v1/log/log.go index 354df4f..c87685a 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -21,13 +21,14 @@ var LevelMap = map[int]string{ TraceLog: "Trace", DebugLog: "Debug", InfoLog: "Info", - WarnLog: "Warning", + WarnLog: "Warn", ErrorLog: "Error", FatalLog: "Fatal", PanicLog: "Panic", } var LevelMapReverse = map[string]int{} +// LogLevelMap 兼容旧配置 var LogLevelMap = LevelMap func init() { diff --git a/src/v1/log/log_default.go b/src/v1/log/log_default.go index 8ef66b8..1275b66 100644 --- a/src/v1/log/log_default.go +++ b/src/v1/log/log_default.go @@ -159,7 +159,7 @@ func (l *MyLogger) Ctl(t bool) ILog { func (l *MyLogger) logItem(level int, s string) { sl := fmt.Sprintf("%s\n%d\n", s, level) - err := l.logger.Output(3, sl) + err := l.logger.Output(3+l.lCallerSkip(l.cnf), sl) if err != nil { panic(err) return diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index d640885..149f782 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -63,7 +63,12 @@ func (l *writerLog) logItem(level int, format string, params ...interface{}) { return } if len(params) <= 0 { - a := fmt.Sprintf("[%s] %s %s: %s\n", l.lLogLevel(l.cnf), l.lFilepath(l.cnf, 3), time.Now().Format(time.RFC3339), format) + a := fmt.Sprintf("[%s] %s %s: %s\n", + LevelMap[level], + time.Now().Format(time.RFC3339), + l.lFilepath(l.cnf, 3), + format, + ) l.w.Write([]byte(a)) return } -- Gitee From e213dc93b7154612c76b7c0bd80c3f9d89f6b9bb Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 14:00:38 +0800 Subject: [PATCH 06/39] skip --- src/v1/log/log_writer.go | 27 +++++++++++++++++++-------- src/v1/log/log_writer_test.go | 10 ++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index 149f782..7940f22 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -9,9 +9,9 @@ import ( // 指定writer的日志打印 type writerLog struct { - w io.Writer - level int - caller int + w io.Writer + level int + callerSkip int cnf *config.LogConfig @@ -24,11 +24,16 @@ func NewWriterLog(w io.Writer, level int, cs ...*config.LogConfig) *writerLog { c = cs[0] } - return &writerLog{ - w: w, - level: level, - cnf: c, + l := &writerLog{ + w: w, + level: level, + cnf: c, + callerSkip: 3, } + + l.callerSkip += l.lCallerSkip(c) + + return l } func (l *writerLog) Debug(format string, params ...interface{}) { @@ -66,7 +71,7 @@ func (l *writerLog) logItem(level int, format string, params ...interface{}) { a := fmt.Sprintf("[%s] %s %s: %s\n", LevelMap[level], time.Now().Format(time.RFC3339), - l.lFilepath(l.cnf, 3), + l.lFilepath(l.cnf, l.callerSkip), format, ) l.w.Write([]byte(a)) @@ -85,3 +90,9 @@ func (l *writerLog) Ctl(t bool) ILog { } return l } + +func (l *writerLog) Caller(skip int) ILog { + nl := &(*l) + nl.callerSkip += skip + return nl +} diff --git a/src/v1/log/log_writer_test.go b/src/v1/log/log_writer_test.go index 0250553..b66a9ba 100644 --- a/src/v1/log/log_writer_test.go +++ b/src/v1/log/log_writer_test.go @@ -16,4 +16,14 @@ func TestWriterLog(t *testing.T) { l.Warn("hello") l.Error("hello") l.Fatal("hello") + + skipLog(l) +} + +func skipLog(l ILog) { + l.Debug("hello") + l.Info("hello") + l.Warn("hello") + l.Error("hello") + l.Fatal("hello") } -- Gitee From b4312edb4af0a0259d7a218a0d432f30590fe5f0 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 14:06:20 +0800 Subject: [PATCH 07/39] modify skip --- src/v1/log/log_writer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index 7940f22..223796f 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -68,7 +68,7 @@ func (l *writerLog) logItem(level int, format string, params ...interface{}) { return } if len(params) <= 0 { - a := fmt.Sprintf("[%s] %s %s: %s\n", + a := fmt.Sprintf("[%s] %s %s %s\n", LevelMap[level], time.Now().Format(time.RFC3339), l.lFilepath(l.cnf, l.callerSkip), -- Gitee From 366b0b310f2b943c7debb564a8ca5ab25a52cf04 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 14:10:00 +0800 Subject: [PATCH 08/39] modify --- src/v1/log/log_writer_test.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/v1/log/log_writer_test.go b/src/v1/log/log_writer_test.go index b66a9ba..fbfa22c 100644 --- a/src/v1/log/log_writer_test.go +++ b/src/v1/log/log_writer_test.go @@ -8,9 +8,14 @@ import ( func TestWriterLog(t *testing.T) { l := NewWriterLog(os.Stdout, 0) - time.Local, _ = time.LoadLocation("Asia/Seoul") + var a = callLog{ + log: l, + } + + a.hello() + l.Debug("hello") l.Info("hello") l.Warn("hello") @@ -18,6 +23,8 @@ func TestWriterLog(t *testing.T) { l.Fatal("hello") skipLog(l) + + skipLog(a.log) } func skipLog(l ILog) { @@ -27,3 +34,15 @@ func skipLog(l ILog) { l.Error("hello") l.Fatal("hello") } + +type callLog struct { + log ILog +} + +func (a callLog) hello() { + a.log.Debug("hello") + a.log.Info("hello") + a.log.Warn("hello") + a.log.Error("hello") + a.log.Fatal("hello") +} -- Gitee From 7d2d355bf1aeee9219edb5a0a5204c4cec55e944 Mon Sep 17 00:00:00 2001 From: wangshaoqi 00995 Date: Tue, 20 Feb 2024 14:15:09 +0800 Subject: [PATCH 09/39] fix bug --- src/v1/log/log_writer.go | 20 ++++++++++---------- src/v1/log/log_writer_test.go | 14 ++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/v1/log/log_writer.go b/src/v1/log/log_writer.go index 223796f..f4a6809 100644 --- a/src/v1/log/log_writer.go +++ b/src/v1/log/log_writer.go @@ -67,17 +67,17 @@ func (l *writerLog) logItem(level int, format string, params ...interface{}) { if l.w == nil { return } - if len(params) <= 0 { - a := fmt.Sprintf("[%s] %s %s %s\n", - LevelMap[level], - time.Now().Format(time.RFC3339), - l.lFilepath(l.cnf, l.callerSkip), - format, - ) - l.w.Write([]byte(a)) - return + if len(params) > 0 { + format = fmt.Sprintf(format, params...) } - l.logItem(level, fmt.Sprintf(format, params...)) + + a := fmt.Sprintf("[%s] %s %s %s\n", + LevelMap[level], + time.Now().Format(time.RFC3339), + l.lFilepath(l.cnf, l.callerSkip), + format, + ) + l.w.Write([]byte(a)) } func (l *writerLog) Write(p []byte) (n int, err error) { diff --git a/src/v1/log/log_writer_test.go b/src/v1/log/log_writer_test.go index fbfa22c..b07d942 100644 --- a/src/v1/log/log_writer_test.go +++ b/src/v1/log/log_writer_test.go @@ -16,20 +16,14 @@ func TestWriterLog(t *testing.T) { a.hello() - l.Debug("hello") - l.Info("hello") - l.Warn("hello") - l.Error("hello") - l.Fatal("hello") - - skipLog(l) - - skipLog(a.log) + testLog(l) + testLog(a.log) } -func skipLog(l ILog) { +func testLog(l ILog) { l.Debug("hello") l.Info("hello") + l.Info("hello %s", time.Now().String()) l.Warn("hello") l.Error("hello") l.Fatal("hello") -- Gitee From 7b1f0f0119334ff78d80963f941040be912ec032 Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 21 Feb 2024 15:36:53 +0800 Subject: [PATCH 10/39] add letter --- src/consts/chars.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/consts/chars.go b/src/consts/chars.go index abf141e..06d976b 100644 --- a/src/consts/chars.go +++ b/src/consts/chars.go @@ -1,7 +1,9 @@ package consts +const Numbers = "1,2,3,4,5,6,7,8,9,0" +const NoZeroNumbers = "1,2,3,4,5,6,7,8,9" -const Numbers="1,2,3,4,5,6,7,8,9,0" -const NoZeroNumbers="1,2,3,4,5,6,7,8,9" +const Letters = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z" -const Letters="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z" \ No newline at end of file +const UpperLetters = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z" +const LowerLetters = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z" -- Gitee From 9169bdb1cf05aacda08a57d16709ad48600a5a2f Mon Sep 17 00:00:00 2001 From: sage Date: Fri, 23 Feb 2024 15:02:42 +0800 Subject: [PATCH 11/39] add log --- src/v1/log/log.go | 2 +- src/v1/log/log_zap.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/v1/log/log.go b/src/v1/log/log.go index c87685a..45e5b83 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -33,7 +33,7 @@ var LogLevelMap = LevelMap func init() { for k, v := range LevelMap { - LevelMapReverse[v] = k + LevelMapReverse[strings.ToUpper(v)] = k } } diff --git a/src/v1/log/log_zap.go b/src/v1/log/log_zap.go index 016c111..c285cfa 100644 --- a/src/v1/log/log_zap.go +++ b/src/v1/log/log_zap.go @@ -7,6 +7,7 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" "os" + "strings" ) // DefaultZapLog default logger @@ -96,7 +97,7 @@ var ZapLogLevelMap = map[int]zapcore.Level{ } func levelToZapLevel(level string) zapcore.Level { - return ZapLogLevelMap[LevelMapReverse[level]] + return ZapLogLevelMap[LevelMapReverse[strings.ToUpper(level)]] } func (l DefaultZapLog) Write(p []byte) (n int, err error) { -- Gitee From 0fa7878b045b13bd42afef0bd66e53eef4537fd8 Mon Sep 17 00:00:00 2001 From: sage Date: Fri, 23 Feb 2024 15:07:08 +0800 Subject: [PATCH 12/39] modify --- src/v1/log/log_zap.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v1/log/log_zap.go b/src/v1/log/log_zap.go index c285cfa..69cafa5 100644 --- a/src/v1/log/log_zap.go +++ b/src/v1/log/log_zap.go @@ -63,7 +63,7 @@ func NewZapLog(name string, logPath string, cs ...*config.LogConfig) *DefaultZap } // 设置日志级别 atomicLevel := zap.NewAtomicLevel() - atomicLevel.SetLevel(levelToZapLevel(c.LogLevel)) + atomicLevel.SetLevel(levelToZapLevel(l.lLogLevel(c))) var writes = []zapcore.WriteSyncer{zapcore.AddSync(&hook)} // 如果是开发环境,同时在控制台上也输出 if c.LogSyncStdOut { -- Gitee From 4a041bd9b5a5bdc7e77510b2ba38da5a526c0a94 Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 3 Apr 2024 17:23:25 +0800 Subject: [PATCH 13/39] add rand nickname add min max --- src/utils/other.go | 29 +++++++++++++++++++++++------ src/utils/rand.go | 5 +++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/utils/other.go b/src/utils/other.go index 4810fa1..dfa19a7 100644 --- a/src/utils/other.go +++ b/src/utils/other.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cast" "gopkg.in/yaml.v3" "io/ioutil" + "math" "strconv" "strings" "time" @@ -51,7 +52,7 @@ func FmtPageParams(pageNum, pageSize int64) (int64, int64) { return pageNum, pageSize } -//CompareVersion 比较版本,-1:小于,0:相等,1:大于 +// CompareVersion 比较版本,-1:小于,0:相等,1:大于 // v1.1.1 compare v1.2.1 func CompareVersion(ver, cVer string) int { if strings.HasPrefix(ver, "v") { @@ -114,12 +115,12 @@ func ReadYamlFile(data interface{}, configPath string) error { return nil } -//Interface2Int64 任意值转int64 +// Interface2Int64 任意值转int64 func Interface2Int64(d interface{}) int64 { return cast.ToInt64(d) } -//Interface2Float64 任意值转float64 +// Interface2Float64 任意值转float64 func Interface2Float64(d interface{}) float64 { return cast.ToFloat64(d) } @@ -139,7 +140,7 @@ func BytesToString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } -//SliceInt64ToMap 切片转map(去重) +// SliceInt64ToMap 切片转map(去重) func SliceInt64ToMap(src []int64) map[int64]bool { m := make(map[int64]bool) for _, v := range src { @@ -151,7 +152,7 @@ func SliceInt64ToMap(src []int64) map[int64]bool { return m } -//LoopDo 重复执行 +// LoopDo 重复执行 func LoopDo(f func(), dur time.Duration) func() { return func() { for { @@ -161,7 +162,7 @@ func LoopDo(f func(), dur time.Duration) func() { } } -//LoopDoI 重复执行(执行包含序号i) +// LoopDoI 重复执行(执行包含序号i) func LoopDoI(f func(int64), dur time.Duration) func() { var i int64 = 0 return func() { @@ -172,3 +173,19 @@ func LoopDoI(f func(int64), dur time.Duration) func() { } } } + +func MaxInt(a int, b int) int { + return int(math.Max(float64(a), float64(b))) +} + +func MinInt(a int, b int) int { + return int(math.Min(float64(a), float64(b))) +} + +func MaxInt64(a int64, b int64) int64 { + return int64(math.Max(float64(a), float64(b))) +} + +func MinInt64(a int64, b int64) int64 { + return int64(math.Min(float64(a), float64(b))) +} diff --git a/src/utils/rand.go b/src/utils/rand.go index bda58ed..0fb919f 100644 --- a/src/utils/rand.go +++ b/src/utils/rand.go @@ -34,3 +34,8 @@ func RandCode(l int, chars []string) string { return code } + +// RandNickname 随机昵称 +func RandNickname() string { + return fmt.Sprintf("user-%s", RandLetterFigureCode(8)) +} -- Gitee From 8fed5d32f18c73be9e3433a235b8087e17a665dd Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 3 Apr 2024 17:30:32 +0800 Subject: [PATCH 14/39] add catch --- src/utils/aes.go | 110 ++++++++++++++++++++++++++++++++++++++++ src/utils/aes_test.go | 55 ++++++++++++++++++++ src/utils/catch.go | 15 ++++++ src/utils/catch_test.go | 9 ++++ src/utils/hash.go | 31 +++++++++++ src/utils/path.go | 15 +++--- 6 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 src/utils/aes.go create mode 100644 src/utils/aes_test.go create mode 100644 src/utils/catch.go create mode 100644 src/utils/catch_test.go create mode 100644 src/utils/hash.go diff --git a/src/utils/aes.go b/src/utils/aes.go new file mode 100644 index 0000000..6396f33 --- /dev/null +++ b/src/utils/aes.go @@ -0,0 +1,110 @@ +package utils + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "encoding/hex" + "errors" + "fmt" +) + +// AesEncrypt AES加密,CBC +// 注意:aes密钥key的长度必须为16,24,32个字符 +func AesEncrypt(origData, key []byte) (string, error) { + block, err := aes.NewCipher(key) + if err != nil { + return "", err + } + + blockSize := block.BlockSize() + origData = PKCS7Padding(origData, blockSize) + blockMode := cipher.NewCBCEncrypter(block, key[:blockSize]) + crypted := make([]byte, len(origData)) + blockMode.CryptBlocks(crypted, origData) + + return EncodeBase64(crypted), nil +} + +// AesDecrypt AES解密 +func AesDecrypt(baseStr string, key []byte) (origData []byte, aesErr error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + defer func() { + if err := recover(); err != nil { + aesErr = errors.New(fmt.Sprintf("AesDecrypt error: %s", err)) + } + }() + + crypted, err := DecodeBase64(baseStr) + if err != nil { + return nil, errors.New("baseStr error") + } + + blockSize := block.BlockSize() + blockMode := cipher.NewCBCDecrypter(block, key[:blockSize]) + origData = make([]byte, len(crypted)) + blockMode.CryptBlocks(origData, crypted) + origData = PKCS7UnPadding(origData) + + return origData, nil +} + +// CBCEncrypt CBC加密 +func CBCEncrypt(text string, key []byte, iv []byte) (string, error) { + //生成cipher.Block 数据块 + block, err := aes.NewCipher(key) + if err != nil { + return "", err + } + //填充内容,如果不足16位字符 + blockSize := block.BlockSize() + + originData := PKCS7Padding([]byte(text), blockSize) + //加密方式 + blockMode := cipher.NewCBCEncrypter(block, iv) + //加密,输出到[]byte数组 + crypted := make([]byte, len(originData)) + blockMode.CryptBlocks(crypted, originData) + + return hex.EncodeToString(crypted), nil +} + +// CBCDecrypt CBC解密 +func CBCDecrypt(sign string, key, iv []byte) (string, error) { + + block, err := aes.NewCipher(key) + if err != nil { + return "", err + } + //if len(iv)%block.BlockSize() != 0 { + // return "", fmt.Errorf("Invalid iv length %d", block.BlockSize()) + //} + ciphertext, err := hex.DecodeString(sign) + if err != nil { + return "", err + } + + origin_data := make([]byte, len(ciphertext)) + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(origin_data, ciphertext) + + return string(PKCS7UnPadding(origin_data)), nil +} + +// PKCS7Padding 填充加密块 +func PKCS7Padding(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +// PKCS7UnPadding 清除加密块中填充字节 +func PKCS7UnPadding(origData []byte) []byte { + length := len(origData) + unpadding := int(origData[length-1]) + return origData[:(length - unpadding)] +} diff --git a/src/utils/aes_test.go b/src/utils/aes_test.go new file mode 100644 index 0000000..c8f4603 --- /dev/null +++ b/src/utils/aes_test.go @@ -0,0 +1,55 @@ +package utils + +import "testing" + +func TestAesEncrypt(t *testing.T) { + data := "{hello}" + key := "asdasdfhj2sa" + key = string(PKCS7Padding([]byte(key), 16)) //aes密钥key必须为16,24,32位 + + s, err := AesEncrypt([]byte(data), []byte(key)) + if err != nil { + t.Fatalf("encrypt fail %s", err) + return + } + t.Logf("encrypted:%s", string(s)) + + ret, err := AesDecrypt(s, []byte(key)) + if err != nil { + t.Fatalf("decrypt fail %s", err) + return + } + if string(ret) != data { + t.Fatalf("decrypt wrong") + return + } + t.Logf("decrypt SUCCESS") + +} + +func TestCBCEncrypt(t *testing.T) { + data := "{hello}" + key := "asdasdfhj2sa" + key = string(PKCS7Padding([]byte(key), 16)) //aes密钥key必须为16,24,32位 + iv := "213213" + iv = string(PKCS7Padding([]byte(iv), 16)) //aes加密必须为16,24,32位 + + s, err := CBCEncrypt(data, []byte(key), []byte(iv)) + if err != nil { + t.Fatalf("encrypt fail %s", err) + return + } + t.Logf("encrypted:%s", string(s)) + + ret, err := CBCDecrypt(s, []byte(key), []byte(iv)) + if err != nil { + t.Fatalf("decrypt fail %s", err) + return + } + if string(ret) != data { + t.Fatalf("decrypt wrong %s", ret) + return + } + t.Logf("decrypt SUCCESS") + +} diff --git a/src/utils/catch.go b/src/utils/catch.go new file mode 100644 index 0000000..f14144a --- /dev/null +++ b/src/utils/catch.go @@ -0,0 +1,15 @@ +package utils + +import ( + "fmt" + "runtime/debug" +) + +func CapturePanic() (has bool) { + if err := recover(); err != nil { + fmt.Printf("runtime panic: %s\n", err) + fmt.Printf("runtime stack: %s\n", debug.Stack()[:1024]) + return true + } + return false +} diff --git a/src/utils/catch_test.go b/src/utils/catch_test.go new file mode 100644 index 0000000..592d4ef --- /dev/null +++ b/src/utils/catch_test.go @@ -0,0 +1,9 @@ +package utils + +import "testing" + +func TestCapturePanic(t *testing.T) { + defer CapturePanic() + + panic("test panic") +} diff --git a/src/utils/hash.go b/src/utils/hash.go new file mode 100644 index 0000000..4fee08b --- /dev/null +++ b/src/utils/hash.go @@ -0,0 +1,31 @@ +package utils + +import ( + "encoding/base64" + "sort" +) + +// Signature 签名 +func Signature(params ...string) string { + var value string + sort.Strings(params) + for _, s := range params { + value += s + } + return Md5Sum(value) +} + +// EncodeBase64 base64编码处理 +func EncodeBase64(b []byte) string { + return base64.StdEncoding.EncodeToString(b) +} + +// DecodeBase64 base64解码处理 +func DecodeBase64(s string) ([]byte, error) { + data, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return nil, err + } + + return data, nil +} diff --git a/src/utils/path.go b/src/utils/path.go index 5ba6192..42a92e6 100644 --- a/src/utils/path.go +++ b/src/utils/path.go @@ -6,17 +6,17 @@ import ( "strings" ) -//运行的程序所在目录 +// BasePath 运行的程序所在目录 func BasePath() string { - executer, err := os.Executable() + exe, err := os.Executable() if err != nil { panic("Cannot get executable folder, just panic: " + err.Error()) } - basePath := filepath.Dir(executer) + basePath := filepath.Dir(exe) return basePath } -// 当前目录(与运行程序所在目录无关) +// CurrentPath 当前目录(与运行程序所在目录无关) func CurrentPath() string { basePath, err := filepath.Abs("./") if err != nil { @@ -25,13 +25,13 @@ func CurrentPath() string { return basePath } -//获取文件后缀 +// FileExt 获取文件后缀 func FileExt(file string) string { arr := strings.Split(file, ".") return arr[len(arr)-1] } -//文件或目录是否存在 +// IsExistPath 文件或目录是否存在 func IsExistPath(path string) bool { _, err := os.Stat(path) if err != nil { @@ -45,3 +45,6 @@ func IsExistPath(path string) bool { } return true } + +// FilePathExist 文件路径是否存在 +var FilePathExist = IsExistPath -- Gitee From 419599edbd7a5734f31fcdee68e0b280ba927d54 Mon Sep 17 00:00:00 2001 From: sage Date: Sun, 7 Apr 2024 16:45:13 +0800 Subject: [PATCH 15/39] add is nil --- src/utils/other.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/utils/other.go b/src/utils/other.go index dfa19a7..da8025e 100644 --- a/src/utils/other.go +++ b/src/utils/other.go @@ -189,3 +189,14 @@ func MaxInt64(a int64, b int64) int64 { func MinInt64(a int64, b int64) int64 { return int64(math.Min(float64(a), float64(b))) } + +// IsNil 判断是否是nil +func IsNil(t interface{}) bool { + if t == nil { + return true + } + if fmt.Sprint(t) == "" { + return true + } + return false +} -- Gitee From febeb386c3f0181804255a0fe7170b64dc3bb236 Mon Sep 17 00:00:00 2001 From: sage Date: Fri, 12 Apr 2024 08:54:55 +0800 Subject: [PATCH 16/39] add catch --- src/miscs/err.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/miscs/err.go b/src/miscs/err.go index 6ecf0b5..dcd35db 100644 --- a/src/miscs/err.go +++ b/src/miscs/err.go @@ -8,7 +8,7 @@ import ( "syscall" ) -//CatchRecover 捕获异常处理 +// CatchRecover 捕获异常处理 func CatchRecover(fs ...func(interface{})) { if err := recover(); err != nil { log.Printf("recover err: %s\n", err) @@ -19,7 +19,13 @@ func CatchRecover(fs ...func(interface{})) { } } -//DefSysSigs 默认监听的系统信号 +func ErrPanic(err error) { + if err != nil { + panic(err) + } +} + +// DefSysSigs 默认监听的系统信号 var DefSysSigs = []os.Signal{ syscall.SIGINT, syscall.SIGTERM, @@ -28,8 +34,8 @@ var DefSysSigs = []os.Signal{ syscall.SIGABRT, } -//CatchSysSig 捕获系统信号 -//捕获后处理 +// CatchSysSig 捕获系统信号 +// 捕获后处理 func CatchSysSig(f func(os.Signal), signs ...os.Signal) { signCh := make(chan os.Signal, 0) signal.Notify(signCh, signs...) -- Gitee From 8a6110e536e43c97c8c0f80d2e25d31f3a2f38d5 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 22 Apr 2024 17:45:19 +0800 Subject: [PATCH 17/39] add metric aggr --- src/v1/libs/clients/metrics/data.go | 78 ++++++++++++++++++++++++ src/v1/libs/clients/metrics/indicator.go | 7 --- 2 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 src/v1/libs/clients/metrics/data.go diff --git a/src/v1/libs/clients/metrics/data.go b/src/v1/libs/clients/metrics/data.go new file mode 100644 index 0000000..82073ba --- /dev/null +++ b/src/v1/libs/clients/metrics/data.go @@ -0,0 +1,78 @@ +package metrics + +import "time" + +// IndicData 单个指标数据 +type IndicData struct { + Name string + Value float64 + Unit string + AggrMethod IndicAggrMethod //聚合方式 + AggrScope time.Duration //聚合时间范围,最小单位为秒 + Labels map[string]string //标签 + Time int64 //指标对应时间,单位:毫秒级时间戳 +} + +func (ind IndicData) Append(cur IndicData) IndicData { + return cur.AggrMethod.Aggr(ind, cur) +} + +func (ind IndicData) EntireLabels() map[string]string { + var m = ind.Labels + if m == nil { + m = map[string]string{} + } + + m["metric"] = ind.Name + m["unit"] = ind.Unit + + return m +} + +type IndicAggrMethod string + +const ( + AggrByCount IndicAggrMethod = "count" //求和 + AggrBySum IndicAggrMethod = "sum" //求和 + AggrByAvg IndicAggrMethod = "avg" //求平均 + AggrByMax IndicAggrMethod = "max" //求最大值 + AggrByMin IndicAggrMethod = "min" //最小值 +) + +func (m IndicAggrMethod) Aggr(old IndicData, cur IndicData) IndicData { + var v = old.Value + if cur.Value == 0 && m == AggrByCount { + cur.Value = 1 + } + + //超过聚合时间范围则取最新的 + if (cur.Time - old.Time) > cur.AggrScope.Milliseconds() { + return cur + } + + switch m { + case AggrByCount: + v += cur.Value + case AggrBySum: + v += cur.Value + case AggrByAvg: + v = (v + cur.Value) / 2 + case AggrByMax: + if cur.Value > v { + v = cur.Value + } + case AggrByMin: + if cur.Value < v { + v = cur.Value + } + } + return IndicData{ + Name: cur.Name, + Value: v, + Unit: cur.Unit, + AggrMethod: cur.AggrMethod, + AggrScope: cur.AggrScope, + Labels: cur.Labels, + Time: old.Time, //聚合后时间取旧数据的时间 + } +} diff --git a/src/v1/libs/clients/metrics/indicator.go b/src/v1/libs/clients/metrics/indicator.go index da65946..bb09c4b 100644 --- a/src/v1/libs/clients/metrics/indicator.go +++ b/src/v1/libs/clients/metrics/indicator.go @@ -4,10 +4,3 @@ package metrics type IIndicator interface { Report(data map[string]*IndicData) //上报数据 } - -//IndicData 单个指标数据 -type IndicData struct { - Name string - Value float64 - Unit string -} \ No newline at end of file -- Gitee From 3f3fe6388a8dd603fe20f4bc1d99681036842d79 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 22 Apr 2024 17:46:01 +0800 Subject: [PATCH 18/39] modify --- src/v1/libs/clients/metrics/indicator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v1/libs/clients/metrics/indicator.go b/src/v1/libs/clients/metrics/indicator.go index bb09c4b..2039609 100644 --- a/src/v1/libs/clients/metrics/indicator.go +++ b/src/v1/libs/clients/metrics/indicator.go @@ -1,6 +1,6 @@ package metrics -//IIndicator 指标器接口 +// IIndicator 指标器接口 type IIndicator interface { Report(data map[string]*IndicData) //上报数据 } -- Gitee From 096b747f584df9b50175d975f3078e9f3781e1e1 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 22 Apr 2024 17:52:46 +0800 Subject: [PATCH 19/39] modify metrics --- src/v1/libs/clients/metrics/indicator.go | 2 +- src/v1/libs/clients/metrics/indicator_aggr.go | 63 +++++++++++++++++++ src/v1/libs/clients/metrics/indicator_log.go | 36 ++++++----- .../clients/metrics/indicator_promethus.go | 6 +- 4 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 src/v1/libs/clients/metrics/indicator_aggr.go diff --git a/src/v1/libs/clients/metrics/indicator.go b/src/v1/libs/clients/metrics/indicator.go index 2039609..7d11125 100644 --- a/src/v1/libs/clients/metrics/indicator.go +++ b/src/v1/libs/clients/metrics/indicator.go @@ -2,5 +2,5 @@ package metrics // IIndicator 指标器接口 type IIndicator interface { - Report(data map[string]*IndicData) //上报数据 + Report(data IndicData) //上报数据 } diff --git a/src/v1/libs/clients/metrics/indicator_aggr.go b/src/v1/libs/clients/metrics/indicator_aggr.go new file mode 100644 index 0000000..cf4ad77 --- /dev/null +++ b/src/v1/libs/clients/metrics/indicator_aggr.go @@ -0,0 +1,63 @@ +package metrics + +import ( + "time" +) + +// TickerAggrIndicator 定时聚合上报indicator +type TickerAggrIndicator struct { + ch chan IndicData + indicators []IIndicator +} + +// NewTickerAggrIndicator 指标上报器-日志 +func NewTickerAggrIndicator(indicators ...IIndicator) *TickerAggrIndicator { + st := &TickerAggrIndicator{ + ch: make(chan IndicData, 16), + indicators: indicators, + } + go st.bgReport() + return st +} + +func (ind *TickerAggrIndicator) bgReport() { + store := map[string]IndicData{} + ti := time.NewTicker(time.Second) + for { + select { + case data := <-ind.ch: + old, exist := store[data.Name] + if !exist { + store[data.Name] = data + continue + } + + store[data.Name] = old.Append(data) + if store[data.Name].Time != old.Time { + ind.report(old) + } + case <-ti.C: + if len(store) == 0 { + continue + } + for _, data := range store { + if (time.Now().UnixMilli() - data.Time) > data.AggrScope.Milliseconds() { + ind.report(data) + } + } + + store = make(map[string]IndicData, len(store)) + } + } +} + +func (ind *TickerAggrIndicator) report(data IndicData) { + for _, v := range ind.indicators { + v.Report(data) + } +} + +// Report 上报数据 +func (ind *TickerAggrIndicator) Report(data IndicData) { + ind.ch <- data +} diff --git a/src/v1/libs/clients/metrics/indicator_log.go b/src/v1/libs/clients/metrics/indicator_log.go index ab285ef..250fb6a 100644 --- a/src/v1/libs/clients/metrics/indicator_log.go +++ b/src/v1/libs/clients/metrics/indicator_log.go @@ -1,35 +1,39 @@ package metrics -import "log" +import ( + v1log "gitee.com/scottq/go-framework/src/v1/log" +) type LogIndicator struct { - label string - ch chan map[string]*IndicData + l v1log.ILog + ch chan IndicData + tag string } -//指标上报器-日志 -func NewLogIndicator(label string) *LogIndicator { +// NewLogIndicator 指标上报器-日志 +func NewLogIndicator(l v1log.ILog, tags ...string) *LogIndicator { st := &LogIndicator{ - label: label, - ch: make(chan map[string]*IndicData, 10), + l: l, + ch: make(chan IndicData, 16), + tag: "LogIndicator", + } + if len(tags) > 0 { + st.tag = tags[0] } go st.bgReport() return st } -func (l *LogIndicator) bgReport() { +func (ind *LogIndicator) bgReport() { for { select { - case data := <-l.ch: - for _, v := range data { - log.Printf("[Statistical-%s]%s: %f %s", l.label, v.Name, v.Value, v.Unit) - } + case data := <-ind.ch: + ind.l.Info("[%s]%s: %f %s %+v", ind.tag, data.Name, data.Value, data.Unit, data.Labels) } } } -//上报数据 -func (l *LogIndicator) Report(data map[string]*IndicData) { - l.ch <- data +// Report 上报数据 +func (ind *LogIndicator) Report(data IndicData) { + ind.ch <- data } - diff --git a/src/v1/libs/clients/metrics/indicator_promethus.go b/src/v1/libs/clients/metrics/indicator_promethus.go index eb1fff9..58f7af6 100644 --- a/src/v1/libs/clients/metrics/indicator_promethus.go +++ b/src/v1/libs/clients/metrics/indicator_promethus.go @@ -1,6 +1,6 @@ package metrics -//todo 指标上报至prometheus +// todo 指标上报至prometheus type PrometheusIndicator struct { label string ch chan map[string]*IndicData @@ -12,7 +12,7 @@ func NewPrometheusIndicator(label string) *PrometheusIndicator { } } -//上报数据 -func (l *PrometheusIndicator) Report(data map[string]*IndicData) { +// 上报数据 +func (l *PrometheusIndicator) Report(data IndicData) { //todo } -- Gitee From 33821140f8fc9a9fee2b2548cfe42c7eff2d5f9f Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 22 Apr 2024 18:00:24 +0800 Subject: [PATCH 20/39] move file --- .../clients/metrics/indicator_promethus.go | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/v1/libs/clients/metrics/indicator_promethus.go diff --git a/src/v1/libs/clients/metrics/indicator_promethus.go b/src/v1/libs/clients/metrics/indicator_promethus.go deleted file mode 100644 index 58f7af6..0000000 --- a/src/v1/libs/clients/metrics/indicator_promethus.go +++ /dev/null @@ -1,18 +0,0 @@ -package metrics - -// todo 指标上报至prometheus -type PrometheusIndicator struct { - label string - ch chan map[string]*IndicData -} - -func NewPrometheusIndicator(label string) *PrometheusIndicator { - return &PrometheusIndicator{ - label: label, - } -} - -// 上报数据 -func (l *PrometheusIndicator) Report(data IndicData) { - //todo -} -- Gitee From 596da3185a74d0737aaf3d222dbfe21950613b13 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 6 May 2024 10:17:18 +0800 Subject: [PATCH 21/39] modify --- go.mod | 1 + src/utils/embedfs.go | 1 + src/utils/embedfs_test.go | 18 ++++++++++++++++++ src/utils/public/_c.txt | 1 + src/utils/public/a.txt | 1 + src/utils/public/b.json | 1 + 6 files changed, 23 insertions(+) create mode 100644 src/utils/embedfs_test.go create mode 100644 src/utils/public/_c.txt create mode 100644 src/utils/public/a.txt create mode 100644 src/utils/public/b.json diff --git a/go.mod b/go.mod index e61beff..03f50cb 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/gin-gonic/gin v1.8.1 + github.com/go-playground/assert/v2 v2.0.1 github.com/go-redis/redis/v7 v7.4.1 github.com/go-sql-driver/mysql v1.7.0 github.com/google/uuid v1.1.2 diff --git a/src/utils/embedfs.go b/src/utils/embedfs.go index efa9891..fc9935a 100644 --- a/src/utils/embedfs.go +++ b/src/utils/embedfs.go @@ -3,6 +3,7 @@ package utils import "embed" //ScanEmbedFsDo 扫描文件操作 +// 注意:下划线文件不会被 embed.FS 嵌入打包进来 func ScanEmbedFsDo(embFs embed.FS, fn func(file string, path string) error) error { return scanFsDo(embFs, ".", fn) } diff --git a/src/utils/embedfs_test.go b/src/utils/embedfs_test.go new file mode 100644 index 0000000..f8f43e8 --- /dev/null +++ b/src/utils/embedfs_test.go @@ -0,0 +1,18 @@ +package utils + +import ( + "embed" + "github.com/go-playground/assert/v2" + "testing" +) + +//go:embed public +var fs embed.FS + +func TestScanEmbedFsDo(t *testing.T) { + err := ScanEmbedFsDo(fs, func(file string, path string) error { + t.Logf("F: %s,%s", file, path) + return nil + }) + assert.Equal(t, err, nil) +} diff --git a/src/utils/public/_c.txt b/src/utils/public/_c.txt new file mode 100644 index 0000000..baebf33 --- /dev/null +++ b/src/utils/public/_c.txt @@ -0,0 +1 @@ +cccc \ No newline at end of file diff --git a/src/utils/public/a.txt b/src/utils/public/a.txt new file mode 100644 index 0000000..7284ab4 --- /dev/null +++ b/src/utils/public/a.txt @@ -0,0 +1 @@ +aaaa \ No newline at end of file diff --git a/src/utils/public/b.json b/src/utils/public/b.json new file mode 100644 index 0000000..bf937c9 --- /dev/null +++ b/src/utils/public/b.json @@ -0,0 +1 @@ +{"b": "bbb"} \ No newline at end of file -- Gitee From 827794c9320084df08b2d06151bb156e340bedf5 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 6 May 2024 15:06:52 +0800 Subject: [PATCH 22/39] add scan dir --- src/utils/embedfs.go | 7 +++++-- src/utils/path.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/utils/embedfs.go b/src/utils/embedfs.go index fc9935a..609af7b 100644 --- a/src/utils/embedfs.go +++ b/src/utils/embedfs.go @@ -2,14 +2,17 @@ package utils import "embed" -//ScanEmbedFsDo 扫描文件操作 +// ScanEmbedFsDo 扫描文件操作 // 注意:下划线文件不会被 embed.FS 嵌入打包进来 func ScanEmbedFsDo(embFs embed.FS, fn func(file string, path string) error) error { return scanFsDo(embFs, ".", fn) } func scanFsDo(embFs embed.FS, dir string, fn func(file string, path string) error) error { - files, _ := embFs.ReadDir(dir) + files, err := embFs.ReadDir(dir) + if err != nil { + return err + } for _, f := range files { //文件路径 path := dir + "/" + f.Name() diff --git a/src/utils/path.go b/src/utils/path.go index 42a92e6..999ff52 100644 --- a/src/utils/path.go +++ b/src/utils/path.go @@ -48,3 +48,34 @@ func IsExistPath(path string) bool { // FilePathExist 文件路径是否存在 var FilePathExist = IsExistPath + +// ScanDirFileDo 扫描目录文件并执行操作 +func ScanDirFileDo(dir string, fn func(file string, path string) error) error { + files, err := os.ReadDir(dir) + if err != nil { + return err + } + for _, f := range files { + path := dir + "/" + f.Name() + //文件路径 + if strings.HasSuffix(dir, "/") { + path = dir + f.Name() + } + if dir == "." { + path = f.Name() + } + + //目录则继续扫描 + if f.IsDir() { + if err := ScanDirFileDo(path, fn); err != nil { + return err + } + continue + } + //文件则func处理 + if err := fn(f.Name(), path); err != nil { + return err + } + } + return nil +} -- Gitee From c0e2c3fe18453411c8cabcbfb466ab0972d2b38d Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 6 May 2024 15:08:21 +0800 Subject: [PATCH 23/39] add path test --- src/utils/path_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/utils/path_test.go diff --git a/src/utils/path_test.go b/src/utils/path_test.go new file mode 100644 index 0000000..b8b4737 --- /dev/null +++ b/src/utils/path_test.go @@ -0,0 +1,15 @@ +package utils + +import ( + "github.com/go-playground/assert/v2" + "testing" +) + +func TestScanDirFileDo(t *testing.T) { + err := ScanDirFileDo("../", func(file string, path string) error { + t.Logf("%s,%s", file, path) + return nil + }) + + assert.Equal(t, err, nil) +} -- Gitee From 33aef28e95924c84107fca53e2c663675df5d65d Mon Sep 17 00:00:00 2001 From: sage Date: Fri, 10 May 2024 10:10:39 +0800 Subject: [PATCH 24/39] add logger --- src/v1/log/log.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/v1/log/log.go b/src/v1/log/log.go index 45e5b83..ba04345 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -160,6 +160,17 @@ func (ink *InvokeLog) Fatal(log string, params ...interface{}) { return } +func (ink *InvokeLog) Write(p []byte) (n int, err error) { + return ink.logger.Write(p) +} + +func (ink *InvokeLog) Ctl(t bool) ILog { + if !t { + return _nullLog + } + return ink +} + type logHelper struct { } -- Gitee From 19a406ddbf5a23d96c908d16b0fd19cbbacfdb84 Mon Sep 17 00:00:00 2001 From: sage Date: Fri, 10 May 2024 10:11:38 +0800 Subject: [PATCH 25/39] modify --- src/v1/log/log.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/v1/log/log.go b/src/v1/log/log.go index ba04345..8f511e2 100644 --- a/src/v1/log/log.go +++ b/src/v1/log/log.go @@ -159,11 +159,9 @@ func (ink *InvokeLog) Fatal(log string, params ...interface{}) { ink.logger.Fatal(fmt.Sprintf(log, params...)) return } - func (ink *InvokeLog) Write(p []byte) (n int, err error) { return ink.logger.Write(p) } - func (ink *InvokeLog) Ctl(t bool) ILog { if !t { return _nullLog -- Gitee From ba982a0495f434b5fb146b07a3242100f21e7399 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 13 May 2024 15:16:27 +0800 Subject: [PATCH 26/39] add conn method --- src/v1/wsserver/ws/client.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/v1/wsserver/ws/client.go b/src/v1/wsserver/ws/client.go index a4480ce..85ac46b 100644 --- a/src/v1/wsserver/ws/client.go +++ b/src/v1/wsserver/ws/client.go @@ -23,7 +23,7 @@ const ( maxMessageSize = 2048 ) -//UnExceptedCloseErr 不处理的关闭错误 +// UnExceptedCloseErr 不处理的关闭错误 var UnExceptedCloseErr = []int{ websocket.CloseGoingAway, websocket.CloseAbnormalClosure, @@ -90,6 +90,10 @@ func (c *Client) ID() string { return c.uuid } +func (c *Client) Conn() *websocket.Conn { + return c.conn +} + // readPump pumps messages from the websocket connection to the hub. // // The application runs readPump in a per-connection goroutine. The application @@ -211,7 +215,7 @@ func (c *Client) writePump() { } } -//Close 主动断开 +// Close 主动断开 func (c *Client) Close() { c.closeOnce.Do(func() { c.closed = true -- Gitee From de5dcfd861693b0ebe19ea7604415848200fb38c Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 13 May 2024 15:25:12 +0800 Subject: [PATCH 27/39] modify --- src/v1/wsserver/ws/client.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/v1/wsserver/ws/client.go b/src/v1/wsserver/ws/client.go index 85ac46b..f044527 100644 --- a/src/v1/wsserver/ws/client.go +++ b/src/v1/wsserver/ws/client.go @@ -9,7 +9,7 @@ import ( "time" ) -const ( +var ( // Time allowed to write a message to the peer. writeWait = 10 * time.Second @@ -18,11 +18,14 @@ const ( // Send pings to peer with this period. Must be less than pongWait. pingPeriod = (pongWait * 9) / 10 - // Maximum message size allowed from peer. - maxMessageSize = 2048 + maxMessageSize int64 = 2048 * 1000 //单位:字节 ) +func SetMessageSize(size int64) { + maxMessageSize = size +} + // UnExceptedCloseErr 不处理的关闭错误 var UnExceptedCloseErr = []int{ websocket.CloseGoingAway, -- Gitee From fefa99be1f246ccdb11d4e8329e38656220d7e43 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 13 May 2024 17:43:03 +0800 Subject: [PATCH 28/39] add close --- src/v1/wsserver/ws/connector.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/v1/wsserver/ws/connector.go b/src/v1/wsserver/ws/connector.go index fcf6edc..dbd3d09 100644 --- a/src/v1/wsserver/ws/connector.go +++ b/src/v1/wsserver/ws/connector.go @@ -3,9 +3,11 @@ package ws import ( "encoding/json" "fmt" + "gitee.com/scottq/go-framework/src/v1/libs/comag" "github.com/gorilla/websocket" "github.com/rfyiamcool/backoff" "net/http" + "sync/atomic" "time" ) @@ -22,7 +24,7 @@ type WsConnector interface { Conn() *websocket.Conn } -//ConnectorEvent 连接器事件 +// ConnectorEvent 连接器事件 type ConnectorEvent string const ( @@ -31,12 +33,16 @@ const ( // wsConnector ws连接器 type wsConnector struct { + comag.StopWorker + wsURL string conn *websocket.Conn reader chan []byte sendCh chan []byte retry int eventHandle func(ConnectorEvent) + + closed atomic.Bool } // NewFeatureWsConnector ws辅助连接器 @@ -52,6 +58,11 @@ func (connector *wsConnector) Conn() *websocket.Conn { return connector.conn } +func (connector *wsConnector) Close() { + connector.closed.Swap(true) + connector.conn.Close() +} + func (connector *wsConnector) Start(reader chan []byte) error { err := connector.reConnect() if err != nil { @@ -85,6 +96,9 @@ func (connector *wsConnector) read() { _, p, err := connector.conn.ReadMessage() if err != nil { logger.Info("ws reconnect be overdue! %s %s", err, connector.wsURL) + if connector.closed.Load() { + return + } //断线重连 err = connector.reConnect() if err != nil { @@ -111,6 +125,9 @@ func (connector *wsConnector) write() { if connector.conn == nil { continue } + if connector.closed.Load() { + return + } if err := connector.conn.WriteMessage(websocket.TextMessage, p); err != nil { logger.Error("write message err: %s %s", err, connector.wsURL) } -- Gitee From 4804f6619f1d46d7e9eeb2b93096b2957b5a8df4 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 13 May 2024 17:48:34 +0800 Subject: [PATCH 29/39] add return error --- src/v1/wsserver/ws/connector.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v1/wsserver/ws/connector.go b/src/v1/wsserver/ws/connector.go index dbd3d09..febc8be 100644 --- a/src/v1/wsserver/ws/connector.go +++ b/src/v1/wsserver/ws/connector.go @@ -58,9 +58,9 @@ func (connector *wsConnector) Conn() *websocket.Conn { return connector.conn } -func (connector *wsConnector) Close() { +func (connector *wsConnector) Close() error { connector.closed.Swap(true) - connector.conn.Close() + return connector.conn.Close() } func (connector *wsConnector) Start(reader chan []byte) error { -- Gitee From f684076180a2a0a1cd2cde9af290d02987513a24 Mon Sep 17 00:00:00 2001 From: sage Date: Thu, 23 May 2024 14:47:00 +0800 Subject: [PATCH 30/39] add pad str --- src/utils/str.go | 26 ++++++++++++++++++++++++++ src/utils/str_test.go | 15 +++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 src/utils/str_test.go diff --git a/src/utils/str.go b/src/utils/str.go index c87218f..aaaad53 100644 --- a/src/utils/str.go +++ b/src/utils/str.go @@ -17,3 +17,29 @@ func FindStrBetweenStr(s string, left, right string) string { } return s[i1+len(left) : i2] } + +// PadLeftString 左填充字符串至指定长度 +func PadLeftString(str string, l int, pad string) string { + if len(str) >= l { + return str[0:l] + } + for { + str = pad + str + if len(str) >= l { + return str[0:l] + } + } +} + +// PadRightString 右填充字符串至指定长度 +func PadRightString(str string, l int, pad string) string { + if len(str) >= l { + return str[0:l] + } + for { + str += pad + if len(str) >= l { + return str[0:l] + } + } +} diff --git a/src/utils/str_test.go b/src/utils/str_test.go new file mode 100644 index 0000000..2872596 --- /dev/null +++ b/src/utils/str_test.go @@ -0,0 +1,15 @@ +package utils + +import ( + "github.com/go-playground/assert/v2" + "testing" +) + +func TestPadLeftString(t *testing.T) { + assert.Equal(t, PadLeftString("", 10, "-"), "----------") + assert.Equal(t, PadLeftString("---", 10, "-"), "----------") + assert.Equal(t, PadLeftString("111", 10, "-"), "-------111") + assert.Equal(t, PadRightString("111", 10, "-"), "111-------") + assert.Equal(t, PadRightString("111--222--333", 10, ".."), "111--222--") + +} -- Gitee From b117c7b6201306287e281853fb0dd8b6d1eea7e5 Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 12 Jun 2024 10:38:09 +0800 Subject: [PATCH 31/39] add advance context --- src/miscs/context.go | 27 ++++++++++++++++++++++++ src/miscs/context_test.go | 43 +++++++++++++++++++++++++++++++++++++++ src/v1/log/log_zap.go | 9 ++++++++ 3 files changed, 79 insertions(+) create mode 100644 src/miscs/context.go create mode 100644 src/miscs/context_test.go diff --git a/src/miscs/context.go b/src/miscs/context.go new file mode 100644 index 0000000..958d085 --- /dev/null +++ b/src/miscs/context.go @@ -0,0 +1,27 @@ +package miscs + +import ( + "context" + "sync" +) + +// AdvancedContext 自定义Context +type AdvancedContext struct { + context.Context + Wait sync.WaitGroup + + cancel context.CancelCauseFunc +} + +func NewCancelAdvancedContext(parent context.Context) *AdvancedContext { + ctx, cancel := context.WithCancelCause(parent) + + return &AdvancedContext{ + Context: ctx, + cancel: cancel, + } +} + +func (c *AdvancedContext) Cancel(err error) { + c.cancel(err) +} diff --git a/src/miscs/context_test.go b/src/miscs/context_test.go new file mode 100644 index 0000000..58e51f4 --- /dev/null +++ b/src/miscs/context_test.go @@ -0,0 +1,43 @@ +package miscs + +import ( + "context" + "fmt" + "github.com/go-playground/assert/v2" + "testing" + "time" +) + +func TestAdvanceContext(t *testing.T) { + + //初始化后使用 + ctx := NewCancelAdvancedContext(context.Background()) + + count := 0 + for i := 1; i <= 10; i++ { + index := i + go func() { + //进行wait增加 + ctx.Wait.Add(1) + defer ctx.Wait.Done() + + for { + select { + case <-ctx.Done(): + count++ + t.Logf("err-%d: %s", index, ctx.Err()) + return + default: + time.Sleep(time.Second) + } + } + }() + } + + time.Sleep(time.Second * 3) + //手动取消 + ctx.Cancel(fmt.Errorf("trigger")) + + ctx.Wait.Wait() + assert.Equal(t, count, 10) +} diff --git a/src/v1/log/log_zap.go b/src/v1/log/log_zap.go index 69cafa5..4800f92 100644 --- a/src/v1/log/log_zap.go +++ b/src/v1/log/log_zap.go @@ -87,6 +87,15 @@ func NewZapLog(name string, logPath string, cs ...*config.LogConfig) *DefaultZap return l } +func NewWithZapLog(zlog *zap.Logger) *DefaultZapLog { + l := &DefaultZapLog{} + + // 构造日志 + l.zapLog = zlog + l.Info("log init success") + return l +} + var ZapLogLevelMap = map[int]zapcore.Level{ DebugLog: zapcore.DebugLevel, InfoLog: zapcore.InfoLevel, -- Gitee From 8cd3891665cfc2a1998f348dcaeea7da57854da2 Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 12 Jun 2024 17:46:28 +0800 Subject: [PATCH 32/39] modify --- src/miscs/context_test.go | 1 - src/miscs/err.go | 14 ++++++++++++++ src/utils/other.go | 12 ++++++++---- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/miscs/context_test.go b/src/miscs/context_test.go index 58e51f4..b48f8b8 100644 --- a/src/miscs/context_test.go +++ b/src/miscs/context_test.go @@ -9,7 +9,6 @@ import ( ) func TestAdvanceContext(t *testing.T) { - //初始化后使用 ctx := NewCancelAdvancedContext(context.Background()) diff --git a/src/miscs/err.go b/src/miscs/err.go index dcd35db..3cafed0 100644 --- a/src/miscs/err.go +++ b/src/miscs/err.go @@ -48,3 +48,17 @@ func CatchSysSig(f func(os.Signal), signs ...os.Signal) { } } } + +func CatchSysSigExit(f func(os.Signal), signs ...os.Signal) { + signCh := make(chan os.Signal, 0) + signal.Notify(signCh, signs...) + for { + select { + case sig := <-signCh: + if f != nil { + f(sig) + } + return + } + } +} diff --git a/src/utils/other.go b/src/utils/other.go index da8025e..3a9ffe3 100644 --- a/src/utils/other.go +++ b/src/utils/other.go @@ -153,21 +153,25 @@ func SliceInt64ToMap(src []int64) map[int64]bool { } // LoopDo 重复执行 -func LoopDo(f func(), dur time.Duration) func() { +func LoopDo(f func() bool, dur time.Duration) func() { return func() { for { - f() + if !f() { + return + } time.Sleep(dur) } } } // LoopDoI 重复执行(执行包含序号i) -func LoopDoI(f func(int64), dur time.Duration) func() { +func LoopDoI(f func(int64) bool, dur time.Duration) func() { var i int64 = 0 return func() { for { - f(i) + if !f(i) { + return + } i++ time.Sleep(dur) } -- Gitee From 1fae94195a2c2fb3c283f55845f8d8ad434ee35b Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 12 Jun 2024 17:48:39 +0800 Subject: [PATCH 33/39] add test --- src/miscs/err_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/miscs/err_test.go b/src/miscs/err_test.go index ea24bc4..f340000 100644 --- a/src/miscs/err_test.go +++ b/src/miscs/err_test.go @@ -15,3 +15,10 @@ func TestCatchSysSig(t *testing.T) { time.Sleep(time.Minute * 10) } + +func TestCatchSysSigExit(t *testing.T) { + CatchSysSigExit(func(sig os.Signal) { + t.Logf("catch signal %d", sig) + time.Sleep(time.Second) + }) +} -- Gitee From ff7c27948d5201e383cb9bbc5c240690963cfca7 Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 17 Jul 2024 15:27:08 +0800 Subject: [PATCH 34/39] add rand --- src/utils/rand.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/utils/rand.go b/src/utils/rand.go index 0fb919f..aa2c8b7 100644 --- a/src/utils/rand.go +++ b/src/utils/rand.go @@ -4,6 +4,7 @@ import ( "fmt" "gitee.com/scottq/go-framework/src/consts" "strings" + "time" ) func RandFigureCode(l int) string { @@ -39,3 +40,18 @@ func RandCode(l int, chars []string) string { func RandNickname() string { return fmt.Sprintf("user-%s", RandLetterFigureCode(8)) } + +// RandOrderNoByDateTime 按日期生成单据编号,类似: TX202404230714209992 +func RandOrderNoByDateTime(prefix string, useDate bool, useTime bool, randLen int) string { + no := prefix + if useDate { + no += time.Now().Format("20060102") + } + if useTime { + no += time.Now().Format("150405") + } + if randLen > 0 { + no += RandFigureCode(randLen) + } + return no +} -- Gitee From 9e4ba0397d40a4fa7681b26b9a51d9b9c0279d0a Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 17 Jul 2024 15:30:37 +0800 Subject: [PATCH 35/39] modify --- src/utils/rand_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/utils/rand_test.go b/src/utils/rand_test.go index 4a22012..0e5510b 100644 --- a/src/utils/rand_test.go +++ b/src/utils/rand_test.go @@ -31,3 +31,11 @@ func TestTrueRand(t *testing.T) { t.Logf("[%d] %d", i, code) } } + +func TestRandOrderNoByDateTime(t *testing.T) { + for i := 1; i <= 10; i++ { + t.Logf("%s", RandOrderNoByDateTime("OA", false, false, 10)) + t.Logf("%s", RandOrderNoByDateTime("OD", true, false, 6)) + t.Logf("%s", RandOrderNoByDateTime("DX", true, true, 3)) + } +} -- Gitee From 1c4de37c0f52f73e91fa6f5643f065b95f05ef98 Mon Sep 17 00:00:00 2001 From: sage Date: Thu, 18 Jul 2024 17:35:08 +0800 Subject: [PATCH 36/39] modify --- src/utils/convert.go | 19 +++++++++++++++++++ src/utils/convert_test.go | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 src/utils/convert.go create mode 100644 src/utils/convert_test.go diff --git a/src/utils/convert.go b/src/utils/convert.go new file mode 100644 index 0000000..751bb2c --- /dev/null +++ b/src/utils/convert.go @@ -0,0 +1,19 @@ +package utils + +import "reflect" + +// InterfaceToArray 转换任意interface{}为数组interface{} +func InterfaceToArray(records interface{}) []interface{} { + // 仅支持切片 + t := reflect.TypeOf(records) + + if t.Kind() != reflect.Slice { + return []interface{}{records} + } + tv := reflect.ValueOf(records) + var list []interface{} + for i := 0; i < tv.Len(); i++ { + list = append(list, tv.Index(i).Interface()) + } + return list +} diff --git a/src/utils/convert_test.go b/src/utils/convert_test.go new file mode 100644 index 0000000..6f02e2c --- /dev/null +++ b/src/utils/convert_test.go @@ -0,0 +1,21 @@ +package utils + +import ( + "github.com/go-playground/assert/v2" + "testing" +) + +func TestInterfaceToArray(t *testing.T) { + list := []int{ + 1, 2, 3, 4, + } + + preloads := InterfaceToArray(list) + + t.Logf("%+v", preloads) + assert.Equal(t, len(list), len(preloads)) + + for k, v := range preloads { + assert.Equal(t, v.(int), list[k]) + } +} -- Gitee From e74bdab3503435405892f0d09d2111166125ab6d Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 22 Jul 2024 10:31:54 +0800 Subject: [PATCH 37/39] modify rand fix mrand bug --- src/utils/rand_test.go | 35 +++++++++++++++++++++++++++++++---- src/utils/rand_true.go | 34 +++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/utils/rand_test.go b/src/utils/rand_test.go index 0e5510b..da7f690 100644 --- a/src/utils/rand_test.go +++ b/src/utils/rand_test.go @@ -1,12 +1,13 @@ package utils import ( + "sync" "testing" ) func TestRandFigureCode(t *testing.T) { for i := 1; i <= 100; i++ { - code := RandFigureCode(4) + code := RandFigureCode(12) t.Logf("[%d] %s", i, code) } } @@ -19,10 +20,36 @@ func TestRandLetterCode(t *testing.T) { } func TestRandLetterFigureCode(t *testing.T) { - for i := 1; i <= 100; i++ { - code := RandLetterFigureCode(4) - t.Logf("[%d] %s", i, code) + for j := 1; j <= 100; j++ { + for i := 1; i <= 10000; i++ { + RandLetterFigureCode(12) + //code := RandLetterFigureCode(12) + //t.Logf("[%d] %s", i, code) + } + } +} + +func TestRandLetterFigureCode_co(t *testing.T) { + var wg sync.WaitGroup + + for j := 1; j <= 100; j++ { + wg.Add(2) + go func() { + defer wg.Done() + for i := 1; i <= 10000; i++ { + RandLetterFigureCode(12) + //t.Logf("[%d] %s", i, code) + } + }() + + go func() { + defer wg.Done() + for i := 1; i <= 10000; i++ { + TrueScopeRandNoSafe(2, 100) + } + }() } + wg.Wait() } func TestTrueRand(t *testing.T) { diff --git a/src/utils/rand_true.go b/src/utils/rand_true.go index be28672..9e25556 100644 --- a/src/utils/rand_true.go +++ b/src/utils/rand_true.go @@ -3,19 +3,43 @@ package utils import ( crand "crypto/rand" "encoding/binary" + "fmt" mrand "math/rand" + "sync" "time" ) -var r *mrand.Rand +var r *mrand.Rand = NewTrueScopeRand() +var rPool *sync.Pool func init() { - var seed int64 - binary.Read(crand.Reader, binary.BigEndian, &seed) - r = mrand.New(mrand.NewSource(seed * time.Now().UnixNano())) + rPool = &sync.Pool{New: func() interface{} { + return NewTrueScopeRand() + }} } -//TrueScopeRand 真随机数,范围随机,min<= V Date: Wed, 24 Jul 2024 09:17:19 +0800 Subject: [PATCH 38/39] modify --- src/v1/config/auth.go | 2 +- src/v1/config/config.go | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/v1/config/config.go diff --git a/src/v1/config/auth.go b/src/v1/config/auth.go index 969f78b..df53f6c 100644 --- a/src/v1/config/auth.go +++ b/src/v1/config/auth.go @@ -1,6 +1,6 @@ package config -//授权登录相关 +// AuthConfig 授权登录相关 type AuthConfig struct { SecretKey string `yaml:"SecretKey"` AuthExpired int64 `yaml:"AuthExpired"` diff --git a/src/v1/config/config.go b/src/v1/config/config.go new file mode 100644 index 0000000..c6fec43 --- /dev/null +++ b/src/v1/config/config.go @@ -0,0 +1,23 @@ +package config + +import ( + "flag" + "io" + "os" +) + +// DefiConfigPath 默认的config path获取 +func DefiConfigPath(s ...string) string { + var filepath = "" + + if len(s) > 0 { + return s[0] + } + + set := flag.NewFlagSet("", flag.ContinueOnError) + set.StringVar(&filepath, "c", "./data/config.yaml", "use config path") + set.SetOutput(io.Discard) + set.Parse(os.Args[1:]) + + return filepath +} -- Gitee From 45b377052ac5f17305df2a6cd3a1ad053a123898 Mon Sep 17 00:00:00 2001 From: sage Date: Mon, 19 Aug 2024 09:52:56 +0800 Subject: [PATCH 39/39] add choose more values --- src/utils/other.go | 24 ++++++++++++++++++++++++ src/utils/other_test.go | 21 ++++++++++++++++++--- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/utils/other.go b/src/utils/other.go index 3a9ffe3..178a9a4 100644 --- a/src/utils/other.go +++ b/src/utils/other.go @@ -204,3 +204,27 @@ func IsNil(t interface{}) bool { } return false } + +// MoreValueChooseInt64 多个值选择int64,若没有more则默认value,有more则选择more的第一个 +func MoreValueChooseInt64(value int64, more ...int64) int64 { + if len(more) > 0 { + return more[0] + } + return value +} + +// MoreValueChooseString 多个值选择string,若没有more则默认value,有more则选择more的第一个 +func MoreValueChooseString(value string, more ...string) string { + if len(more) > 0 { + return more[0] + } + return value +} + +// MoreValueChooseFloat64 多个值选择string,若没有more则默认value,有more则选择more的第一个 +func MoreValueChooseFloat64(value float64, more ...float64) float64 { + if len(more) > 0 { + return more[0] + } + return value +} diff --git a/src/utils/other_test.go b/src/utils/other_test.go index 8f7b142..cd87464 100644 --- a/src/utils/other_test.go +++ b/src/utils/other_test.go @@ -1,6 +1,7 @@ package utils import ( + "github.com/go-playground/assert/v2" "testing" ) @@ -19,6 +20,20 @@ func TestCompareVersion(t *testing.T) { } func TestSliceInt64ToMap(t *testing.T) { - t.Logf("%+v",SliceInt64ToMap([]int64{2,1,2,3,4})) - t.Logf("%+v",SliceInt64ToMap([]int64{1,1,2,3,4,5,6})) -} \ No newline at end of file + t.Logf("%+v", SliceInt64ToMap([]int64{2, 1, 2, 3, 4})) + t.Logf("%+v", SliceInt64ToMap([]int64{1, 1, 2, 3, 4, 5, 6})) +} + +func TestMoreValueChoose(t *testing.T) { + assert.Equal(t, int64(1), MoreValueChooseInt64(1)) + assert.Equal(t, int64(2), MoreValueChooseInt64(1, 2, 3)) + assert.Equal(t, int64(3), MoreValueChooseInt64(1, 3, 2)) + + assert.Equal(t, "1", MoreValueChooseString("1")) + assert.Equal(t, "2", MoreValueChooseString("1", "2", "3")) + assert.Equal(t, "3", MoreValueChooseString("1", "3", "2", "4")) + + assert.Equal(t, float64(1), MoreValueChooseFloat64(1)) + assert.Equal(t, float64(2), MoreValueChooseFloat64(1, 2, 3)) + assert.Equal(t, float64(3), MoreValueChooseFloat64(1, 3, 2)) +} -- Gitee