retrylog.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package model
  2. import (
  3. "time"
  4. "github.com/bytedance/sonic"
  5. "github.com/labring/aiproxy/core/common"
  6. "github.com/labring/aiproxy/core/common/config"
  7. "gorm.io/gorm"
  8. )
  9. type RetryLog struct {
  10. RequestBody string `gorm:"type:text" json:"request_body,omitempty"`
  11. ResponseBody string `gorm:"type:text" json:"response_body,omitempty"`
  12. RequestBodyTruncated bool ` json:"request_body_truncated,omitempty"`
  13. ResponseBodyTruncated bool ` json:"response_body_truncated,omitempty"`
  14. RequestAt time.Time ` json:"request_at"`
  15. RetryAt time.Time ` json:"retry_at,omitempty"`
  16. TTFBMilliseconds ZeroNullInt64 ` json:"ttfb_milliseconds,omitempty"`
  17. CreatedAt time.Time `gorm:"autoCreateTime;index" json:"created_at"`
  18. Model string `gorm:"size:64" json:"model"`
  19. RequestID EmptyNullString `gorm:"type:char(16);index:,where:request_id is not null" json:"request_id"`
  20. ID int `gorm:"primaryKey" json:"id"`
  21. ChannelID int ` json:"channel,omitempty"`
  22. Code int `gorm:"index" json:"code,omitempty"`
  23. Mode int ` json:"mode,omitempty"`
  24. RetryTimes ZeroNullInt64 ` json:"retry_times,omitempty"`
  25. }
  26. func (r *RetryLog) BeforeSave(_ *gorm.DB) (err error) {
  27. if reqMax := config.GetLogDetailRequestBodyMaxSize(); reqMax > 0 &&
  28. int64(len(r.RequestBody)) > reqMax {
  29. r.RequestBody = common.TruncateByRune(r.RequestBody, int(reqMax)) + "..."
  30. r.RequestBodyTruncated = true
  31. } else if reqMax < 0 {
  32. r.RequestBody = ""
  33. r.RequestBodyTruncated = true
  34. }
  35. if respMax := config.GetLogDetailResponseBodyMaxSize(); respMax > 0 &&
  36. int64(len(r.ResponseBody)) > respMax {
  37. r.ResponseBody = common.TruncateByRune(r.ResponseBody, int(respMax)) + "..."
  38. r.ResponseBodyTruncated = true
  39. } else if respMax < 0 {
  40. r.ResponseBody = ""
  41. r.ResponseBodyTruncated = true
  42. }
  43. return err
  44. }
  45. func (r *RetryLog) MarshalJSON() ([]byte, error) {
  46. type Alias RetryLog
  47. a := &struct {
  48. *Alias
  49. CreatedAt int64 `json:"created_at"`
  50. RequestAt int64 `json:"request_at"`
  51. RetryAt int64 `json:"retry_at,omitempty"`
  52. }{
  53. Alias: (*Alias)(r),
  54. CreatedAt: r.CreatedAt.UnixMilli(),
  55. RequestAt: r.RequestAt.UnixMilli(),
  56. }
  57. if !r.RetryAt.IsZero() {
  58. a.RetryAt = r.RetryAt.UnixMilli()
  59. }
  60. return sonic.Marshal(a)
  61. }
  62. func RecordRetryLog(
  63. requestID string,
  64. createAt time.Time,
  65. requestAt time.Time,
  66. retryAt time.Time,
  67. firstByteAt time.Time,
  68. code int,
  69. channelID int,
  70. modelName string,
  71. mode int,
  72. retryTimes int,
  73. requestDetail *RequestDetail,
  74. ) error {
  75. if createAt.IsZero() {
  76. createAt = time.Now()
  77. }
  78. if requestAt.IsZero() {
  79. requestAt = createAt
  80. }
  81. if firstByteAt.IsZero() || firstByteAt.Before(requestAt) {
  82. firstByteAt = requestAt
  83. }
  84. log := &RetryLog{
  85. RequestID: EmptyNullString(requestID),
  86. RequestAt: requestAt,
  87. CreatedAt: createAt,
  88. RetryAt: retryAt,
  89. TTFBMilliseconds: ZeroNullInt64(firstByteAt.Sub(requestAt).Milliseconds()),
  90. Code: code,
  91. Model: modelName,
  92. Mode: mode,
  93. ChannelID: channelID,
  94. RetryTimes: ZeroNullInt64(retryTimes),
  95. RequestBody: requestDetail.RequestBody,
  96. ResponseBody: requestDetail.ResponseBody,
  97. }
  98. return LogDB.Create(log).Error
  99. }