| import React, { useState, useEffect } from 'react'; |
| import { |
| ResponsiveContainer, LineChart, Line, |
| XAxis, YAxis, Tooltip, CartesianGrid, Legend |
| } from 'recharts'; |
| import { fetchSysCost } from '../api/posts_trm'; |
| |
| function PerformanceLogs({ userId }) { |
| const [data, setData] = useState([]); |
| |
| useEffect(() => { |
| fetchSysCost(userId) |
| .then(list => { |
| const msList = list.map(item => ({ |
| ...item, |
| elapsed_time: item.elapsed_time * 1000, |
| cpu_user: item.cpu_user * 1000, |
| cpu_system: item.cpu_system * 1000, |
| memory_rss: item.memory_rss / (1024 * 1024*8), // convert bytes to MB |
| record_time_ts: new Date(item.record_time).getTime() // add numeric timestamp |
| })); |
| console.log('Converted data:', msList[0]); // debug first item |
| setData(msList); |
| }) |
| .catch(err => console.error('fetchSysCost error:', err)); |
| }, [userId]); |
| |
| return ( |
| <section className="dashboard-performance"> |
| {/* 响应时间图表 */} |
| <div style={{ marginBottom: '30px' }}> |
| <h3>响应时间</h3> |
| <ResponsiveContainer width="100%" height={300}> |
| <LineChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}> |
| <CartesianGrid strokeDasharray="3 3" /> |
| <XAxis |
| dataKey="record_time_ts" |
| type="number" |
| domain={['dataMin', 'dataMax']} |
| tickFormatter={ts => new Date(ts).toLocaleTimeString()} |
| /> |
| <YAxis domain={[0, 'auto']} label={{ value: '时间 (ms)', angle: -90, position: 'insideLeft' }} /> |
| <Tooltip formatter={(val) => typeof val === 'number' ? `${val.toFixed(2)} ms` : val} /> |
| <Legend /> |
| <Line type="monotone" dataKey="elapsed_time" stroke="#8884d8" name="响应时间 (ms)" /> |
| </LineChart> |
| </ResponsiveContainer> |
| </div> |
| |
| {/* CPU时间图表 */} |
| <div style={{ marginBottom: '30px' }}> |
| <h3>CPU 使用时间</h3> |
| <ResponsiveContainer width="100%" height={300}> |
| <LineChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}> |
| <CartesianGrid strokeDasharray="3 3" /> |
| <XAxis |
| dataKey="record_time_ts" |
| type="number" |
| domain={['dataMin', 'dataMax']} |
| tickFormatter={ts => new Date(ts).toLocaleTimeString()} |
| /> |
| <YAxis domain={[0, 'auto']} label={{ value: '时间 (ms)', angle: -90, position: 'insideLeft' }} /> |
| <Tooltip formatter={(val) => typeof val === 'number' ? `${val.toFixed(2)} ms` : val} /> |
| <Legend /> |
| <Line type="monotone" dataKey="cpu_user" stroke="#82ca9d" name="CPU 用户时间 (ms)" /> |
| <Line type="monotone" dataKey="cpu_system" stroke="#ffc658" name="CPU 系统时间 (ms)" /> |
| </LineChart> |
| </ResponsiveContainer> |
| </div> |
| |
| {/* 内存图表 */} |
| <div style={{ marginBottom: '30px' }}> |
| <h3>内存使用</h3> |
| <ResponsiveContainer width="100%" height={300}> |
| <LineChart data={data} margin={{ top: 20, right: 30, left: 20, bottom: 5 }}> |
| <CartesianGrid strokeDasharray="3 3" /> |
| <XAxis |
| dataKey="record_time_ts" |
| type="number" |
| domain={['dataMin', 'dataMax']} |
| tickFormatter={ts => new Date(ts).toLocaleTimeString()} |
| /> |
| <YAxis domain={[0, 'auto']} label={{ value: '内存 (MB)', angle: -90, position: 'insideLeft' }} /> |
| <Tooltip formatter={(val) => typeof val === 'number' ? `${val.toFixed(2)} MB` : val} /> |
| <Legend /> |
| <Line type="monotone" dataKey="memory_rss" stroke="#ff7300" name="内存 RSS" /> |
| </LineChart> |
| </ResponsiveContainer> |
| </div> |
| </section> |
| ); |
| } |
| |
| export default PerformanceLogs; |