| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- const express = require("express");
- const router = express.Router();
- const { executeQuery } = require("../config/database");
- // 获取工具调用日志列表
- router.get("/", async (req, res) => {
- try {
- const { page = 1, pageSize = 10, user, mcp_tools_name, status, startTime, endTime } = req.query;
- const offset = (parseInt(page) - 1) * parseInt(pageSize);
- // 构建查询条件
- let whereConditions = [];
- let queryParams = [];
- if (user) {
- whereConditions.push("user LIKE ?");
- queryParams.push(`%${user}%`);
- }
- if (mcp_tools_name) {
- whereConditions.push("mcp_tools_name LIKE ?");
- queryParams.push(`%${mcp_tools_name}%`);
- }
- if (status) {
- if (status === "failure") {
- // 将“失败”视为非成功的所有状态,避免仅限于字符串 'failure'
- whereConditions.push("status <> 'success'");
- } else {
- whereConditions.push("status = ?");
- queryParams.push(status);
- }
- }
- if (startTime) {
- whereConditions.push("call_timestamp >= ?");
- queryParams.push(parseInt(startTime));
- }
- if (endTime) {
- whereConditions.push("call_timestamp <= ?");
- queryParams.push(parseInt(endTime));
- }
- const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(" AND ")}` : "";
- // 获取总数
- const countQuery = `SELECT COUNT(*) as total FROM tools_call_log ${whereClause}`;
- const countResult = await executeQuery(countQuery, queryParams);
- const total = countResult[0]?.total || 0;
- // 获取列表数据
- const listQuery = `
- SELECT id, user, token, mcp_tools_name, status, fail_msg,
- call_timestamp, finish_timestamp
- FROM tools_call_log
- ${whereClause}
- ORDER BY call_timestamp DESC
- LIMIT ? OFFSET ?
- `;
- const listParams = [...queryParams, parseInt(pageSize), offset];
- const list = await executeQuery(listQuery, listParams);
- res.json({
- data: list,
- total,
- page: parseInt(page),
- pageSize: parseInt(pageSize),
- });
- } catch (error) {
- console.error("获取工具调用日志列表失败:", error);
- res.status(500).json({
- success: false,
- error: "获取工具调用日志列表失败",
- });
- }
- });
- // 获取工具调用日志详情(仅匹配数字ID,避免与 /stats 等命名路由冲突)
- router.get("/:id(\\d+)", async (req, res) => {
- try {
- const { id } = req.params;
- const query = `
- SELECT id, user, token, mcp_tools_name, request_params, status,
- response, fail_msg, call_timestamp, finish_timestamp
- FROM tools_call_log
- WHERE id = ?
- `;
- const result = await executeQuery(query, [id]);
- if (result.length === 0) {
- return res.status(404).json({
- success: false,
- error: "工具调用日志不存在",
- });
- }
- res.json(result[0]);
- } catch (error) {
- console.error("获取工具调用日志详情失败:", error);
- res.status(500).json({
- success: false,
- error: "获取工具调用日志详情失败",
- });
- }
- });
- // 获取统计信息:支持与列表一致的筛选条件
- router.get("/stats", async (req, res) => {
- try {
- const { user, mcp_tools_name, status, startTime, endTime } = req.query;
- let whereConditions = [];
- let queryParams = [];
- if (user) {
- whereConditions.push("user LIKE ?");
- queryParams.push(`%${user}%`);
- }
- if (mcp_tools_name) {
- whereConditions.push("mcp_tools_name LIKE ?");
- queryParams.push(`%${mcp_tools_name}%`);
- }
- if (status) {
- if (status === "failure") {
- whereConditions.push("status <> 'success'");
- } else {
- whereConditions.push("status = ?");
- queryParams.push(status);
- }
- }
- if (startTime) {
- whereConditions.push("call_timestamp >= ?");
- queryParams.push(parseInt(startTime));
- }
- if (endTime) {
- whereConditions.push("call_timestamp <= ?");
- queryParams.push(parseInt(endTime));
- }
- const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(" AND ")}` : "";
- const sql = `
- SELECT
- COUNT(*) AS total,
- SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS success_count
- FROM tools_call_log
- ${whereClause}
- `;
- const rows = await executeQuery(sql, queryParams);
- const row = rows && rows[0] ? rows[0] : { total: 0, success_count: 0 };
- const total = Number(row.total) || 0;
- const successCount = Number(row.success_count) || 0;
- const failureCount = total - successCount;
- const successRate = total > 0 ? Number(((successCount / total) * 100).toFixed(2)) : 0;
- res.json({ total, successCount, failureCount, successRate });
- } catch (error) {
- console.error("获取工具调用日志统计失败:", error);
- res.status(500).json({ error: "获取工具调用日志统计失败" });
- }
- });
- module.exports = router;
|