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

162 lines
3.7 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"`
}
// 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"`
}
// 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,
},
}
}
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
}