log.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package controller
  2. import (
  3. "net/http"
  4. "strconv"
  5. "time"
  6. "github.com/gin-gonic/gin"
  7. "github.com/labring/aiproxy/core/controller/utils"
  8. "github.com/labring/aiproxy/core/middleware"
  9. "github.com/labring/aiproxy/core/model"
  10. )
  11. func parseTimeRange(c *gin.Context) (startTime, endTime time.Time) {
  12. startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
  13. endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
  14. if startTimestamp != 0 {
  15. startTime = time.UnixMilli(startTimestamp)
  16. }
  17. sevenDaysAgo := time.Now().AddDate(0, 0, -7)
  18. if startTime.IsZero() || startTime.Before(sevenDaysAgo) {
  19. startTime = sevenDaysAgo
  20. }
  21. if endTimestamp != 0 {
  22. endTime = time.UnixMilli(endTimestamp)
  23. }
  24. return
  25. }
  26. func parseCommonParams(c *gin.Context) (params struct {
  27. tokenName string
  28. modelName string
  29. channelID int
  30. tokenID int
  31. order string
  32. requestID string
  33. codeType string
  34. code int
  35. withBody bool
  36. ip string
  37. user string
  38. },
  39. ) {
  40. params.tokenName = c.Query("token_name")
  41. params.modelName = c.Query("model_name")
  42. params.channelID, _ = strconv.Atoi(c.Query("channel"))
  43. params.tokenID, _ = strconv.Atoi(c.Query("token_id"))
  44. params.order = c.Query("order")
  45. params.requestID = c.Query("request_id")
  46. params.codeType = c.Query("code_type")
  47. params.code, _ = strconv.Atoi(c.Query("code"))
  48. params.withBody, _ = strconv.ParseBool(c.Query("with_body"))
  49. params.ip = c.Query("ip")
  50. params.user = c.Query("user")
  51. return
  52. }
  53. // GetLogs godoc
  54. //
  55. // @Summary Get all logs
  56. // @Description Returns a paginated list of all logs with optional filters
  57. // @Tags logs
  58. // @Produce json
  59. // @Security ApiKeyAuth
  60. // @Param page query int false "Page number"
  61. // @Param per_page query int false "Items per page"
  62. // @Param start_timestamp query int false "Start timestamp (milliseconds)"
  63. // @Param end_timestamp query int false "End timestamp (milliseconds)"
  64. // @Param model_name query string false "Model name"
  65. // @Param channel query int false "Channel ID"
  66. // @Param order query string false "Order"
  67. // @Param request_id query string false "Request ID"
  68. // @Param code_type query string false "Status code type"
  69. // @Param code query int false "Status code"
  70. // @Param with_body query bool false "With body"
  71. // @Param ip query string false "IP"
  72. // @Param user query string false "User"
  73. // @Success 200 {object} middleware.APIResponse{data=model.GetLogsResult}
  74. // @Router /api/logs/ [get]
  75. func GetLogs(c *gin.Context) {
  76. page, perPage := utils.ParsePageParams(c)
  77. startTime, endTime := parseTimeRange(c)
  78. params := parseCommonParams(c)
  79. result, err := model.GetLogs(
  80. startTime,
  81. endTime,
  82. params.modelName,
  83. params.requestID,
  84. params.channelID,
  85. params.order,
  86. model.CodeType(params.codeType),
  87. params.code,
  88. params.withBody,
  89. params.ip,
  90. params.user,
  91. page,
  92. perPage,
  93. )
  94. if err != nil {
  95. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  96. return
  97. }
  98. middleware.SuccessResponse(c, result)
  99. }
  100. // GetGroupLogs godoc
  101. //
  102. // @Summary Get group logs
  103. // @Description Get logs for a specific group
  104. // @Tags log
  105. // @Produce json
  106. // @Security ApiKeyAuth
  107. // @Param group path string true "Group name"
  108. // @Param page query int false "Page number"
  109. // @Param per_page query int false "Items per page"
  110. // @Param start_timestamp query int false "Start timestamp (milliseconds)"
  111. // @Param end_timestamp query int false "End timestamp (milliseconds)"
  112. // @Param token_name query string false "Token name"
  113. // @Param model_name query string false "Model name"
  114. // @Param channel query int false "Channel ID"
  115. // @Param token_id query int false "Token ID"
  116. // @Param order query string false "Order"
  117. // @Param request_id query string false "Request ID"
  118. // @Param code_type query string false "Status code type"
  119. // @Param code query int false "Status code"
  120. // @Param with_body query bool false "With body"
  121. // @Param ip query string false "IP"
  122. // @Param user query string false "User"
  123. // @Success 200 {object} middleware.APIResponse{data=model.GetGroupLogsResult}
  124. // @Router /api/log/{group} [get]
  125. func GetGroupLogs(c *gin.Context) {
  126. group := c.Param("group")
  127. if group == "" {
  128. middleware.ErrorResponse(c, http.StatusBadRequest, "invalid group parameter")
  129. return
  130. }
  131. page, perPage := utils.ParsePageParams(c)
  132. startTime, endTime := parseTimeRange(c)
  133. params := parseCommonParams(c)
  134. result, err := model.GetGroupLogs(
  135. group,
  136. startTime,
  137. endTime,
  138. params.modelName,
  139. params.requestID,
  140. params.tokenID,
  141. params.tokenName,
  142. params.order,
  143. model.CodeType(params.codeType),
  144. params.code,
  145. params.withBody,
  146. params.ip,
  147. params.user,
  148. page,
  149. perPage,
  150. )
  151. if err != nil {
  152. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  153. return
  154. }
  155. middleware.SuccessResponse(c, result)
  156. }
  157. // SearchLogs godoc
  158. //
  159. // @Summary Search logs
  160. // @Description Search logs with various filters
  161. // @Tags logs
  162. // @Produce json
  163. // @Security ApiKeyAuth
  164. // @Param keyword query string false "Keyword"
  165. // @Param page query int false "Page number"
  166. // @Param per_page query int false "Items per page"
  167. // @Param start_timestamp query int false "Start timestamp (milliseconds)"
  168. // @Param end_timestamp query int false "End timestamp (milliseconds)"
  169. // @Param model_name query string false "Filter by model name"
  170. // @Param channel query int false "Filter by channel"
  171. // @Param token_id query int false "Filter by token id"
  172. // @Param order query string false "Order"
  173. // @Param request_id query string false "Request ID"
  174. // @Param code_type query string false "Status code type"
  175. // @Param code query int false "Status code"
  176. // @Param with_body query bool false "With body"
  177. // @Param ip query string false "IP"
  178. // @Param user query string false "User"
  179. // @Success 200 {object} middleware.APIResponse{data=model.GetLogsResult}
  180. // @Router /api/logs/search [get]
  181. func SearchLogs(c *gin.Context) {
  182. page, perPage := utils.ParsePageParams(c)
  183. startTime, endTime := parseTimeRange(c)
  184. params := parseCommonParams(c)
  185. keyword := c.Query("keyword")
  186. result, err := model.SearchLogs(
  187. keyword,
  188. params.requestID,
  189. params.tokenID,
  190. params.modelName,
  191. startTime,
  192. endTime,
  193. params.channelID,
  194. params.order,
  195. model.CodeType(params.codeType),
  196. params.code,
  197. params.withBody,
  198. params.ip,
  199. params.user,
  200. page,
  201. perPage,
  202. )
  203. if err != nil {
  204. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  205. return
  206. }
  207. middleware.SuccessResponse(c, result)
  208. }
  209. // SearchGroupLogs godoc
  210. //
  211. // @Summary Search group logs
  212. // @Description Search logs for a specific group with filters
  213. // @Tags log
  214. // @Produce json
  215. // @Security ApiKeyAuth
  216. // @Param group path string true "Group name"
  217. // @Param keyword query string false "Keyword"
  218. // @Param page query int false "Page number"
  219. // @Param per_page query int false "Items per page"
  220. // @Param start_timestamp query int false "Start timestamp (milliseconds)"
  221. // @Param end_timestamp query int false "End timestamp (milliseconds)"
  222. // @Param token_name query string false "Filter by token name"
  223. // @Param model_name query string false "Filter by model name"
  224. // @Param token_id query int false "Filter by token id"
  225. // @Param order query string false "Order"
  226. // @Param request_id query string false "Request ID"
  227. // @Param code_type query string false "Status code type"
  228. // @Param code query int false "Status code"
  229. // @Param with_body query bool false "With body"
  230. // @Param ip query string false "IP"
  231. // @Param user query string false "User"
  232. // @Success 200 {object} middleware.APIResponse{data=model.GetGroupLogsResult}
  233. // @Router /api/log/{group}/search [get]
  234. func SearchGroupLogs(c *gin.Context) {
  235. group := c.Param("group")
  236. if group == "" {
  237. middleware.ErrorResponse(c, http.StatusBadRequest, "invalid group parameter")
  238. return
  239. }
  240. page, perPage := utils.ParsePageParams(c)
  241. startTime, endTime := parseTimeRange(c)
  242. params := parseCommonParams(c)
  243. keyword := c.Query("keyword")
  244. result, err := model.SearchGroupLogs(
  245. group,
  246. keyword,
  247. params.requestID,
  248. params.tokenID,
  249. params.tokenName,
  250. params.modelName,
  251. startTime,
  252. endTime,
  253. params.order,
  254. model.CodeType(params.codeType),
  255. params.code,
  256. params.withBody,
  257. params.ip,
  258. params.user,
  259. page,
  260. perPage,
  261. )
  262. if err != nil {
  263. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  264. return
  265. }
  266. middleware.SuccessResponse(c, result)
  267. }
  268. // GetLogDetail godoc
  269. //
  270. // @Summary Get log detail
  271. // @Description Get detailed information about a specific log entry
  272. // @Tags logs
  273. // @Produce json
  274. // @Security ApiKeyAuth
  275. // @Param log_id path string true "Log ID"
  276. // @Success 200 {object} middleware.APIResponse{data=model.RequestDetail}
  277. // @Router /api/logs/detail/{log_id} [get]
  278. func GetLogDetail(c *gin.Context) {
  279. logID, _ := strconv.Atoi(c.Param("log_id"))
  280. log, err := model.GetLogDetail(logID)
  281. if err != nil {
  282. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  283. return
  284. }
  285. middleware.SuccessResponse(c, log)
  286. }
  287. // GetGroupLogDetail godoc
  288. //
  289. // @Summary Get group log detail
  290. // @Description Get detailed information about a specific log entry in a group
  291. // @Tags log
  292. // @Produce json
  293. // @Security ApiKeyAuth
  294. // @Param group path string true "Group name"
  295. // @Param log_id path string true "Log ID"
  296. // @Success 200 {object} middleware.APIResponse{data=model.RequestDetail}
  297. // @Router /api/log/{group}/detail/{log_id} [get]
  298. func GetGroupLogDetail(c *gin.Context) {
  299. group := c.Param("group")
  300. if group == "" {
  301. middleware.ErrorResponse(c, http.StatusBadRequest, "invalid group parameter")
  302. return
  303. }
  304. logID, _ := strconv.Atoi(c.Param("log_id"))
  305. log, err := model.GetGroupLogDetail(logID, group)
  306. if err != nil {
  307. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  308. return
  309. }
  310. middleware.SuccessResponse(c, log)
  311. }
  312. // DeleteHistoryLogs godoc
  313. //
  314. // @Summary Delete historical logs
  315. // @Description Deletes logs older than the specified retention period
  316. // @Tags logs
  317. // @Produce json
  318. // @Security ApiKeyAuth
  319. // @Param timestamp query int true "Timestamp (milliseconds)"
  320. // @Success 200 {object} middleware.APIResponse{data=int}
  321. // @Router /api/logs/ [delete]
  322. func DeleteHistoryLogs(c *gin.Context) {
  323. timestamp, _ := strconv.ParseInt(c.Query("timestamp"), 10, 64)
  324. if timestamp == 0 {
  325. middleware.ErrorResponse(c, http.StatusBadRequest, "timestamp is required")
  326. return
  327. }
  328. count, err := model.DeleteOldLog(time.UnixMilli(timestamp))
  329. if err != nil {
  330. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  331. return
  332. }
  333. middleware.SuccessResponse(c, count)
  334. }
  335. // SearchConsumeError godoc
  336. //
  337. // @Summary Search consumption errors
  338. // @Description Search for logs with consumption errors
  339. // @Tags logs
  340. // @Produce json
  341. // @Security ApiKeyAuth
  342. // @Param page query int false "Page number"
  343. // @Param per_page query int false "Items per page"
  344. // @Param start_timestamp query int false "Start timestamp (milliseconds)"
  345. // @Param end_timestamp query int false "End timestamp (milliseconds)"
  346. // @Param keyword query string false "Keyword"
  347. // @Param group query string false "Group"
  348. // @Param token_name query string false "Token name"
  349. // @Param model_name query string false "Model name"
  350. // @Param content query string false "Content"
  351. // @Param token_id query int false "Token ID"
  352. // @Param order query string false "Order"
  353. // @Param request_id query string false "Request ID"
  354. // @Success 200 {object} middleware.APIResponse{data=map[string]any{logs=[]model.RequestDetail,total=int}}
  355. // @Router /api/logs/consume_error [get]
  356. func SearchConsumeError(c *gin.Context) {
  357. keyword := c.Query("keyword")
  358. group := c.Query("group")
  359. tokenName := c.Query("token_name")
  360. modelName := c.Query("model_name")
  361. tokenID, _ := strconv.Atoi(c.Query("token_id"))
  362. page, perPage := utils.ParsePageParams(c)
  363. order := c.Query("order")
  364. requestID := c.Query("request_id")
  365. logs, total, err := model.SearchConsumeError(
  366. keyword,
  367. requestID,
  368. group,
  369. tokenName,
  370. modelName,
  371. tokenID,
  372. page,
  373. perPage,
  374. order,
  375. )
  376. if err != nil {
  377. middleware.ErrorResponse(c, http.StatusInternalServerError, err.Error())
  378. return
  379. }
  380. middleware.SuccessResponse(c, gin.H{
  381. "logs": logs,
  382. "total": total,
  383. })
  384. }