systemLogApi.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { apiUrl, getAgentHeaders } from "@/lib/config";
  2. export interface SystemLogItem {
  3. id: number;
  4. timestamp: string;
  5. level: string;
  6. category: string;
  7. event: string;
  8. source: string;
  9. trace_id?: string;
  10. conversation_id?: number;
  11. user_id?: number;
  12. visitor_id?: number;
  13. message: string;
  14. meta_json?: string;
  15. created_at: string;
  16. }
  17. export interface QuerySystemLogsResult {
  18. items: SystemLogItem[];
  19. total: number;
  20. page: number;
  21. page_size: number;
  22. }
  23. export interface QuerySystemLogsParams {
  24. from?: string;
  25. to?: string;
  26. level?: string;
  27. category?: string;
  28. event?: string;
  29. source?: string;
  30. conversationId?: number;
  31. keyword?: string;
  32. page?: number;
  33. pageSize?: number;
  34. }
  35. export interface LogMinLevelPolicy {
  36. effective_min_level: string;
  37. env_min_level: string;
  38. persisted_in_database: boolean;
  39. }
  40. export async function fetchLogMinLevelPolicy(): Promise<LogMinLevelPolicy> {
  41. const res = await fetch(apiUrl("/agent/logs/min-level"), {
  42. headers: getAgentHeaders(),
  43. });
  44. if (!res.ok) {
  45. const j = await res.json().catch(() => ({}));
  46. throw new Error((j as { error?: string }).error || `加载策略失败(${res.status})`);
  47. }
  48. return res.json();
  49. }
  50. export async function putLogMinLevelPolicy(minLevel: string): Promise<{ effective_min_level: string }> {
  51. const res = await fetch(apiUrl("/agent/logs/min-level"), {
  52. method: "PUT",
  53. headers: {
  54. "Content-Type": "application/json",
  55. ...getAgentHeaders(),
  56. },
  57. body: JSON.stringify({ min_level: minLevel }),
  58. });
  59. if (!res.ok) {
  60. const j = await res.json().catch(() => ({}));
  61. throw new Error((j as { error?: string }).error || `保存失败(${res.status})`);
  62. }
  63. return res.json();
  64. }
  65. export async function deleteLogMinLevelPolicy(): Promise<{ effective_min_level: string }> {
  66. const res = await fetch(apiUrl("/agent/logs/min-level"), {
  67. method: "DELETE",
  68. headers: getAgentHeaders(),
  69. });
  70. if (!res.ok) {
  71. const j = await res.json().catch(() => ({}));
  72. throw new Error((j as { error?: string }).error || `恢复失败(${res.status})`);
  73. }
  74. return res.json();
  75. }
  76. export async function fetchSystemLogs(params: QuerySystemLogsParams): Promise<QuerySystemLogsResult> {
  77. const q = new URLSearchParams();
  78. if (params.from) q.set("from", params.from);
  79. if (params.to) q.set("to", params.to);
  80. if (params.level) q.set("level", params.level);
  81. if (params.category) q.set("category", params.category);
  82. if (params.event) q.set("event", params.event);
  83. if (params.source) q.set("source", params.source);
  84. if (params.conversationId != null) q.set("conversation_id", String(params.conversationId));
  85. if (params.keyword) q.set("keyword", params.keyword);
  86. q.set("page", String(params.page ?? 1));
  87. q.set("page_size", String(params.pageSize ?? 50));
  88. const res = await fetch(`${apiUrl("/agent/logs/api")}?${q.toString()}`, {
  89. headers: getAgentHeaders(),
  90. });
  91. if (!res.ok) {
  92. const j = await res.json().catch(() => ({}));
  93. throw new Error((j as { error?: string }).error || `加载日志失败(${res.status})`);
  94. }
  95. return res.json();
  96. }
  97. export async function reportFrontendLog(input: {
  98. level: "info" | "warn" | "error";
  99. category: string;
  100. event: string;
  101. message: string;
  102. traceId?: string;
  103. conversationId?: number;
  104. visitorId?: number;
  105. meta?: Record<string, unknown>;
  106. }): Promise<void> {
  107. const payload: Record<string, unknown> = {
  108. level: input.level,
  109. category: input.category,
  110. event: input.event,
  111. message: input.message,
  112. trace_id: input.traceId,
  113. conversation_id: input.conversationId,
  114. visitor_id: input.visitorId,
  115. meta: input.meta ?? {},
  116. };
  117. const res = await fetch(apiUrl("/agent/logs/frontend"), {
  118. method: "POST",
  119. headers: {
  120. "Content-Type": "application/json",
  121. ...getAgentHeaders(),
  122. },
  123. body: JSON.stringify(payload),
  124. });
  125. if (!res.ok) {
  126. // 日志上报失败不阻断业务
  127. console.warn("frontend log report failed", res.status);
  128. }
  129. }