zai2api2 / internal /telemetry.go
bg5's picture
部署 zai2api 到 HF Space
9aab84d verified
Raw History Blame Contribute Delete
4.72 kB
package internal
import (
"sync"
"sync/atomic"
"time"
)
// ModelStats 模型统计
type ModelStats struct {
Requests int64 `json:"requests"`
InputTok int64 `json:"input_tokens"`
OutputTok int64 `json:"output_tokens"`
}
// Telemetry 遥测数据
type Telemetry struct {
StartTime time.Time
TotalRequests int64
TotalInputTok int64
TotalOutputTok int64
minuteRequests int64
minuteInputTok int64
minuteOutputTok int64
requestTimes []time.Time
modelStats map[string]*ModelStats
mu sync.Mutex
}
var telemetry = &Telemetry{
StartTime: time.Now(),
requestTimes: make([]time.Time, 0),
modelStats: make(map[string]*ModelStats),
}
func RecordRequest(inputTokens, outputTokens int64, model string) {
atomic.AddInt64(&telemetry.TotalRequests, 1)
atomic.AddInt64(&telemetry.TotalInputTok, inputTokens)
atomic.AddInt64(&telemetry.TotalOutputTok, outputTokens)
atomic.AddInt64(&telemetry.minuteRequests, 1)
atomic.AddInt64(&telemetry.minuteInputTok, inputTokens)
atomic.AddInt64(&telemetry.minuteOutputTok, outputTokens)
telemetry.mu.Lock()
telemetry.requestTimes = append(telemetry.requestTimes, time.Now())
// 模型维度统计
if model != "" {
if _, ok := telemetry.modelStats[model]; !ok {
telemetry.modelStats[model] = &ModelStats{}
}
telemetry.modelStats[model].Requests++
telemetry.modelStats[model].InputTok += inputTokens
telemetry.modelStats[model].OutputTok += outputTokens
}
telemetry.mu.Unlock()
}
func GetRPM() int {
telemetry.mu.Lock()
defer telemetry.mu.Unlock()
now := time.Now()
cutoff := now.Add(-time.Minute)
validTimes := make([]time.Time, 0)
for _, t := range telemetry.requestTimes {
if t.After(cutoff) {
validTimes = append(validTimes, t)
}
}
telemetry.requestTimes = validTimes
return len(validTimes)
}
type TelemetryData struct {
Uptime string `json:"uptime"`
TotalRequests int64 `json:"total_requests"`
RPM int `json:"rpm"`
TotalInputTok int64 `json:"total_input_tokens"`
TotalOutputTok int64 `json:"total_output_tokens"`
AvgInputTok int64 `json:"avg_input_tokens"`
AvgOutputTok int64 `json:"avg_output_tokens"`
ValidTokens int `json:"valid_tokens"`
MultimodalCalls int64 `json:"multimodal_calls"`
TotalCalls int64 `json:"total_calls"`
SuccessCalls int64 `json:"success_calls"`
SuccessRate float64 `json:"success_rate"`
ModelStats map[string]*ModelStats `json:"model_stats,omitempty"`
}
func GetTelemetryData() TelemetryData {
totalReqs := atomic.LoadInt64(&telemetry.TotalRequests)
totalIn := atomic.LoadInt64(&telemetry.TotalInputTok)
totalOut := atomic.LoadInt64(&telemetry.TotalOutputTok)
var avgIn, avgOut int64
if totalReqs > 0 {
avgIn = totalIn / totalReqs
avgOut = totalOut / totalReqs
}
uptime := time.Since(telemetry.StartTime)
uptimeStr := formatDuration(uptime)
// 获取 token 管理器统计
tmStats := GetTokenManager().GetStats()
// 复制模型统计
telemetry.mu.Lock()
modelStatsCopy := make(map[string]*ModelStats)
for k, v := range telemetry.modelStats {
modelStatsCopy[k] = &ModelStats{
Requests: v.Requests,
InputTok: v.InputTok,
OutputTok: v.OutputTok,
}
}
telemetry.mu.Unlock()
return TelemetryData{
Uptime: uptimeStr,
TotalRequests: totalReqs,
RPM: GetRPM(),
TotalInputTok: totalIn,
TotalOutputTok: totalOut,
AvgInputTok: avgIn,
AvgOutputTok: avgOut,
ValidTokens: tmStats.ValidTokenCount,
MultimodalCalls: tmStats.MultimodalCount,
TotalCalls: tmStats.TotalCalls,
SuccessCalls: tmStats.SuccessCalls,
SuccessRate: tmStats.SuccessRate,
ModelStats: modelStatsCopy,
}
}
func formatDuration(d time.Duration) string {
days := int(d.Hours()) / 24
hours := int(d.Hours()) % 24
minutes := int(d.Minutes()) % 60
seconds := int(d.Seconds()) % 60
if days > 0 {
return formatTime(days, "d") + formatTime(hours, "h") + formatTime(minutes, "m")
}
if hours > 0 {
return formatTime(hours, "h") + formatTime(minutes, "m") + formatTime(seconds, "s")
}
if minutes > 0 {
return formatTime(minutes, "m") + formatTime(seconds, "s")
}
return formatTime(seconds, "s")
}
func formatTime(value int, unit string) string {
if value == 0 {
return ""
}
return string(rune('0'+value/10)) + string(rune('0'+value%10)) + unit
}