ops_models.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package service
  2. import (
  3. "strings"
  4. "time"
  5. )
  6. type OpsSystemLog struct {
  7. ID int64 `json:"id"`
  8. CreatedAt time.Time `json:"created_at"`
  9. Host string `json:"host"`
  10. Level string `json:"level"`
  11. Component string `json:"component"`
  12. Message string `json:"message"`
  13. RequestID string `json:"request_id"`
  14. ClientRequestID string `json:"client_request_id"`
  15. UserID *int64 `json:"user_id"`
  16. APIKeyID *int64 `json:"api_key_id"`
  17. AccountID *int64 `json:"account_id"`
  18. Platform string `json:"platform"`
  19. Model string `json:"model"`
  20. Extra map[string]any `json:"extra,omitempty"`
  21. }
  22. type OpsErrorLog struct {
  23. ID int64 `json:"id"`
  24. CreatedAt time.Time `json:"created_at"`
  25. // Standardized classification
  26. // - phase: request|auth|account_auth|routing|upstream|network|internal
  27. // - owner: client|provider|platform
  28. // - source: client_request|upstream_http|gateway
  29. Phase string `json:"phase"`
  30. Type string `json:"type"`
  31. Owner string `json:"error_owner"`
  32. Source string `json:"error_source"`
  33. Severity string `json:"severity"`
  34. StatusCode int `json:"status_code"`
  35. Platform string `json:"platform"`
  36. Model string `json:"model"`
  37. Resolved bool `json:"resolved"`
  38. ResolvedAt *time.Time `json:"resolved_at"`
  39. ResolvedByUserID *int64 `json:"resolved_by_user_id"`
  40. ResolvedByUserName string `json:"resolved_by_user_name"`
  41. ResolvedStatusRaw string `json:"-"`
  42. ClientRequestID string `json:"client_request_id"`
  43. RequestID string `json:"request_id"`
  44. Message string `json:"message"`
  45. UserID *int64 `json:"user_id"`
  46. UserEmail string `json:"user_email"`
  47. APIKeyID *int64 `json:"api_key_id"`
  48. AccountID *int64 `json:"account_id"`
  49. AccountName string `json:"account_name"`
  50. GroupID *int64 `json:"group_id"`
  51. GroupName string `json:"group_name"`
  52. ClientIP *string `json:"client_ip"`
  53. RequestPath string `json:"request_path"`
  54. Stream bool `json:"stream"`
  55. InboundEndpoint string `json:"inbound_endpoint"`
  56. UpstreamEndpoint string `json:"upstream_endpoint"`
  57. RequestedModel string `json:"requested_model"`
  58. UpstreamModel string `json:"upstream_model"`
  59. RequestType *int16 `json:"request_type"`
  60. UserAgent string `json:"user_agent"`
  61. // 关联 api_key 名称(LEFT JOIN api_keys 取得;软删只覆盖 key 列,name 保留,故已删 key 仍有原名)。
  62. APIKeyName string `json:"api_key_name,omitempty"`
  63. APIKeyDeleted bool `json:"api_key_deleted,omitempty"`
  64. }
  65. type OpsErrorLogDetail struct {
  66. OpsErrorLog
  67. ErrorBody string `json:"error_body"`
  68. // Upstream context (optional)
  69. UpstreamStatusCode *int `json:"upstream_status_code,omitempty"`
  70. UpstreamErrorMessage string `json:"upstream_error_message,omitempty"`
  71. UpstreamErrorDetail string `json:"upstream_error_detail,omitempty"`
  72. UpstreamErrors string `json:"upstream_errors,omitempty"` // JSON array (string) for display/parsing
  73. // Timings (optional)
  74. AuthLatencyMs *int64 `json:"auth_latency_ms"`
  75. RoutingLatencyMs *int64 `json:"routing_latency_ms"`
  76. UpstreamLatencyMs *int64 `json:"upstream_latency_ms"`
  77. ResponseLatencyMs *int64 `json:"response_latency_ms"`
  78. TimeToFirstTokenMs *int64 `json:"time_to_first_token_ms"`
  79. // vNext metric semantics
  80. IsBusinessLimited bool `json:"is_business_limited"`
  81. // Bound (non-deleted) key prefix, snapshotted at error time.
  82. APIKeyPrefix string `json:"api_key_prefix,omitempty"`
  83. }
  84. type OpsErrorLogFilter struct {
  85. StartTime *time.Time
  86. EndTime *time.Time
  87. Platform string
  88. GroupID *int64
  89. AccountID *int64
  90. StatusCodes []int
  91. StatusCodesOther bool
  92. Phase string // Recovered provider rows bypass status>=400 only with the explicit opt-in below.
  93. Owner string
  94. Source string
  95. Resolved *bool
  96. Query string
  97. UserQuery string // Search by user email
  98. // Optional correlation keys for exact matching.
  99. RequestID string
  100. ClientRequestID string
  101. // User-scoped filters (used by the user-facing error requests endpoint and
  102. // by admin drill-down from the usage page).
  103. UserID *int64
  104. APIKeyID *int64
  105. // Model matches against requested_model first, then model.
  106. Model string
  107. // ModelFuzzy 为 true 时 Model 走 ILIKE 模糊匹配(仅用户端启用);false(默认)保持精确 =,管理端语义不变。
  108. ModelFuzzy bool
  109. // ExcludeCountTokens drops count_tokens probe errors (is_count_tokens=true).
  110. ExcludeCountTokens bool
  111. // IncludeRecoveredUpstream explicitly exempts provider-health phases
  112. // (upstream and account_auth) from the status>=400 guard. Ops provider
  113. // health lists need status<400 recovered rows; request-error endpoints do
  114. // not set this flag and retain client-error semantics.
  115. IncludeRecoveredUpstream bool
  116. // ErrorPhasesAny / ErrorTypesAny add plain ANY() filters WITHOUT touching the
  117. // special-cased single `Phase` field. With IncludeRecoveredUpstream, an ANY
  118. // list containing only upstream/account_auth also bypasses status>=400.
  119. // NOTE: these ANY filters do NOT bypass status>=400; records with error_phase='upstream'
  120. // but status_code<400 (recovered upstream errors) remain excluded.
  121. // Used to map user-facing coarse categories to backend conditions.
  122. ErrorPhasesAny []string
  123. ErrorTypesAny []string
  124. // View controls error categorization for list endpoints.
  125. // - errors: show actionable errors (exclude business-limited / 429 / 529)
  126. // - excluded: only show excluded errors
  127. // - all: show everything
  128. View string
  129. Page int
  130. PageSize int
  131. // SortBy/SortOrder: server-side sorting aligned with the usage-log list.
  132. // Repo whitelists columns (created_at/model/status_code); anything else
  133. // falls back to created_at. SortOrder is "asc"/"desc" (default desc).
  134. SortBy string
  135. SortOrder string
  136. }
  137. // SetSort normalizes raw sort_by/sort_order query values into the filter.
  138. // Shared by the admin and user-facing error list handlers.
  139. func (f *OpsErrorLogFilter) SetSort(sortBy, sortOrder string) {
  140. f.SortBy = strings.TrimSpace(sortBy)
  141. f.SortOrder = strings.TrimSpace(sortOrder)
  142. }
  143. type OpsErrorLogList struct {
  144. Errors []*OpsErrorLog `json:"errors"`
  145. Total int `json:"total"`
  146. Page int `json:"page"`
  147. PageSize int `json:"page_size"`
  148. }