package config import ( "net/url" "os" "path/filepath" "runtime" "sync" "time" "github.com/go-playground/validator" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/cast" "github.com/spf13/viper" ) var ENVS = [][2]string{ {"本地测试环境", "http://localhost:8080"}, } type Config struct { IsLocal bool Debug bool `mapstructure:"debug"` HTTPPort int `mapstructure:"http_port" validate:"required"` PrometheusPort int `mapstructure:"prometheus_port" validate:"required"` Databases struct { OSS string `mapstructure:"oss" validate:"required"` PostgreSQL string `mapstructure:"postgresql" validate:"required"` Qdrant string `mapstructure:"qdrant" validate:"required"` } `mapstructure:"databases"` Sentry struct { Environment string DSN string } } type ossConfig struct { Schema string Endpoint string AccessID string AccessSecret string Region string Bucket string Secure bool } func (c *Config) GetOSSConfig() *ossConfig { oss, err := url.Parse(c.Databases.OSS) if err != nil { log.Fatal().Err(err).Msg("parse oss config error") } accessSecret, _ := oss.User.Password() return &ossConfig{ Schema: oss.Scheme, Endpoint: oss.Host, AccessID: oss.User.Username(), AccessSecret: accessSecret, Region: oss.Query().Get("region"), Bucket: oss.Query().Get("bucket"), Secure: cast.ToBool(oss.Query().Get("secure")), } } var ( c *Config once sync.Once ) func Get() *Config { once.Do(setup) return c } func setup() { _, b, _, _ := runtime.Caller(0) projectRoot := filepath.Join(filepath.Dir(b), "../..") viper.SetConfigName("config") viper.AddConfigPath(projectRoot + "/configs") viper.AddConfigPath("/etc/octopus/") viper.AddConfigPath(projectRoot) err := viper.ReadInConfig() if _, ok := err.(viper.ConfigFileNotFoundError); ok { log.Info().Msg("config files not found, ignoring") } else if err != nil { log.Warn().Err(err).Msg("read config failed") } // unmarshal it if err := viper.Unmarshal(&c); err != nil { log.Fatal().Err(err).Msg("unmarshal config failed") } if c.Debug { log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}) } // and validate it v := validator.New() if err := v.Struct(c); err != nil { log.Fatal().Err(err).Msg("validate config failed") } log.Info().Msg("load configs success") }