From 0cf05cdf30a0c845f5a1d1529456afdf7ec46c92 Mon Sep 17 00:00:00 2001 From: loveuer Date: Mon, 10 Mar 2025 18:09:27 +0800 Subject: [PATCH] wip: auto init with property --- log.go | 53 ++++++++--------------- property.go | 109 +++++++++++++++++++++++++++++++++++++++-------- property_test.go | 16 +++++++ 3 files changed, 125 insertions(+), 53 deletions(-) create mode 100644 property_test.go diff --git a/log.go b/log.go index 9d1529f..2a37b33 100644 --- a/log.go +++ b/log.go @@ -19,66 +19,49 @@ var uzone_logger_pool = &sync.Pool{ }, } -func (ul *uzone_logger) Debug(msg string, data ...any) { - traceId, ok := ul.ctx.Value(api.TraceKey).(string) - if !ok { - traceId = uuid.Must(uuid.NewV7()).String() +func (ul *uzone_logger) traceId() string { + if ul.ctx == nil { + return uuid.Must(uuid.NewV7()).String() } - log.Debug(traceId+" | "+msg, data...) + if tid, ok := ul.ctx.Value(api.TraceKey).(string); ok && tid != "" { + return tid + } + + return uuid.Must(uuid.NewV7()).String() +} + +func (ul *uzone_logger) Debug(msg string, data ...any) { + log.Debug(ul.traceId()+" | "+msg, data...) uzone_logger_pool.Put(ul) } func (ul *uzone_logger) Info(msg string, data ...any) { - traceId, ok := ul.ctx.Value(api.TraceKey).(string) - if !ok { - traceId = uuid.Must(uuid.NewV7()).String() - } - - log.Info(traceId+" | "+msg, data...) + log.Info(ul.traceId()+" | "+msg, data...) uzone_logger_pool.Put(ul) } func (ul *uzone_logger) Warn(msg string, data ...any) { - traceId, ok := ul.ctx.Value(api.TraceKey).(string) - if !ok { - traceId = uuid.Must(uuid.NewV7()).String() - } - - log.Warn(traceId+" | "+msg, data...) + log.Warn(ul.traceId()+" | "+msg, data...) uzone_logger_pool.Put(ul) } func (ul *uzone_logger) Error(msg string, data ...any) { - traceId, ok := ul.ctx.Value(api.TraceKey).(string) - if !ok { - traceId = uuid.Must(uuid.NewV7()).String() - } - - log.Error(traceId+" | "+msg, data...) + log.Error(ul.traceId()+" | "+msg, data...) uzone_logger_pool.Put(ul) } func (ul *uzone_logger) Panic(msg string, data ...any) { - traceId, ok := ul.ctx.Value(api.TraceKey).(string) - if !ok { - traceId = uuid.Must(uuid.NewV7()).String() - } - - log.Panic(traceId+" | "+msg, data...) + log.Panic(ul.traceId()+" | "+msg, data...) + uzone_logger_pool.Put(ul) } func (ul *uzone_logger) Fatal(msg string, data ...any) { - traceId, ok := ul.ctx.Value(api.TraceKey).(string) - if !ok { - traceId = uuid.Must(uuid.NewV7()).String() - } - - log.Fatal(traceId+" | "+msg, data...) + log.Fatal(ul.traceId()+" | "+msg, data...) uzone_logger_pool.Put(ul) } diff --git a/property.go b/property.go index a342981..8416b4a 100644 --- a/property.go +++ b/property.go @@ -1,26 +1,29 @@ package uzone import ( + "fmt" + "github.com/spf13/cast" "gopkg.in/yaml.v3" "os" + "reflect" "time" "github.com/loveuer/uzone/pkg/tool" ) type _property struct { - Debug bool `yaml:"debug" json:"debug" arg:"env:UZONE.DEBUG"` + Debug bool `yaml:"debug" json:"debug" env:"UZONE.DEBUG"` Listen struct { - Http string `yaml:"http" json:"http" arg:"env:UZONE.LISTEN.HTTP"` + Http string `yaml:"http" json:"http" env:"UZONE.LISTEN.HTTP"` } `yaml:"listen" json:"listen"` DB struct { - URI string `json:"uri" arg:"env:UZONE.DB.URI"` + URI string `json:"uri" env:"UZONE.DB.URI"` } `yaml:"db" json:"db"` Cache struct { - URI string `json:"uri" arg:"env:UZONE.CACHE.URI"` + URI string `json:"uri" env:"UZONE.CACHE.URI"` } `yaml:"cache" json:"cache"` Elasticsearch struct { - URI string `yaml:"uri" json:"uri" arg:"env:UZONE.ELASTICSEARCH.URI"` + URI string `yaml:"uri" json:"uri" env:"UZONE.ELASTICSEARCH.URI"` } `yaml:"elasticsearch" json:"elasticsearch"` } @@ -30,27 +33,97 @@ func init() { time.Local = time.FixedZone("CST", 8*3600) var ( - err error - info os.FileInfo - bs []byte + err error + bs []byte + + configFn = func(path string) error { + if bs, err = os.ReadFile(path); err != nil { + uzone_logger_pool.Get().(*uzone_logger).Debug("[%30s] read %s err, err = %s", "init", path, err.Error()) + return err + } + + if err = yaml.Unmarshal(bs, property); err != nil { + uzone_logger_pool.Get().(*uzone_logger).Debug("[%30s] unmarshal %s err, err = %s", "init", path, err.Error()) + return err + } + + return nil + } ) - if info, err = os.Stat("etc/config.yaml"); err == nil && !info.IsDir() { - if bs, err = os.ReadFile("etc/config.yaml"); err != nil { - uzone_logger_pool.Get().(*uzone_logger).Warn("[%30s] read etc/config.yaml err, err = %s", "init", err.Error()) - goto BindEnv - } - - if err = yaml.Unmarshal(bs, property); err != nil { - uzone_logger_pool.Get().(*uzone_logger).Warn("[%30s] unmarshal etc/config.yaml err, err = %s", "init", err.Error()) - } - + if err = configFn("etc/config.yaml"); err == nil { goto BindEnv } + if err = configFn("etc/config.yml"); err == nil { + goto BindEnv + } + + _ = configFn("etc/config.json") + BindEnv: + _ = bindEnv(property) if property.Debug { tool.TablePrinter(property) } } + +func bindEnv(data any) error { + rv := reflect.ValueOf(data) + + if rv.Type().Kind() != reflect.Pointer { + return fmt.Errorf("can only bind ptr") + } + + rv = rv.Elem() + + return bindStruct(rv) +} + +func bindStruct(rv reflect.Value) error { + if rv.Type().Kind() != reflect.Struct { + return fmt.Errorf("can only bind struct ptr") + } + + for i := 0; i < rv.NumField(); i++ { + f := rv.Field(i) + + if f.Type().Kind() == reflect.Pointer { + f = f.Elem() + } + + if f.Type().Kind() == reflect.Struct { + return bindStruct(f) + } + + if !f.CanSet() { + continue + } + + tag := rv.Type().Field(i).Tag.Get("env") + if tag == "" || tag == "-" { + continue + } + + bv := os.Getenv(tag) + if bv == "" { + continue + } + + switch f.Type().Kind() { + case reflect.String: + f.SetString(bv) + case reflect.Bool: + f.SetBool(cast.ToBool(bv)) + case reflect.Int64, reflect.Int, reflect.Uint64, reflect.Uint, reflect.Int32, reflect.Uint32, reflect.Int16, reflect.Uint16, reflect.Int8, reflect.Uint8: + f.SetInt(cast.ToInt64(bv)) + case reflect.Float64, reflect.Float32: + f.SetFloat(cast.ToFloat64(bv)) + default: + uzone_logger_pool.Get().(*uzone_logger).Warn("[%30s] unsupported env binding, type = %s, value = %s", "init", f.Type().Kind().String(), bv) + } + } + + return nil +} diff --git a/property_test.go b/property_test.go new file mode 100644 index 0000000..0115305 --- /dev/null +++ b/property_test.go @@ -0,0 +1,16 @@ +package uzone + +import ( + "os" + "testing" +) + +func Test_bindEnv(t *testing.T) { + os.Setenv("UZONE.LISTEN.HTTP", "0.0.0.0:99") + os.Setenv("UZONE.DEBUG", "true") + p := &_property{} + bindEnv(p) + + t.Logf("listen.http = %s", p.Listen.Http) + t.Logf("debug = %v", p.Debug) +}