156 lines
5.8 KiB
JavaScript
156 lines
5.8 KiB
JavaScript
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(`/api/metrics/all-values`);
|
|
setMetrics(metricsResponse.data);
|
|
|
|
// 2. Преобразуем и отправляем на анализ
|
|
const requestData = transformMetricsForAnalysis(metricsResponse.data);
|
|
const analysisResponse = await axios.get(`: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; |