fb0d83251f
- 新建 internal/logger/logger.go,提供 Init/FromCtx/WithRequestID 方法 - Config 新增 LogConfig(level/format),支持 GEN2D_LOG_LEVEL/GEN2D_LOG_FORMAT 环境变量 - config.yml 和 .env.example 添加日志配置示例
183 lines
5.8 KiB
Go
Executable File
183 lines
5.8 KiB
Go
Executable File
package config
|
|
|
|
import (
|
|
"log"
|
|
|
|
"github.com/joho/godotenv"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// Config 应用全局配置。
|
|
type Config struct {
|
|
Server ServerConfig `mapstructure:"server"`
|
|
Database DatabaseConfig `mapstructure:"database"`
|
|
JWT JWTConfig `mapstructure:"jwt"`
|
|
Log LogConfig `mapstructure:"log"`
|
|
LLM LLMConfig `mapstructure:"llm"`
|
|
ImageGen ImageGenConfig `mapstructure:"image_gen"`
|
|
Qiniu QiniuConfig `mapstructure:"qiniu"`
|
|
}
|
|
|
|
// LogConfig 日志配置。
|
|
type LogConfig struct {
|
|
Level string `mapstructure:"level"` // debug / info / warn / error
|
|
Format string `mapstructure:"format"` // text / json
|
|
}
|
|
|
|
// ServerConfig HTTP 服务配置。
|
|
type ServerConfig struct {
|
|
Port int `mapstructure:"port"`
|
|
Mode string `mapstructure:"mode"`
|
|
MaxFileSize int64 `mapstructure:"max_file_size"`
|
|
}
|
|
|
|
// DatabaseConfig 数据库配置。
|
|
type DatabaseConfig struct {
|
|
DSN string `mapstructure:"dsn"`
|
|
}
|
|
|
|
// JWTConfig JWT 签名配置。
|
|
type JWTConfig struct {
|
|
Secret string `mapstructure:"secret"`
|
|
Expire int64 `mapstructure:"expire"`
|
|
}
|
|
|
|
// LLMConfig 大语言模型配置。
|
|
type LLMConfig struct {
|
|
BaseURL string `mapstructure:"base_url"`
|
|
APIKey string `mapstructure:"api_key"`
|
|
Model string `mapstructure:"model"`
|
|
Temperature float64 `mapstructure:"temperature"`
|
|
MaxTokens int `mapstructure:"max_tokens"`
|
|
}
|
|
|
|
// ImageGenConfig OpenAI 兼容文生图模型配置。
|
|
type ImageGenConfig struct {
|
|
BaseURL string `mapstructure:"base_url"`
|
|
APIKey string `mapstructure:"api_key"`
|
|
Model string `mapstructure:"model"`
|
|
Width int `mapstructure:"width"`
|
|
Height int `mapstructure:"height"`
|
|
Quality string `mapstructure:"quality"`
|
|
Timeout int `mapstructure:"timeout"` // HTTP 请求超时秒数,默认 120
|
|
MaxRetries int `mapstructure:"max_retries"` // 5xx 错误重试次数,默认 2
|
|
RetryDelay int `mapstructure:"retry_delay"` // 重试间隔秒数,默认 5
|
|
}
|
|
|
|
// QiniuConfig 七牛云对象存储配置。
|
|
type QiniuConfig struct {
|
|
AccessKey string `mapstructure:"access_key"`
|
|
SecretKey string `mapstructure:"secret_key"`
|
|
Bucket string `mapstructure:"bucket"`
|
|
CDNHost string `mapstructure:"cdn_host"`
|
|
UseHTTPS bool `mapstructure:"use_https"`
|
|
}
|
|
|
|
// Load 从 YAML 配置文件和环境变量加载配置。
|
|
// 优先级:环境变量 > YAML 文件 > 默认值。
|
|
func Load() *Config {
|
|
if err := godotenv.Load(); err != nil {
|
|
log.Println("config: no .env file found, using system env or defaults")
|
|
}
|
|
|
|
v := viper.New()
|
|
v.SetConfigName("config")
|
|
v.SetConfigType("yaml")
|
|
v.AddConfigPath("internal/config")
|
|
|
|
setDefaults(v)
|
|
|
|
if err := v.ReadInConfig(); err != nil {
|
|
log.Printf("config: could not read config file: %v, using env + defaults", err)
|
|
} else {
|
|
log.Printf("config: using config file: %s", v.ConfigFileUsed())
|
|
}
|
|
|
|
bindEnvVars(v)
|
|
|
|
v.AllowEmptyEnv(true)
|
|
|
|
var cfg Config
|
|
if err := v.Unmarshal(&cfg); err != nil {
|
|
log.Fatalf("config: unmarshal failed: %v", err)
|
|
}
|
|
|
|
return &cfg
|
|
}
|
|
|
|
func setDefaults(v *viper.Viper) {
|
|
v.SetDefault("server.port", 8080)
|
|
v.SetDefault("server.mode", "debug")
|
|
v.SetDefault("server.max_file_size", int64(10<<20))
|
|
|
|
v.SetDefault("log.level", "info")
|
|
v.SetDefault("log.format", "text")
|
|
|
|
v.SetDefault("database.dsn", "data/gen2d.db")
|
|
|
|
v.SetDefault("jwt.secret", "gen2d-dev-secret")
|
|
v.SetDefault("jwt.expire", int64(7200))
|
|
|
|
v.SetDefault("llm.base_url", "https://api.openai.com/v1")
|
|
v.SetDefault("llm.api_key", "")
|
|
v.SetDefault("llm.model", "gpt-4o")
|
|
v.SetDefault("llm.temperature", 0.7)
|
|
v.SetDefault("llm.max_tokens", 2048)
|
|
|
|
v.SetDefault("image_gen.base_url", "https://api.suchuang.vip/v1")
|
|
v.SetDefault("image_gen.api_key", "")
|
|
v.SetDefault("image_gen.model", "gpt-image-2-token")
|
|
v.SetDefault("image_gen.width", 1024)
|
|
v.SetDefault("image_gen.height", 1024)
|
|
v.SetDefault("image_gen.quality", "low")
|
|
v.SetDefault("image_gen.timeout", 120)
|
|
v.SetDefault("image_gen.max_retries", 2)
|
|
v.SetDefault("image_gen.retry_delay", 5)
|
|
v.SetDefault("image_gen.num_images", 1)
|
|
v.SetDefault("image_gen.steps", 30)
|
|
v.SetDefault("image_gen.cfg_scale", 7.0)
|
|
|
|
v.SetDefault("qiniu.access_key", "")
|
|
v.SetDefault("qiniu.secret_key", "")
|
|
v.SetDefault("qiniu.bucket", "")
|
|
v.SetDefault("qiniu.cdn_host", "")
|
|
v.SetDefault("qiniu.use_https", true)
|
|
}
|
|
|
|
func bindEnvVars(v *viper.Viper) {
|
|
v.BindEnv("server.port", "GEN2D_PORT")
|
|
v.BindEnv("server.mode", "GEN2D_MODE")
|
|
v.BindEnv("server.max_file_size", "GEN2D_MAX_FILE_SIZE")
|
|
v.BindEnv("database.dsn", "GEN2D_DSN")
|
|
|
|
v.BindEnv("log.level", "GEN2D_LOG_LEVEL")
|
|
v.BindEnv("log.format", "GEN2D_LOG_FORMAT")
|
|
v.BindEnv("jwt.secret", "GEN2D_JWT_SECRET")
|
|
v.BindEnv("jwt.expire", "GEN2D_JWT_EXPIRE")
|
|
|
|
v.BindEnv("llm.base_url", "GEN2D_LLM_BASE_URL")
|
|
v.BindEnv("llm.api_key", "GEN2D_LLM_API_KEY")
|
|
v.BindEnv("llm.model", "GEN2D_LLM_MODEL")
|
|
v.BindEnv("llm.temperature", "GEN2D_LLM_TEMPERATURE")
|
|
v.BindEnv("llm.max_tokens", "GEN2D_LLM_MAX_TOKENS")
|
|
|
|
v.BindEnv("image_gen.base_url", "GEN2D_IMAGE_BASE_URL")
|
|
v.BindEnv("image_gen.api_key", "GEN2D_IMAGE_API_KEY")
|
|
v.BindEnv("image_gen.model", "GEN2D_IMAGE_MODEL")
|
|
v.BindEnv("image_gen.width", "GEN2D_IMAGE_WIDTH")
|
|
v.BindEnv("image_gen.height", "GEN2D_IMAGE_HEIGHT")
|
|
v.BindEnv("image_gen.quality", "GEN2D_IMAGE_QUALITY")
|
|
v.BindEnv("image_gen.timeout", "GEN2D_IMAGE_TIMEOUT")
|
|
v.BindEnv("image_gen.max_retries", "GEN2D_IMAGE_MAX_RETRIES")
|
|
v.BindEnv("image_gen.retry_delay", "GEN2D_IMAGE_RETRY_DELAY")
|
|
v.BindEnv("image_gen.num_images", "GEN2D_IMAGE_NUM_IMAGES")
|
|
v.BindEnv("image_gen.steps", "GEN2D_IMAGE_STEPS")
|
|
v.BindEnv("image_gen.cfg_scale", "GEN2D_IMAGE_CFG_SCALE")
|
|
|
|
v.BindEnv("qiniu.access_key", "GEN2D_QINIU_ACCESS_KEY")
|
|
v.BindEnv("qiniu.secret_key", "GEN2D_QINIU_SECRET_KEY")
|
|
v.BindEnv("qiniu.bucket", "GEN2D_QINIU_BUCKET")
|
|
v.BindEnv("qiniu.cdn_host", "GEN2D_QINIU_CDN_HOST")
|
|
v.BindEnv("qiniu.use_https", "GEN2D_QINIU_USE_HTTPS")
|
|
}
|