adding data analyzer
test-org/trust-module-frontend/pipeline/pr-rc This commit looks good Details

pull/51/head
DmitriyA 2025-07-14 02:59:06 -04:00
parent 61c623b93d
commit ef5df6971d
3 changed files with 169 additions and 17 deletions

View File

@ -92,13 +92,13 @@ const PrometheusChart = ({ metricInfo, chartHeight = 580 }) => {
};
const step = calculateStep(start, end);
const data = await metricsService.fetchMetricsRange(
metricName,
Math.floor(start.getTime() / 1000),
Math.floor(end.getTime() / 1000),
step,
extendedFilters
);
const data = await metricsService.fetchMetricsRange(
metricName,
Math.floor(start.getTime() / 1000),
Math.floor(end.getTime() / 1000),
step,
extendedFilters
);
const formattedData = downsampleData(formatMetricData(data), 100); //КОЛИЧЕСТВО ТОЧЕК НА ГРАФИКЕ
@ -256,12 +256,6 @@ const data = await metricsService.fetchMetricsRange(
source_id
}}
ranges={ranges}
/*ranges={ranges.length > 0 ? ranges : [
{ min: 0, max: 60, status: 1 },
{ min: 60, max: 80, status: 2 },
{ min: 80, max: 90, status: 3 },
{ min: 90, max: 100, status: 4 }
]}*/
/>
{showLogs && (
<StatusLogTable logs={statusLogs} />

View File

@ -0,0 +1,156 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import {
Button,
Typography,
Paper,
Box,
CircularProgress,
Alert,
Snackbar,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow
} from '@mui/material';
const MetricsAnalyzer = () => {
const [loading, setLoading] = useState(false);
const [metrics, setMetrics] = useState([]);
const [analysisResult, setAnalysisResult] = useState(null);
const [error, setError] = useState(null);
const [openSnackbar, setOpenSnackbar] = useState(false);
const transformMetricsForAnalysis = (metrics) => {
return metrics.flatMap(metricResponse =>
metricResponse.data.map(metricData => ({
description: metricData.description,
device: parseInt(metricData.device, 10),
id: metricData.source_id,
name: metricData.__name__,
source: metricData.instance,
status: parseInt(metricData.status, 10),
timestamp: metricData.timestamp,
value: metricData.value.toString()
}))
);
};
const analyzeMetrics = async () => {
try {
setLoading(true);
setError(null);
// 1. Сначала загружаем метрики
const metricsResponse = await axios.get(`${import.meta.env.VITE_BACK_URL}/api/metrics/all-values`);
setMetrics(metricsResponse.data);
// 2. Преобразуем и отправляем на анализ
const requestData = transformMetricsForAnalysis(metricsResponse.data);
const analysisResponse = await axios.get(`${import.meta.env.VITE_BACK_URL}:5134/api/metrics/rest`, {
data: requestData,
headers: {
'Content-Type': 'application/json',
}
});
setAnalysisResult(analysisResponse.data);
setOpenSnackbar(true);
} catch (err) {
const errorMessage = err.response?.data?.message ||
err.message ||
'Ошибка при анализе метрик';
setError(errorMessage);
setOpenSnackbar(true);
} finally {
setLoading(false);
}
};
const handleCloseSnackbar = () => {
setOpenSnackbar(false);
};
return (
<Box sx={{ maxWidth: 800, margin: '0 auto', mt: 4 }}>
<Typography variant="h5" gutterBottom sx={{ mb: 3 }}>
Анализ метрик системы
</Typography>
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 3 }}>
<Button
variant="contained"
color="primary"
onClick={analyzeMetrics}
disabled={loading}
startIcon={loading ? <CircularProgress size={24} /> : null}
size="large"
>
{loading ? 'Выполняется анализ...' : 'Проанализировать метрики'}
</Button>
</Box>
{analysisResult && (
<Paper elevation={3} sx={{ p: 3, mt: 2 }}>
<Typography variant="h6" gutterBottom>
Результаты анализа
</Typography>
{Array.isArray(analysisResult) ? (
<TableContainer>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>Параметр</TableCell>
<TableCell>Результат</TableCell>
<TableCell>Описание</TableCell>
</TableRow>
</TableHead>
<TableBody>
{analysisResult.map((item, index) => (
<TableRow key={index}>
<TableCell>{item.name || item.parameter}</TableCell>
<TableCell>{item.value || item.result}</TableCell>
<TableCell>{item.description || '-'}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
) : (
<Box sx={{
p: 2,
backgroundColor: 'background.paper',
borderRadius: 1,
maxHeight: 400,
overflow: 'auto'
}}>
<Typography variant="body2" component="pre">
{JSON.stringify(analysisResult, null, 2)}
</Typography>
</Box>
)}
</Paper>
)}
<Snackbar
open={openSnackbar}
autoHideDuration={6000}
onClose={handleCloseSnackbar}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
>
<Alert
onClose={handleCloseSnackbar}
severity={error ? 'error' : 'success'}
sx={{ width: '100%' }}
>
{error || 'Анализ метрик успешно завершен'}
</Alert>
</Snackbar>
</Box>
);
};
export default MetricsAnalyzer;

View File

@ -2,10 +2,9 @@ import SystemStatusChart from "../../Charts/SystemStatusChart";
import TreeTable from "../UI/TreeTable";
import FlowChart from "../TreeChart/FlowChart";
import { getStatusColor } from "../TreeChart/dataUtils";
import MetricsAnalyzer from "./MetricsAnalyzer"; // Импортируем новый компонент
const TabContent = ({ activeTab, tabs, statusHistories, treeData1, tabContent, handleOpenTab }) => {
// Функция для подсчета количества элементов каждого статуса
const countStatuses = (data) => {
const counts = { green: 0, yellow: 0, orange: 0, red: 0 };
@ -66,6 +65,9 @@ const TabContent = ({ activeTab, tabs, statusHistories, treeData1, tabContent, h
<label>Статус компонентов системы</label>
<TreeTable data={treeData1} />
{/* Добавляем кнопку анализа
<MetricsAnalyzer />*/}
</div>
);
} else if (activeTab === "Визуализация") {