✨ feat(database): 完善请求日志体系并为全表补充时间字段

- request_log 新增 user_agent 列(含旧表 ALTER 迁移)及 ip/status 索引,记录解码后的明文 query(含 key,不脱敏)
- 请求日志批量写入改为多值 INSERT 单次往返,替代事务逐条 Exec
- 新增按本地时区分天聚合查询,状态页展示今日请求量与近 7 天请求趋势(峰值日高亮)
- 新增 TZ 时区支持:.env 配置 TZ 后日志时间戳与状态页全部时间统一生效,二进制内嵌 tzdata 保证容器可用
- 五张表统一补齐 created_at/updated_at 字段,启动时自动补列并按业务时间回填旧行
- device_pool 的 device_header 增加唯一约束;audio_cache 写入改为 UPSERT 修复同 key 重复报错
- 状态页"最近请求"新增 UA 列与限流状态显示;config.yaml 暴露 rate_limit_qps 配置并默认启用请求日志
This commit is contained in:
chenxin committed 2026-10-09 22:08:04 +08:00
1 parent 1a4997e031
commit 126a96d744
12 files changed
+277 -55

No files matched your search

+18
View File
@@ -3,8 +3,10 @@ package config
import (
"fmt"
"log"
"os"
"sync"
"sync/atomic"
"time"
"github.com/spf13/viper"
)
@@ -121,6 +123,22 @@ func NewConfigManager() *ConfigManager {
}
}
// ApplyTimezone 按 TZ 环境变量/.env 设置进程时区。
// 必须在任何时间显示之前调用(time.Local 首次使用后不再重读 TZ)。
// 环境变量已设 TZ 时以环境变量为准(.env 不覆盖已有环境变量)。
func ApplyTimezone() {
loadDotenv("./.env")
tz := os.Getenv("TZ")
if tz == "" {
return
}
if _, err := time.LoadLocation(tz); err != nil {
log.Printf("[config/WARN] 无效时区 TZ=%s,沿用系统时区: %v", tz, err)
return // 不写入 TZ:无效值会让 time.Local 落到 UTC
}
os.Setenv("TZ", tz)
}
// LoadConfig 加载配置文件
func LoadConfig(configPath string) error {
// 初始化管理器