feat(stats): add daily statistics aggregation job and model

- Create `DailyStat` model for immutable daily metrics including
  request counts, tokens, latency, and top models.
- Implement `DailyStatsJob` to aggregate `log_records` from the previous
  day, running daily at 00:05 UTC.
- Register database migrations and schedule the job in the server.
- Add `last7d` and `last30d` period support to stats handler.
This commit is contained in:
zenfun
2026-01-02 22:20:37 +08:00
parent 7b20c35fba
commit 5b2b176a55
4 changed files with 296 additions and 3 deletions

View File

@@ -0,0 +1,42 @@
package model
import "time"
// TopModelStat represents a single model's statistics in the top models list
type TopModelStat struct {
Model string `json:"model"`
Requests int64 `json:"requests"`
Tokens int64 `json:"tokens"`
}
// DailyStat stores immutable daily aggregated statistics.
// Once generated by the cron job, a row is never modified.
// Design principles:
// - Immutable: once generated, never modified
// - Store raw aggregates, compute derived values (error_rate, avg_latency) at read time
// - One row per day, ~365 rows/year
type DailyStat struct {
Date string `gorm:"primaryKey;size:10" json:"date"` // "2006-01-02" (UTC)
// Request counts
Requests int64 `json:"requests"`
Success int64 `json:"success"`
Failed int64 `json:"failed"`
// Token counts
TokensIn int64 `json:"tokens_in"`
TokensOut int64 `json:"tokens_out"`
// Latency (for avg calculation: avg = LatencySumMs / Requests)
LatencySumMs int64 `json:"latency_sum_ms"`
// Top models (JSON array of TopModelStat)
TopModels string `gorm:"type:text" json:"top_models"`
CreatedAt time.Time `json:"created_at"`
}
// TableName specifies the table name for DailyStat
func (DailyStat) TableName() string {
return "daily_stats"
}