* feat(logs): complete modern log metrics and filters * fix(release): use GitHub-hosted runners (#685) * feat(logs): complete modern log metrics and filters * fix(logs): validate index ordering and tooltips
298 lines
9.1 KiB
Go
298 lines
9.1 KiB
Go
package requestlog
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"gpt-load/internal/channel"
|
|
"gpt-load/internal/execution"
|
|
"gpt-load/internal/pricing"
|
|
"gpt-load/internal/protocol"
|
|
"gpt-load/internal/reasoning"
|
|
"gpt-load/internal/telemetry"
|
|
"gpt-load/internal/usage"
|
|
)
|
|
|
|
var (
|
|
ErrAlreadyStarted = errors.New("request log service is already started")
|
|
ErrNotRestartable = errors.New("request log service cannot be restarted")
|
|
)
|
|
|
|
type lifecycleState string
|
|
|
|
const (
|
|
lifecycleNew lifecycleState = "new"
|
|
lifecycleRunning lifecycleState = "running"
|
|
lifecycleStopping lifecycleState = "stopping"
|
|
lifecycleStopped lifecycleState = "stopped"
|
|
)
|
|
|
|
type Attempt struct {
|
|
Sequence int `json:"sequence"`
|
|
GroupID uint `json:"group_id"`
|
|
GroupName string `json:"group_name"`
|
|
ChannelID channel.ID `json:"channel_id"`
|
|
CredentialID uint `json:"credential_id"`
|
|
Operation execution.Operation `json:"operation"`
|
|
RouteMode channel.RouteMode `json:"route_mode"`
|
|
UpstreamModel string `json:"upstream_model"`
|
|
UpstreamRequestID string `json:"upstream_request_id"`
|
|
DispatchState execution.DispatchState `json:"dispatch_state"`
|
|
ResponseStarted bool `json:"response_started"`
|
|
UpstreamProtocol protocol.Protocol `json:"upstream_protocol"`
|
|
Reasoning reasoning.Config `json:"reasoning"`
|
|
StatusCode int `json:"status_code"`
|
|
DurationMs int64 `json:"duration_ms"`
|
|
FailureCategory telemetry.FailureCategory `json:"failure_category"`
|
|
FailureOrigin execution.ErrorOrigin `json:"failure_origin"`
|
|
FailureScope execution.ErrorScope `json:"failure_scope"`
|
|
RetryDirective telemetry.RetryDirective `json:"retry_directive"`
|
|
Effect telemetry.Effect `json:"effect"`
|
|
CooldownUntilMS *int64 `json:"cooldown_until_ms"`
|
|
RuleID string `json:"rule_id"`
|
|
Action telemetry.Action `json:"action"`
|
|
WillRetry bool `json:"will_retry"`
|
|
ErrorCode string `json:"error_code"`
|
|
ErrorSummary string `json:"error_summary"`
|
|
Committed bool `json:"committed"`
|
|
PricingReceipt *pricing.Receipt `json:"pricing_receipt,omitempty"`
|
|
}
|
|
|
|
type RetryState string
|
|
|
|
const (
|
|
RetryStateRetried RetryState = "retried"
|
|
RetryStateNotRetried RetryState = "not_retried"
|
|
)
|
|
|
|
type Cursor struct {
|
|
CompletedAtMS int64
|
|
RequestID string
|
|
}
|
|
|
|
type ListQuery struct {
|
|
FromMS *int64
|
|
ToMS *int64
|
|
GroupID *uint
|
|
ChannelID channel.ID
|
|
ClientModel string
|
|
UpstreamModel string
|
|
ModelConsistency telemetry.ModelConsistency
|
|
AccessKeyID *uint
|
|
Status telemetry.RequestStatus
|
|
RequestID string
|
|
Protocol protocol.Protocol
|
|
Operation execution.Operation
|
|
Stream *bool
|
|
FinalStatusCode *int
|
|
UsageState usage.State
|
|
CostState pricing.CostState
|
|
PricingCompleteness pricing.Completeness
|
|
CachePresent *bool
|
|
CredentialID *uint
|
|
AttemptStatusCode *int
|
|
FailureCategory telemetry.FailureCategory
|
|
AttemptErrorCode string
|
|
RetryState RetryState
|
|
RetryCountMin *int
|
|
RetryCountMax *int
|
|
FirstResponseMinMS *int64
|
|
FirstResponseMaxMS *int64
|
|
DurationMinMS *int64
|
|
DurationMaxMS *int64
|
|
InputTokensMin *int64
|
|
InputTokensMax *int64
|
|
OutputTokensMin *int64
|
|
OutputTokensMax *int64
|
|
CostMinNanoUSD *int64
|
|
CostMaxNanoUSD *int64
|
|
Limit int
|
|
Cursor *Cursor
|
|
}
|
|
|
|
type AccessKeyRef struct {
|
|
ID uint
|
|
Name *string
|
|
Deleted bool
|
|
}
|
|
|
|
type Record struct {
|
|
RequestID string
|
|
CompletedAtMS int64
|
|
AccessKey AccessKeyRef
|
|
Protocol protocol.Protocol
|
|
Operation execution.Operation
|
|
UpstreamProtocol protocol.Protocol
|
|
ClientModel string
|
|
UpstreamModel string
|
|
UpstreamReportedModel string
|
|
ModelConsistency telemetry.ModelConsistency
|
|
Status telemetry.RequestStatus
|
|
StatusCode int
|
|
Stream bool
|
|
FirstResponseMs *int64
|
|
DurationMs int64
|
|
AttemptCount int
|
|
ErrorCode string
|
|
ErrorSummary string
|
|
AffinityHit bool
|
|
AffinityKind string
|
|
Reasoning reasoning.Config
|
|
Attempts []Attempt
|
|
GroupID uint
|
|
ChannelID channel.ID
|
|
CredentialID uint
|
|
RouteMode channel.RouteMode
|
|
UsageState usage.State
|
|
CostState pricing.CostState
|
|
PricingCompleteness pricing.Completeness
|
|
PricingMode pricing.Mode
|
|
ContextThresholdTokens *int64
|
|
UncachedInputTokens int64
|
|
CacheReadTokens int64
|
|
CacheWrite5MTokens int64
|
|
CacheWrite1HTokens int64
|
|
CacheWriteUnknownTokens int64
|
|
OutputTokens int64
|
|
EstimatedCostNanoUSD int64
|
|
}
|
|
|
|
type Page struct {
|
|
Items []Record
|
|
NextCursor *Cursor
|
|
}
|
|
|
|
type UsageGranularity string
|
|
|
|
const (
|
|
UsageGranularityMinute UsageGranularity = "minute"
|
|
UsageGranularityHour UsageGranularity = "hour"
|
|
UsageGranularityDay UsageGranularity = "day"
|
|
UsageFiveMinuteBucketMS int64 = 5 * 60 * 1000
|
|
)
|
|
|
|
type UsageDistributionDimension string
|
|
|
|
const (
|
|
UsageDistributionDimensionGroup UsageDistributionDimension = "group"
|
|
UsageDistributionDimensionModel UsageDistributionDimension = "model"
|
|
UsageDistributionDimensionAccessKey UsageDistributionDimension = "access_key"
|
|
)
|
|
|
|
type UsageDistributionMetric string
|
|
|
|
const (
|
|
UsageDistributionMetricRequests UsageDistributionMetric = "requests"
|
|
UsageDistributionMetricTokens UsageDistributionMetric = "tokens"
|
|
UsageDistributionMetricCost UsageDistributionMetric = "cost"
|
|
)
|
|
|
|
type UsageQuery struct {
|
|
// SelfScoped 控制只读用户视图,与管理员的密钥筛选独立。
|
|
SelfScoped bool
|
|
FromMS int64
|
|
ToMS int64
|
|
// 供管理 API 描述时间桶;QueryUsage 始终从 FromMS/ToMS 推导,不接受覆盖。
|
|
Granularity UsageGranularity
|
|
BucketWidthMS int64
|
|
AccessKeyID *uint
|
|
GroupID *uint
|
|
ChannelID channel.ID
|
|
CredentialID *uint
|
|
UpstreamModel string
|
|
}
|
|
|
|
type UsageAggregate struct {
|
|
RequestCount int64
|
|
SuccessCount int64
|
|
FailureCount int64
|
|
UncachedInputTokens int64
|
|
CacheReadTokens int64
|
|
CacheWrite5MTokens int64
|
|
CacheWrite1HTokens int64
|
|
CacheWriteUnknownTokens int64
|
|
OutputTokens int64
|
|
EstimatedCostNanoUSD int64
|
|
UsageMissingCount int64
|
|
PartialCount int64
|
|
UnpricedRequestCount int64
|
|
PricingPartialCount int64
|
|
}
|
|
|
|
type UsageSeriesPoint struct {
|
|
BucketStartMS int64
|
|
BucketEndMS int64
|
|
UsageAggregate
|
|
}
|
|
|
|
type UsageDistributionItem struct {
|
|
GroupID uint
|
|
AccessKeyID uint
|
|
Model string
|
|
UsageDistributionAggregate
|
|
}
|
|
|
|
type UsageDistributionAggregate struct {
|
|
RequestCount int64
|
|
TotalTokens int64
|
|
EstimatedCostNanoUSD int64
|
|
}
|
|
|
|
type UsageDistribution struct {
|
|
Dimension UsageDistributionDimension
|
|
Metric UsageDistributionMetric
|
|
Items []UsageDistributionItem
|
|
Other *UsageDistributionAggregate
|
|
}
|
|
|
|
type UsageReport struct {
|
|
Summary UsageAggregate
|
|
Series []UsageSeriesPoint
|
|
Distributions UsageDistributions
|
|
}
|
|
|
|
type UsageDistributions struct {
|
|
Group map[UsageDistributionMetric]UsageDistribution
|
|
Model map[UsageDistributionMetric]UsageDistribution
|
|
AccessKey map[UsageDistributionMetric]UsageDistribution
|
|
}
|
|
|
|
func (distributions UsageDistributions) Get(
|
|
dimension UsageDistributionDimension,
|
|
metric UsageDistributionMetric,
|
|
) (UsageDistribution, bool) {
|
|
var values map[UsageDistributionMetric]UsageDistribution
|
|
switch dimension {
|
|
case UsageDistributionDimensionGroup:
|
|
values = distributions.Group
|
|
case UsageDistributionDimensionModel:
|
|
values = distributions.Model
|
|
case UsageDistributionDimensionAccessKey:
|
|
values = distributions.AccessKey
|
|
default:
|
|
return UsageDistribution{}, false
|
|
}
|
|
distribution, ok := values[metric]
|
|
return distribution, ok
|
|
}
|
|
|
|
type Stats struct {
|
|
EnqueuedTotal uint64
|
|
PersistedTotal uint64
|
|
DroppedNotRunningTotal uint64
|
|
DroppedQueueFullTotal uint64
|
|
DroppedStoppingTotal uint64
|
|
DroppedPersistFailedTotal uint64
|
|
DroppedShutdownTotal uint64
|
|
DroppedTotal uint64
|
|
WriteFailureTotal uint64
|
|
AccessQuotaCheckpointWriteFailureTotal uint64
|
|
AccessQuotaCheckpointDegraded bool
|
|
RetentionDeleteFailureTotal uint64
|
|
QueueDepth int
|
|
QueueCapacity int
|
|
LastWriteFailureAt time.Time
|
|
LastAccessQuotaCheckpointWriteFailureAt time.Time
|
|
LastRetentionFailureAt time.Time
|
|
}
|