adding data analyzer
test-org/trust-module-frontend/pipeline/pr-rc This commit looks good
Details
test-org/trust-module-frontend/pipeline/pr-rc This commit looks good
Details
parent
61c623b93d
commit
ef5df6971d
|
|
@ -256,12 +256,6 @@ const data = await metricsService.fetchMetricsRange(
|
||||||
source_id
|
source_id
|
||||||
}}
|
}}
|
||||||
ranges={ranges}
|
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 && (
|
{showLogs && (
|
||||||
<StatusLogTable logs={statusLogs} />
|
<StatusLogTable logs={statusLogs} />
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -2,10 +2,9 @@ import SystemStatusChart from "../../Charts/SystemStatusChart";
|
||||||
import TreeTable from "../UI/TreeTable";
|
import TreeTable from "../UI/TreeTable";
|
||||||
import FlowChart from "../TreeChart/FlowChart";
|
import FlowChart from "../TreeChart/FlowChart";
|
||||||
import { getStatusColor } from "../TreeChart/dataUtils";
|
import { getStatusColor } from "../TreeChart/dataUtils";
|
||||||
|
import MetricsAnalyzer from "./MetricsAnalyzer"; // Импортируем новый компонент
|
||||||
|
|
||||||
const TabContent = ({ activeTab, tabs, statusHistories, treeData1, tabContent, handleOpenTab }) => {
|
const TabContent = ({ activeTab, tabs, statusHistories, treeData1, tabContent, handleOpenTab }) => {
|
||||||
// Функция для подсчета количества элементов каждого статуса
|
|
||||||
const countStatuses = (data) => {
|
const countStatuses = (data) => {
|
||||||
const counts = { green: 0, yellow: 0, orange: 0, red: 0 };
|
const counts = { green: 0, yellow: 0, orange: 0, red: 0 };
|
||||||
|
|
||||||
|
|
@ -66,6 +65,9 @@ const TabContent = ({ activeTab, tabs, statusHistories, treeData1, tabContent, h
|
||||||
|
|
||||||
<label>Статус компонентов системы</label>
|
<label>Статус компонентов системы</label>
|
||||||
<TreeTable data={treeData1} />
|
<TreeTable data={treeData1} />
|
||||||
|
|
||||||
|
{/* Добавляем кнопку анализа
|
||||||
|
<MetricsAnalyzer />*/}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (activeTab === "Визуализация") {
|
} else if (activeTab === "Визуализация") {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue