log.go 12 KB

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