Skip to content

如何设计一套统计全站请求耗时的工具

Posted on:2024年8月15日 at 09:33

以下是一个解决方案的示例:

1. 需求分析

2. 实现步骤

前端实现

  1. 拦截请求

    使用 XMLHttpRequestfetch 的拦截器,捕获请求和响应。

    // 对 XMLHttpRequest 的封装
    (function () {
      const originalSend = XMLHttpRequest.prototype.send;
      XMLHttpRequest.prototype.send = function (...args) {
        const xhr = this;
        const startTime = performance.now();
        xhr.addEventListener("loadend", () => {
          const endTime = performance.now();
          const duration = endTime - startTime;
          logRequest(xhr.responseURL, xhr.method, duration, xhr.status);
        });
        originalSend.apply(xhr, args);
      };
    })();
    
    // 对 fetch 的封装
    (function () {
      const originalFetch = window.fetch;
      window.fetch = function (...args) {
        const startTime = performance.now();
        return originalFetch(...args).then((response) => {
          const endTime = performance.now();
          const duration = endTime - startTime;
          logRequest(
            response.url,
            args[1]?.method || "GET",
            duration,
            response.status,
          );
          return response;
        });
      };
    })();
    
  2. 记录日志

    实现 logRequest 函数,将请求信息记录到服务器端。

    function logRequest(url, method, duration, status) {
      navigator.sendBeacon(
        "/log",
        JSON.stringify({
          url,
          method,
          duration,
          status,
          timestamp: new Date().toISOString(),
        }),
      );
    }
    
  3. 显示统计数据

    通过发送定期的请求,将收集的数据发送到服务器,并在服务器端生成统计报告。

后端实现

  1. 数据存储

    选择合适的存储方式(如数据库、日志文件),存储请求日志。

    const express = require("express");
    const app = express();
    const fs = require("fs");
    
    app.use(express.json());
    
    app.post("/log", (req, res) => {
      const logEntry = req.body;
      fs.appendFile(
        "request_logs.json",
        JSON.stringify(logEntry) + "\n",
        (err) => {
          if (err) {
            console.error("Failed to write log:", err);
          }
        },
      );
      res.status(200).send("Logged");
    });
    
    app.listen(3000, () => {
      console.log("Server running on port 3000");
    });
    
  2. 数据分析

    实现数据分析和可视化工具,生成统计报告和图表。

    // 数据分析示例(伪代码)
    const logs = readLogs("request_logs.json");
    const stats = analyzeLogs(logs);
    renderStatsToDashboard(stats);
    
  3. 报警机制

    根据设置的阈值(如请求耗时、错误率)进行报警。

    function checkAlerts(stats) {
      if (stats.averageDuration > THRESHOLD_DURATION) {
        sendAlert("High average request duration");
      }
      if (stats.errorRate > THRESHOLD_ERROR_RATE) {
        sendAlert("High error rate");
      }
    }
    

数据可视化

  1. 前端展示

    使用图表库(如 Chart.js、D3.js)展示统计数据。

    <canvas id="request-chart"></canvas>
    <script>
      const ctx = document.getElementById("request-chart").getContext("2d");
      const chart = new Chart(ctx, {
        type: "line",
        data: {
          labels: ["Jan", "Feb", "Mar", "Apr"], // Example labels
          datasets: [
            {
              label: "Request Duration",
              data: [30, 40, 35, 50], // Example data
              borderColor: "rgba(75, 192, 192, 1)",
              borderWidth: 1,
            },
          ],
        },
      });
    </script>
    
  2. 报告生成

    生成详细的性能报告,并提供下载或在线查看的功能。

原文转自:https://fe.ecool.fun/topic/d158ac72-5f69-434b-a00c-c7976efe8781