systemLog.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. import { executeQuery } from '../config/database';
  2. export interface SystemLog {
  3. id?: number;
  4. level: 'info' | 'warn' | 'error' | 'debug';
  5. message: string;
  6. source: string;
  7. module?: string;
  8. user_id?: number;
  9. username?: string;
  10. ip_address?: string;
  11. details?: string;
  12. created_at?: Date;
  13. }
  14. export class SystemLogModel {
  15. // 获取所有系统日志
  16. static async getAll(limit?: number, offset?: number): Promise<SystemLog[]> {
  17. let query = 'SELECT * FROM system_logs ORDER BY created_at DESC';
  18. const params: (string | number)[] = [];
  19. if (limit !== undefined) {
  20. query += ' LIMIT ?';
  21. params.push(limit);
  22. if (offset !== undefined) {
  23. query += ' OFFSET ?';
  24. params.push(offset);
  25. }
  26. }
  27. return await executeQuery(query, params);
  28. }
  29. // 根据ID获取系统日志
  30. static async getById(id: number): Promise<SystemLog | null> {
  31. const query = 'SELECT * FROM system_logs WHERE id = ?';
  32. const logs = await executeQuery(query, [id]);
  33. return logs.length > 0 ? logs[0] : null;
  34. }
  35. // 根据日志级别获取系统日志
  36. static async getByLevel(level: string, limit?: number, offset?: number): Promise<SystemLog[]> {
  37. let query = 'SELECT * FROM system_logs WHERE level = ? ORDER BY created_at DESC';
  38. const params: (string | number)[] = [level];
  39. if (limit !== undefined) {
  40. query += ' LIMIT ?';
  41. params.push(limit);
  42. if (offset !== undefined) {
  43. query += ' OFFSET ?';
  44. params.push(offset);
  45. }
  46. }
  47. return await executeQuery(query, params);
  48. }
  49. // 根据来源获取系统日志
  50. static async getBySource(source: string, limit?: number, offset?: number): Promise<SystemLog[]> {
  51. let query = 'SELECT * FROM system_logs WHERE source = ? ORDER BY created_at DESC';
  52. const params: (string | number)[] = [source];
  53. if (limit !== undefined) {
  54. query += ' LIMIT ?';
  55. params.push(limit);
  56. if (offset !== undefined) {
  57. query += ' OFFSET ?';
  58. params.push(offset);
  59. }
  60. }
  61. return await executeQuery(query, params);
  62. }
  63. // 根据模块获取系统日志
  64. static async getByModule(module: string, limit?: number, offset?: number): Promise<SystemLog[]> {
  65. let query = 'SELECT * FROM system_logs WHERE module = ? ORDER BY created_at DESC';
  66. const params: (string | number)[] = [module];
  67. if (limit !== undefined) {
  68. query += ' LIMIT ?';
  69. params.push(limit);
  70. if (offset !== undefined) {
  71. query += ' OFFSET ?';
  72. params.push(offset);
  73. }
  74. }
  75. return await executeQuery(query, params);
  76. }
  77. // 根据时间范围获取系统日志
  78. static async getByTimeRange(startTime: Date, endTime: Date, limit?: number, offset?: number): Promise<SystemLog[]> {
  79. let query = 'SELECT * FROM system_logs WHERE created_at BETWEEN ? AND ? ORDER BY created_at DESC';
  80. const params: any[] = [startTime, endTime];
  81. if (limit !== undefined) {
  82. query += ' LIMIT ?';
  83. params.push(limit);
  84. if (offset !== undefined) {
  85. query += ' OFFSET ?';
  86. params.push(offset);
  87. }
  88. }
  89. return await executeQuery(query, params);
  90. }
  91. // 获取系统日志总数
  92. static async getCount(): Promise<number> {
  93. const query = 'SELECT COUNT(*) as count FROM system_logs';
  94. const result = await executeQuery(query);
  95. return result[0].count;
  96. }
  97. // 获取日志级别统计
  98. static async getLevelStats(startTime?: Date, endTime?: Date): Promise<any[]> {
  99. let query = `
  100. SELECT
  101. level,
  102. COUNT(*) as count
  103. FROM system_logs
  104. `;
  105. const params: any[] = [];
  106. if (startTime && endTime) {
  107. query += ' WHERE created_at BETWEEN ? AND ?';
  108. params.push(startTime, endTime);
  109. }
  110. query += ' GROUP BY level';
  111. return await executeQuery(query, params);
  112. }
  113. // 获取来源统计
  114. static async getSourceStats(startTime?: Date, endTime?: Date): Promise<any[]> {
  115. let query = `
  116. SELECT
  117. source,
  118. COUNT(*) as count
  119. FROM system_logs
  120. `;
  121. const params: any[] = [];
  122. if (startTime && endTime) {
  123. query += ' WHERE created_at BETWEEN ? AND ?';
  124. params.push(startTime, endTime);
  125. }
  126. query += ' GROUP BY source';
  127. return await executeQuery(query, params);
  128. }
  129. // 获取每日系统日志统计
  130. static async getDailyStats(days: number = 7): Promise<any[]> {
  131. const query = `
  132. SELECT
  133. DATE(created_at) as date,
  134. COUNT(*) as total,
  135. SUM(CASE WHEN level = 'info' THEN 1 ELSE 0 END) as info,
  136. SUM(CASE WHEN level = 'warn' THEN 1 ELSE 0 END) as warn,
  137. SUM(CASE WHEN level = 'error' THEN 1 ELSE 0 END) as error,
  138. SUM(CASE WHEN level = 'debug' THEN 1 ELSE 0 END) as debug
  139. FROM system_logs
  140. WHERE created_at >= DATE_SUB(CURRENT_DATE(), INTERVAL ? DAY)
  141. GROUP BY DATE(created_at)
  142. ORDER BY date DESC
  143. `;
  144. return await executeQuery(query, [days]);
  145. }
  146. // 创建系统日志
  147. static async create(systemLog: Omit<SystemLog, 'id' | 'created_at'>): Promise<SystemLog> {
  148. const query = `
  149. INSERT INTO system_logs (level, message, source, module, user_id, username, ip_address, details)
  150. VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  151. `;
  152. const params = [
  153. systemLog.level,
  154. systemLog.message,
  155. systemLog.source,
  156. systemLog.module || null,
  157. systemLog.user_id || null,
  158. systemLog.username || null,
  159. systemLog.ip_address || null,
  160. systemLog.details || null
  161. ];
  162. const result = await executeQuery(query, params) as any;
  163. return { ...systemLog, id: result.insertId, created_at: new Date() };
  164. }
  165. // 搜索系统日志
  166. static async search(searchTerm: string, limit?: number, offset?: number): Promise<SystemLog[]> {
  167. let query = `
  168. SELECT * FROM system_logs
  169. WHERE message LIKE ? OR source LIKE ? OR module LIKE ? OR details LIKE ?
  170. ORDER BY created_at DESC
  171. `;
  172. const params: (string | number)[] = [
  173. `%${searchTerm}%`, `%${searchTerm}%`, `%${searchTerm}%`, `%${searchTerm}%`
  174. ];
  175. if (limit !== undefined) {
  176. query += ' LIMIT ?';
  177. params.push(limit);
  178. if (offset !== undefined) {
  179. query += ' OFFSET ?';
  180. params.push(offset);
  181. }
  182. }
  183. return await executeQuery(query, params);
  184. }
  185. // 获取搜索结果总数
  186. static async getSearchCount(searchTerm: string): Promise<number> {
  187. const query = `
  188. SELECT COUNT(*) as count
  189. FROM system_logs
  190. WHERE message LIKE ? OR source LIKE ? OR module LIKE ? OR details LIKE ?
  191. `;
  192. const params = [
  193. `%${searchTerm}%`, `%${searchTerm}%`, `%${searchTerm}%`, `%${searchTerm}%`
  194. ];
  195. const result = await executeQuery(query, params);
  196. return result[0].count;
  197. }
  198. // 清理旧的系统日志
  199. static async cleanup(daysToKeep: number = 30): Promise<number> {
  200. const query = 'DELETE FROM system_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL ? DAY)';
  201. const result = await executeQuery(query, [daysToKeep]) as any;
  202. return result.affectedRows;
  203. }
  204. // 获取最近的系统日志
  205. static async getRecent(limit: number = 10): Promise<SystemLog[]> {
  206. const query = 'SELECT * FROM system_logs ORDER BY created_at DESC LIMIT ?';
  207. return await executeQuery(query, [limit]);
  208. }
  209. // 根据用户ID获取系统日志
  210. static async getByUserId(userId: number, limit?: number, offset?: number): Promise<SystemLog[]> {
  211. let query = 'SELECT * FROM system_logs WHERE user_id = ? ORDER BY created_at DESC';
  212. const params: (string | number)[] = [userId];
  213. if (limit !== undefined) {
  214. query += ' LIMIT ?';
  215. params.push(limit);
  216. if (offset !== undefined) {
  217. query += ' OFFSET ?';
  218. params.push(offset);
  219. }
  220. }
  221. return await executeQuery(query, params);
  222. }
  223. // 根据用户名获取系统日志
  224. static async getByUsername(username: string, limit?: number, offset?: number): Promise<SystemLog[]> {
  225. let query = 'SELECT * FROM system_logs WHERE username = ? ORDER BY created_at DESC';
  226. const params: (string | number)[] = [username];
  227. if (limit !== undefined) {
  228. query += ' LIMIT ?';
  229. params.push(limit);
  230. if (offset !== undefined) {
  231. query += ' OFFSET ?';
  232. params.push(offset);
  233. }
  234. }
  235. return await executeQuery(query, params);
  236. }
  237. // 获取完整的系统日志统计信息
  238. static async getFullStats(): Promise<any> {
  239. try {
  240. // 获取总数
  241. const totalQuery = 'SELECT COUNT(*) as count FROM system_logs';
  242. const totalResult = await executeQuery(totalQuery);
  243. const total = totalResult[0].count;
  244. // 获取各级别数量
  245. const levelQuery = `
  246. SELECT
  247. level,
  248. COUNT(*) as count
  249. FROM system_logs
  250. GROUP BY level
  251. `;
  252. const levelStats = await executeQuery(levelQuery);
  253. const byLevel: Record<string, number> = {};
  254. levelStats.forEach((stat: any) => {
  255. byLevel[stat.level] = stat.count;
  256. });
  257. // 获取来源统计
  258. const sourceQuery = `
  259. SELECT
  260. source,
  261. COUNT(*) as count
  262. FROM system_logs
  263. GROUP BY source
  264. `;
  265. const sourceStats = await executeQuery(sourceQuery);
  266. const bySource: Record<string, number> = {};
  267. sourceStats.forEach((stat: any) => {
  268. bySource[stat.source] = stat.count;
  269. });
  270. // 获取时间范围统计
  271. const todayQuery = `
  272. SELECT COUNT(*) as count
  273. FROM system_logs
  274. WHERE DATE(created_at) = CURDATE()
  275. `;
  276. const todayResult = await executeQuery(todayQuery);
  277. const today = todayResult[0].count;
  278. const weekQuery = `
  279. SELECT COUNT(*) as count
  280. FROM system_logs
  281. WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
  282. `;
  283. const weekResult = await executeQuery(weekQuery);
  284. const week = weekResult[0].count;
  285. const monthQuery = `
  286. SELECT COUNT(*) as count
  287. FROM system_logs
  288. WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
  289. `;
  290. const monthResult = await executeQuery(monthQuery);
  291. const month = monthResult[0].count;
  292. return {
  293. total,
  294. byLevel,
  295. bySource,
  296. byTimeRange: {
  297. today,
  298. week,
  299. month
  300. }
  301. };
  302. } catch (error) {
  303. console.error('获取系统日志统计信息失败:', error);
  304. // 返回默认值
  305. return {
  306. total: 0,
  307. byLevel: {},
  308. bySource: {},
  309. byTimeRange: {
  310. today: 0,
  311. week: 0,
  312. month: 0
  313. }
  314. };
  315. }
  316. }
  317. // 根据多个条件获取系统日志数量
  318. static async getCountByMultipleConditions(
  319. conditions: { [key: string]: any },
  320. startTime?: Date,
  321. endTime?: Date,
  322. fuzzyFields?: string[]
  323. ): Promise<number> {
  324. let query = 'SELECT COUNT(*) as count FROM system_logs WHERE 1=1';
  325. const params: any[] = [];
  326. for (const [key, value] of Object.entries(conditions)) {
  327. if (value !== undefined && value !== null) {
  328. if (fuzzyFields && fuzzyFields.includes(key)) {
  329. query += ` AND ${key} LIKE ?`;
  330. params.push(`%${value}%`);
  331. } else if (Array.isArray(value)) {
  332. const placeholders = value.map(() => '?').join(', ');
  333. query += ` AND ${key} IN (${placeholders})`;
  334. params.push(...value);
  335. } else {
  336. query += ` AND ${key} = ?`;
  337. params.push(value);
  338. }
  339. }
  340. }
  341. if (startTime && endTime) {
  342. query += ' AND created_at BETWEEN ? AND ?';
  343. params.push(startTime, endTime);
  344. }
  345. const result = await executeQuery(query, params) as any;
  346. return result[0].count;
  347. }
  348. // 根据多个条件获取系统日志
  349. static async getByMultipleConditions(
  350. conditions: { [key: string]: any },
  351. startTime?: Date,
  352. endTime?: Date,
  353. limit?: number,
  354. offset?: number,
  355. fuzzyFields?: string[]
  356. ): Promise<SystemLog[]> {
  357. let query = 'SELECT * FROM system_logs WHERE 1=1';
  358. const params: any[] = [];
  359. for (const [key, value] of Object.entries(conditions)) {
  360. if (value !== undefined && value !== null) {
  361. if (fuzzyFields && fuzzyFields.includes(key)) {
  362. query += ` AND ${key} LIKE ?`;
  363. params.push(`%${value}%`);
  364. } else if (Array.isArray(value)) {
  365. const placeholders = value.map(() => '?').join(', ');
  366. query += ` AND ${key} IN (${placeholders})`;
  367. params.push(...value);
  368. } else {
  369. query += ` AND ${key} = ?`;
  370. params.push(value);
  371. }
  372. }
  373. }
  374. if (startTime && endTime) {
  375. query += ' AND created_at BETWEEN ? AND ?';
  376. params.push(startTime, endTime);
  377. }
  378. query += ' ORDER BY created_at DESC';
  379. if (limit !== undefined && offset !== undefined) {
  380. query += ' LIMIT ? OFFSET ?';
  381. params.push(limit, offset);
  382. }
  383. return await executeQuery(query, params);
  384. }
  385. // 根据时间范围获取系统日志数量
  386. static async getCountByTimeRange(startTime: Date, endTime: Date): Promise<number> {
  387. const query = 'SELECT COUNT(*) as count FROM system_logs WHERE created_at BETWEEN ? AND ?';
  388. const result = await executeQuery(query, [startTime, endTime]) as any;
  389. return result[0].count;
  390. }
  391. // 根据日志级别获取系统日志数量
  392. static async getCountByLevel(level: string): Promise<number> {
  393. const query = 'SELECT COUNT(*) as count FROM system_logs WHERE level = ?';
  394. const result = await executeQuery(query, [level]) as any;
  395. return result[0].count;
  396. }
  397. // 根据来源获取系统日志数量
  398. static async getCountBySource(source: string): Promise<number> {
  399. const query = 'SELECT COUNT(*) as count FROM system_logs WHERE source = ?';
  400. const result = await executeQuery(query, [source]) as any;
  401. return result[0].count;
  402. }
  403. // 根据模块获取系统日志数量
  404. static async getCountByModule(module: string): Promise<number> {
  405. const query = 'SELECT COUNT(*) as count FROM system_logs WHERE module = ?';
  406. const result = await executeQuery(query, [module]) as any;
  407. return result[0].count;
  408. }
  409. // 根据用户ID获取系统日志数量
  410. static async getCountByUserId(userId: number): Promise<number> {
  411. const query = 'SELECT COUNT(*) as count FROM system_logs WHERE user_id = ?';
  412. const result = await executeQuery(query, [userId]) as any;
  413. return result[0].count;
  414. }
  415. // 根据用户名获取系统日志数量
  416. static async getCountByUsername(username: string): Promise<number> {
  417. const query = 'SELECT COUNT(*) as count FROM system_logs WHERE username = ?';
  418. const result = await executeQuery(query, [username]) as any;
  419. return result[0].count;
  420. }
  421. }