diff --git a/config.example.yaml b/config.example.yaml index a1cef63..71ec177 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -19,7 +19,7 @@ api: cron: enabled: true - daily_spec: "0 10 * * *" + daily_spec: "20 8-23/4 * * *" retention: days: 0 diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 78449eb..5729ae7 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -36,6 +36,20 @@ func Init(webFS embed.FS, configPath string) *gin.Engine { // 2. 初始化日志 util.InitLogger(cfg.Log) + // 以 debug 级别输出配置加载详情和环境变量覆盖情况 + util.Logger.Debug("Configuration loading details", + zap.String("config_file", config.GetRawViper().ConfigFileUsed()), + ) + envOverrides := config.GetEnvOverrides() + if len(envOverrides) > 0 { + for _, override := range envOverrides { + util.Logger.Debug("Environment variable override applied", zap.String("detail", override)) + } + } else { + util.Logger.Debug("No environment variable overrides detected") + } + util.Logger.Debug("Full effective configuration:\n" + config.GetFormattedSettings()) + // 输出配置信息 util.Logger.Info("Application configuration loaded") util.Logger.Info("├─ Config file", zap.String("path", config.GetRawViper().ConfigFileUsed())) diff --git a/internal/config/config.go b/internal/config/config.go index 408dc23..fa75254 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,6 +3,7 @@ package config import ( "fmt" "os" + "sort" "strings" "sync" "time" @@ -156,7 +157,7 @@ func Init(configPath string) error { v.SetDefault("log.db_log_level", "info") v.SetDefault("api.mode", "local") v.SetDefault("cron.enabled", true) - v.SetDefault("cron.daily_spec", "0 10 * * *") + v.SetDefault("cron.daily_spec", "20 8-23/4 * * *") v.SetDefault("retention.days", 0) v.SetDefault("db.type", "sqlite") v.SetDefault("db.dsn", "data/bing_paper.db") @@ -254,6 +255,38 @@ func GetRawViper() *viper.Viper { return v } +// GetAllSettings 返回所有生效配置项 +func GetAllSettings() map[string]interface{} { + return v.AllSettings() +} + +// GetFormattedSettings 以 key: value 形式返回所有配置项的字符串 +func GetFormattedSettings() string { + keys := v.AllKeys() + sort.Strings(keys) + var sb strings.Builder + for _, k := range keys { + sb.WriteString(fmt.Sprintf("%s: %v\n", k, v.Get(k))) + } + return sb.String() +} + +// GetEnvOverrides 返回环境变量覆盖详情(已排序) +func GetEnvOverrides() []string { + var overrides []string + keys := v.AllKeys() + sort.Strings(keys) + for _, key := range keys { + // 根据 viper 的配置生成对应的环境变量名 + // Prefix: BINGPAPER, KeyReplacer: . -> _ + envKey := strings.ToUpper(fmt.Sprintf("BINGPAPER_%s", strings.ReplaceAll(key, ".", "_"))) + if val, ok := os.LookupEnv(envKey); ok { + overrides = append(overrides, fmt.Sprintf("%s: %s=%s", key, envKey, val)) + } + } + return overrides +} + func GetTokenTTL() time.Duration { ttl, err := time.ParseDuration(GetConfig().Token.DefaultTTL) if err != nil { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 943057a..065fafa 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -1,6 +1,9 @@ package config import ( + "fmt" + "os" + "strings" "testing" ) @@ -19,3 +22,46 @@ func TestDefaultConfig(t *testing.T) { t.Errorf("Expected DB type sqlite, got %s", cfg.DB.Type) } } + +func TestDebugFunctions(t *testing.T) { + // 设置一个环境变量 + os.Setenv("BINGPAPER_SERVER_PORT", "9999") + defer os.Unsetenv("BINGPAPER_SERVER_PORT") + + err := Init("") + if err != nil { + t.Fatalf("Failed to init config: %v", err) + } + + settings := GetAllSettings() + serverCfg, ok := settings["server"].(map[string]interface{}) + if !ok { + t.Fatalf("Expected server config map, got %v", settings["server"]) + } + + // Viper numbers in AllSettings are often int + portValue := serverCfg["port"] + // 允许不同的数字类型,因为 viper 内部实现可能变化 + portStr := fmt.Sprintf("%v", portValue) + if portStr != "9999" { + t.Errorf("Expected port 9999 in settings, got %v (%T)", portValue, portValue) + } + + overrides := GetEnvOverrides() + found := false + for _, o := range overrides { + if strings.Contains(o, "server.port") && strings.Contains(o, "9999") { + found = true + break + } + } + if !found { + t.Errorf("Expected server.port override in %v", overrides) + } + + // 验证格式化输出 + formatted := GetFormattedSettings() + if !strings.Contains(formatted, "server.port: 9999") { + t.Errorf("Expected formatted settings to contain server.port: 9999, got %s", formatted) + } +}