app.go (768行) 拆分为 6 个文件: - app.go: App struct/辅助方法/NewApp/startup/shutdown/GetVersion - app_products.go: 商品加载/账号查询 - app_seckill.go: 抢购控制/日志/时间 - app_verify.go: 积分查询/兑换记录复验 - app_export.go: 账号导出/整理 - app_activity.go: 活动切换/配置保存 scheduler.go (1141行) 拆分为 4 个文件: - scheduler.go: struct/常量/设置/RunNow主循环/executeRound/辅助函数 - attempt.go: runAttempt/runAttemptFast/激进模式缓存 - warmup.go: 预热管理/warmupAttempts - schedule_timer.go: 定时抢购/时间校准/定时器管理 其他清理: - CollectFontCandidates 从 config 包移到 image 包(职责归属) - 删除 logger 死代码: ParseLogLine/ParseLogMeta/DetectLogLevel/ IsLogLevel/LogMeta/LogDebug/cutBracket 等反解析函数及对应测试 (日志结构化后不再有生产调用方) - 删除 static/ 空目录残留
75 lines
2.3 KiB
Go
75 lines
2.3 KiB
Go
package logger
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestStructuredLogging 验证 LogEvent→sink→MemoryLogStore 结构化链路:
|
|
// LogEntry 的 category/level/account 应直接由调用方填入,而非字符串反解析。
|
|
func TestStructuredLogging(t *testing.T) {
|
|
store := NewMemoryLogStore(100)
|
|
cleanup := InitLogging(store, t.TempDir())
|
|
defer func() {
|
|
cleanup()
|
|
globalSink = nil
|
|
}()
|
|
|
|
LogEvent("抢购", "success", "兑换成功: %s", "商品A")
|
|
LogAccountEvent("抢购", "warn", "testuser", "冷却: %ds", 5)
|
|
|
|
entries := store.Since(0)
|
|
// InitLogging 自身产生 1 条"日志文件已启用",加上上述 2 条,共 3 条
|
|
if len(entries) != 3 {
|
|
t.Fatalf("Since(0) = %d entries, want 3", len(entries))
|
|
}
|
|
if entries[0].Category != "日志" {
|
|
t.Errorf("entry0 Category = %q, want '日志' (InitLogging 启动日志)", entries[0].Category)
|
|
}
|
|
|
|
e1 := entries[1]
|
|
if e1.ID != 2 {
|
|
t.Errorf("entry1 ID = %d, want 2", e1.ID)
|
|
}
|
|
if e1.Category != "抢购" {
|
|
t.Errorf("entry1 Category = %q, want '抢购'", e1.Category)
|
|
}
|
|
if e1.Level != "success" {
|
|
t.Errorf("entry1 Level = %q, want 'success'", e1.Level)
|
|
}
|
|
if e1.Account != "" {
|
|
t.Errorf("entry1 Account = %q, want empty", e1.Account)
|
|
}
|
|
if e1.Time == "" {
|
|
t.Error("entry1 Time is empty")
|
|
}
|
|
if !strings.Contains(e1.Message, "[抢购][success]") {
|
|
t.Errorf("entry1 Message = %q, want contains '[抢购][success]'", e1.Message)
|
|
}
|
|
if !strings.Contains(e1.Message, "兑换成功: 商品A") {
|
|
t.Errorf("entry1 Message = %q, want contains '兑换成功: 商品A'", e1.Message)
|
|
}
|
|
|
|
e2 := entries[2]
|
|
if e2.ID != 3 {
|
|
t.Errorf("entry2 ID = %d, want 3", e2.ID)
|
|
}
|
|
if e2.Account != "testuser" {
|
|
t.Errorf("entry2 Account = %q, want 'testuser'", e2.Account)
|
|
}
|
|
if !strings.Contains(e2.Message, "[账号:testuser]") {
|
|
t.Errorf("entry2 Message = %q, want contains '[账号:testuser]'", e2.Message)
|
|
}
|
|
if !strings.Contains(e2.Message, "冷却: 5s") {
|
|
t.Errorf("entry2 Message = %q, want contains '冷却: 5s'", e2.Message)
|
|
}
|
|
|
|
// 验证 minLevel 过滤:设为 error 后 info 日志不应进入内存
|
|
SetMinLevel("error")
|
|
LogEvent("测试", "info", "这条应被过滤")
|
|
if got := store.Since(e2.ID); len(got) != 0 {
|
|
t.Errorf("after SetMinLevel(error), Since(%d) = %d entries, want 0", e2.ID, len(got))
|
|
}
|
|
SetMinLevel("info") // 恢复,避免影响后续测试
|
|
}
|