Files
go-web-gin/config/config.go

214 lines
5.5 KiB
Go

package config
import (
"fmt"
"strings"
"git.hujye.com/infrastructure/go-web-gin/env"
"github.com/spf13/viper"
)
var (
globalConfig *Config
viperInstance *viper.Viper
)
// Config represents the application configuration
type Config struct {
Server ServerConfig `mapstructure:"server"`
App AppConfig `mapstructure:"app"`
Log LogConfig `mapstructure:"log"`
MySQL MySQLConfig `mapstructure:"mysql"`
Redis RedisConfig `mapstructure:"redis"`
}
// ServerConfig represents server configuration
type ServerConfig struct {
Port int `mapstructure:"port"`
Host string `mapstructure:"host"`
Mode string `mapstructure:"mode"` // debug, release, test
}
// AppConfig represents application configuration
type AppConfig struct {
Name string `mapstructure:"name"`
Environment string `mapstructure:"environment"`
LogLevel string `mapstructure:"log_level"`
}
// LogConfig represents log configuration
type LogConfig struct {
OutputToFile bool `mapstructure:"output_to_file"`
Filename string `mapstructure:"filename"`
MaxSize int `mapstructure:"max_size"`
MaxBackups int `mapstructure:"max_backups"`
MaxAge int `mapstructure:"max_age"`
Compress bool `mapstructure:"compress"`
}
// MySQLConfig represents mysql configuration
type MySQLConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
DBName string `mapstructure:"db_name"`
Charset string `mapstructure:"charset"`
ParseTime bool `mapstructure:"parse_time"`
MaxIdleConns int `mapstructure:"max_idle_conns"`
MaxOpenConns int `mapstructure:"max_open_conns"`
ConnMaxLifetime int `mapstructure:"conn_max_lifetime"` // seconds
}
// RedisConfig represents redis configuration
type RedisConfig struct {
Addr string `mapstructure:"addr"`
Password string `mapstructure:"password"`
DB int `mapstructure:"db"`
PoolSize int `mapstructure:"pool_size"`
MinIdleConns int `mapstructure:"min_idle_conns"`
MaxRetries int `mapstructure:"max_retries"`
DialTimeout int `mapstructure:"dial_timeout"` // seconds
ReadTimeout int `mapstructure:"read_timeout"` // seconds
WriteTimeout int `mapstructure:"write_timeout"` // seconds
}
// Load loads configuration from environment variable CFG_PATH
// Default path is config/config.yml
func Load() (*Config, error) {
v := viper.New()
v.SetConfigFile(env.GetCfgPath())
v.SetConfigType("yaml")
// Read environment variables
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
// Read config file
if err := v.ReadInConfig(); err != nil {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
var cfg Config
if err := v.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
}
globalConfig = &cfg
viperInstance = v
return &cfg, nil
}
// Get returns the global configuration
// Must call Load first
func Get() *Config {
if globalConfig == nil {
// Return default config if not loaded
return &Config{
Server: ServerConfig{
Port: 8080,
Host: "0.0.0.0",
Mode: "debug",
},
App: AppConfig{
Name: "go-web-gin",
Environment: string(env.Local),
LogLevel: "info",
},
Log: LogConfig{
OutputToFile: true,
Filename: "logs/app.log",
MaxSize: 100,
MaxBackups: 3,
MaxAge: 28,
Compress: true,
},
MySQL: MySQLConfig{
Host: "127.0.0.1",
Port: 3306,
User: "root",
Password: "",
DBName: "test",
Charset: "utf8mb4",
ParseTime: true,
MaxIdleConns: 10,
MaxOpenConns: 100,
ConnMaxLifetime: 3600,
},
Redis: RedisConfig{
Addr: "127.0.0.1:6379",
Password: "",
DB: 0,
PoolSize: 10,
MinIdleConns: 5,
MaxRetries: 3,
DialTimeout: 5,
ReadTimeout: 3,
WriteTimeout: 3,
},
}
}
return globalConfig
}
// GetAddr returns the server address (host:port)
func (c *Config) GetAddr() string {
return fmt.Sprintf("%s:%d", c.Server.Host, c.Server.Port)
}
// IsDebug returns true if server mode is debug
func (c *Config) IsDebug() bool {
return c.Server.Mode == "debug"
}
// IsRelease returns true if server mode is release
func (c *Config) IsRelease() bool {
return c.Server.Mode == "release"
}
// GetString returns a custom string config value by key
// Supports dot notation for nested keys, e.g. "database.host"
func GetString(key string) string {
if viperInstance != nil {
return viperInstance.GetString(key)
}
return ""
}
// GetInt returns a custom int config value by key
func GetInt(key string) int {
if viperInstance != nil {
return viperInstance.GetInt(key)
}
return 0
}
// GetBool returns a custom bool config value by key
func GetBool(key string) bool {
if viperInstance != nil {
return viperInstance.GetBool(key)
}
return false
}
// GetStringSlice returns a custom string slice config value by key
func GetStringSlice(key string) []string {
if viperInstance != nil {
return viperInstance.GetStringSlice(key)
}
return nil
}
// GetValue returns a custom config value of any type by key
func GetValue(key string) any {
if viperInstance != nil {
return viperInstance.Get(key)
}
return nil
}
// Viper returns the underlying viper instance for advanced usage
func Viper() *viper.Viper {
return viperInstance
}