mirror of
https://git.fightbot.fun/hxuanyu/BingPaper.git
synced 2026-02-15 08:59:33 +08:00
新增配置调试功能:支持输出完整配置项与环境变量覆盖详情,调整 cron.daily_spec 默认值
This commit is contained in:
@@ -19,7 +19,7 @@ api:
|
|||||||
|
|
||||||
cron:
|
cron:
|
||||||
enabled: true
|
enabled: true
|
||||||
daily_spec: "0 10 * * *"
|
daily_spec: "20 8-23/4 * * *"
|
||||||
|
|
||||||
retention:
|
retention:
|
||||||
days: 0
|
days: 0
|
||||||
|
|||||||
@@ -36,6 +36,20 @@ func Init(webFS embed.FS, configPath string) *gin.Engine {
|
|||||||
// 2. 初始化日志
|
// 2. 初始化日志
|
||||||
util.InitLogger(cfg.Log)
|
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("Application configuration loaded")
|
||||||
util.Logger.Info("├─ Config file", zap.String("path", config.GetRawViper().ConfigFileUsed()))
|
util.Logger.Info("├─ Config file", zap.String("path", config.GetRawViper().ConfigFileUsed()))
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -156,7 +157,7 @@ func Init(configPath string) error {
|
|||||||
v.SetDefault("log.db_log_level", "info")
|
v.SetDefault("log.db_log_level", "info")
|
||||||
v.SetDefault("api.mode", "local")
|
v.SetDefault("api.mode", "local")
|
||||||
v.SetDefault("cron.enabled", true)
|
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("retention.days", 0)
|
||||||
v.SetDefault("db.type", "sqlite")
|
v.SetDefault("db.type", "sqlite")
|
||||||
v.SetDefault("db.dsn", "data/bing_paper.db")
|
v.SetDefault("db.dsn", "data/bing_paper.db")
|
||||||
@@ -254,6 +255,38 @@ func GetRawViper() *viper.Viper {
|
|||||||
return v
|
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 {
|
func GetTokenTTL() time.Duration {
|
||||||
ttl, err := time.ParseDuration(GetConfig().Token.DefaultTTL)
|
ttl, err := time.ParseDuration(GetConfig().Token.DefaultTTL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,3 +22,46 @@ func TestDefaultConfig(t *testing.T) {
|
|||||||
t.Errorf("Expected DB type sqlite, got %s", cfg.DB.Type)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user