refactor(setting): 优化配置启动日志与错误提示

1. 移除main.go中重复的TTS配置错误警告
2. 统一日志中文全角逗号格式
3. 新增TTS配置项脱敏掩码函数
4. 完善启动日志的必填项检查和状态展示
5. 调整TTS配置错误的提示文案,明确500路由情况
This commit is contained in:
sun
2026-07-01 00:13:15 +08:00
parent 7e1102902d
commit f39c72acbe
2 changed files with 53 additions and 12 deletions
+2 -4
View File
@@ -23,17 +23,15 @@ func main() {
// 所有环境变量读取在 setting 包内集中完成,业务模块只读全局 Config。
setting.InitAllConfigs()
// 兼容旧调用顺序:rate limiter / 静态文件 / stats / controller 的初始化保持独立。
// 兼容旧调用顺序:rate limiter / 静态文件 / stats / controller 的初始化保持独立。
middleware.InitRateLimiter()
setting.CheckStaticFiles()
service.InitStats()
controller.InitController()
// 启动期一次性打印所有 Config 状态,便于运维核对。
// (必填项缺失的明确警告由 LogStartupSummary 自身负责,避免重复打印。)
setting.LogStartupSummary()
if setting.TTSConfigErr != nil {
log.Printf("警告: 服务将继续运行,但 TTS 功能不可用,请检查环境变量配置")
}
controller.SetStartTime(time.Now())
+51 -8
View File
@@ -140,7 +140,7 @@ func InitTTSConfig() error {
if parsedTimeout, err := time.ParseDuration(timeoutStr); err == nil {
timeout = parsedTimeout
} else {
log.Printf("无效的超时设置 '%s',使用默认值: %v", timeoutStr, timeout)
log.Printf("无效的超时设置 '%s',使用默认值: %v", timeoutStr, timeout)
}
}
@@ -154,12 +154,12 @@ func InitTTSConfig() error {
sampleRate := 24000
if srStr := os.Getenv("BYTEDANCE_TTS_SAMPLE_RATE"); srStr != "" {
if sr, err := fmt.Sscanf(srStr, "%d", &sampleRate); err != nil || sr != 1 {
log.Printf("无效的采样率设置 '%s',使用默认值: 24000", srStr)
log.Printf("无效的采样率设置 '%s',使用默认值: 24000", srStr)
sampleRate = 24000
}
validRates := map[int]bool{8000: true, 16000: true, 22050: true, 24000: true, 32000: true, 44100: true, 48000: true}
if !validRates[sampleRate] {
log.Printf("不支持的采样率 %d,使用默认值: 24000", sampleRate)
log.Printf("不支持的采样率 %d,使用默认值: 24000", sampleRate)
sampleRate = 24000
}
}
@@ -179,14 +179,17 @@ func InitTTSConfig() error {
// LogStartupSummary 在启动期打印所有 Config 的最终状态。
// 调用时机:InitAllConfigs 之后,ListenAndServe 之前。
// 必填项逐项输出,失败分支明确告知"v1/audio/speech 路由将 500"。
func LogStartupSummary() {
log.Printf("=== 环境配置汇总 ===")
log.Printf("服务端口: %s", Server.Port)
if len(Auth.APIKeys) == 0 {
log.Printf("OPENAI_TTS_API_KEY: 未设置(所有请求无需鉴权)")
} else {
log.Printf("OPENAI_TTS_API_KEY: 已设置 %d 个有效密钥", len(Auth.APIKeys))
}
if CORS.AllowAll {
log.Printf("ALLOWED_ORIGINS: *(允许所有跨域,不可与凭据共用)")
} else if len(CORS.Origins) == 0 {
@@ -194,12 +197,52 @@ func LogStartupSummary() {
} else {
log.Printf("ALLOWED_ORIGINS: 已配置 %d 个允许的跨域来源白名单", len(CORS.Origins))
}
if TTSConfigErr != nil {
log.Printf("火山 TTS 配置: 初始化失败 - %v (TTS 功能不可用)", TTSConfigErr)
} else {
log.Printf("火山 TTS 配置: 初始化成功 (model=%s, format=%s, sample_rate=%d, timeout=%v)",
TTSConfig.Model, TTSConfig.Format, TTSConfig.SampleRate, TTSConfig.Timeout)
// 火山 TTS 必填项逐项状态:缺则 ❌,有则 ✓(API Key 脱敏,仅显示头尾各 4 字符)
log.Printf("火山 TTS 必填项状态:")
type ttsCheck struct {
name string
value string
ok bool
}
checks := []ttsCheck{
{"BYTEDANCE_TTS_API_KEY", maskAPIKey(TTSConfig.ApiKey), TTSConfig.ApiKey != ""},
{"BYTEDANCE_TTS_RESOURCE_ID", TTSConfig.ResourceId, TTSConfig.ResourceId != ""},
{"BYTEDANCE_TTS_SPEAKER", TTSConfig.Speaker, TTSConfig.Speaker != ""},
}
missingCount := 0
for _, c := range checks {
mark := "✓"
if !c.ok {
mark = "❌"
missingCount++
}
val := c.value
if val == "" {
val = "(未设置)"
}
log.Printf(" %s %s: %s", mark, c.name, val)
}
if TTSConfigErr != nil {
log.Printf("火山 TTS 整体: 初始化失败,%d 个必填项缺失,/v1/audio/speech 路由将全部返回 500", missingCount)
} else {
log.Printf("火山 TTS 可选项: model=%s, format=%s, sample_rate=%d, timeout=%v",
TTSConfig.Model, TTSConfig.Format, TTSConfig.SampleRate, TTSConfig.Timeout)
log.Printf("火山 TTS 整体: 初始化成功")
}
}
// maskAPIKey 对 API Key 脱敏,显示头 4 / 尾 4 字符,中间 * 号代替。
// 短于等于 8 字符整体掩为 ****,空串原样返回。
func maskAPIKey(key string) string {
if key == "" {
return ""
}
if len(key) <= 8 {
return "****"
}
return key[:4] + "****" + key[len(key)-4:]
}
// CheckEnvironmentVariables 返回环境变量状态,供 /health 端点使用。