requestLog.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. const path = require('path')
  2. const db = require("../plugin/DataBase/db")
  3. const Logger = require('./Logger')
  4. const ipSearcher = require('../plugin/ip2region')
  5. class RequestLog {
  6. constructor() {
  7. this.logger = new Logger()
  8. this.searcher = ipSearcher.newWithFileOnly(path.join(__dirname, '../plugin/ip2region/ip2region.xdb'))
  9. }
  10. async insertLog(req, resData, namespace, method, path) {
  11. try {
  12. const time = Date.now();
  13. const ip = this.getClientIp(req);
  14. let ipData
  15. try {
  16. let ipInfo = await this.searcher.search(ip)
  17. ipData = ipInfo?.region ?? null
  18. } catch {
  19. ipData = null
  20. }
  21. const userAgent = req.headers['user-agent'] ?? null;
  22. const deviceType = req.headers['device-type'] ?? '浏览器'
  23. let reqData = method.toLowerCase() === 'get' ? req.query : req.body
  24. const safe = (v) => (v === undefined ? null : v)
  25. const sql = `
  26. INSERT INTO requestLog
  27. (create_user, create_time, method, reqData, resData, code, ip, ua, deviceType, apiName, location, url)
  28. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  29. `
  30. const params = [
  31. safe(reqData?.uuid) ?? '', // create_user
  32. time, // create_time
  33. method, // method
  34. JSON.stringify(reqData ?? {}), // reqData
  35. JSON.stringify(resData ?? {}), // resData
  36. safe(resData?.code), // code
  37. safe(ip), // ip
  38. safe(userAgent), // ua
  39. safe(deviceType), // deviceType
  40. namespace ?? '未知', // apiName
  41. safe(ipData) ?? '未知', // location
  42. path // url
  43. ];
  44. let r = await db.query(sql, params)
  45. if (!r || r.affectedRows !== 1) {
  46. this.logger.error(`插入日志信息失败!数据库错误`)
  47. }
  48. } catch (error) {
  49. this.logger.error(`插入日志信息失败!${error}`)
  50. }
  51. }
  52. getClientIp(req) {
  53. let ip = null
  54. if (req.headers['x-forwarded-for']) {
  55. ip = req.headers['x-forwarded-for'].split(',')[0].trim();
  56. } else if (req.headers['x-real-ip']) {
  57. ip = req.headers['x-real-ip'];
  58. } else {
  59. ip = req.connection.remoteAddress || ''
  60. }
  61. // 如果是 IPv6 映射的 IPv4 (::ffff:x.x.x.x),提取后面的 IPv4
  62. if (ip.startsWith("::ffff:")) {
  63. ip = ip.replace("::ffff:", "")
  64. }
  65. // 如果是 [::1] 或其他 IPv6
  66. const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/
  67. if (!ipv4Regex.test(ip)) {
  68. return '0.0.0.0'; // 非 IPv4
  69. }
  70. return ip ?? '0.0.0.0';
  71. }
  72. }
  73. module.exports = RequestLog