fixed bugs
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
32ece2f0ff
commit
a24b89220c
|
|
@ -43,9 +43,12 @@ const PrometheusChart = ({ metricName }) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const setupWebSocket = useCallback(() => {
|
const setupWebSocket = useCallback(() => {
|
||||||
if (socketRef.current?.connected) return socketRef.current;
|
if (socketRef.current) {
|
||||||
|
// Если соединение уже существует, возвращаем его
|
||||||
if (socketRef.current) socketRef.current.disconnect();
|
if (socketRef.current.connected) return socketRef.current;
|
||||||
|
// Если соединение в процессе переподключения, тоже возвращаем
|
||||||
|
if (socketRef.current.reconnecting) return socketRef.current;
|
||||||
|
}
|
||||||
|
|
||||||
const socket = io('http://192.168.2.39:3000/metrics-ws', {
|
const socket = io('http://192.168.2.39:3000/metrics-ws', {
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
|
|
@ -97,104 +100,73 @@ const PrometheusChart = ({ metricName }) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const fetchData = useCallback(() => {
|
const fetchData = useCallback(() => {
|
||||||
try {
|
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
let start = useCustomRange
|
const start = now - selectedRange.value;
|
||||||
? Math.floor(startDate.getTime() / 1000)
|
const end = now;
|
||||||
: now - selectedRange.value;
|
|
||||||
let end = useCustomRange
|
|
||||||
? Math.floor(endDate.getTime() / 1000)
|
|
||||||
: now;
|
|
||||||
|
|
||||||
if (start >= end) {
|
|
||||||
console.error('Invalid time range: start >= end');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const step = calculateStep(start, end);
|
const step = calculateStep(start, end);
|
||||||
console.log(`Fetching data for ${metricName}`, { start, end, step });
|
|
||||||
|
|
||||||
if (socketRef.current?.connected) {
|
if (socketRef.current?.connected) {
|
||||||
socketRef.current.emit('get-metrics', {
|
socketRef.current.emit('get-metrics', {
|
||||||
metric: metricName,
|
metric: metricName,
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
step
|
step,
|
||||||
|
_t: Date.now() // Добавляем timestamp для уникальности
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
console.error('WebSocket is not connected');
|
|
||||||
setupWebSocket();
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
}, [metricName, selectedRange.value]); // Только необходимые зависимости
|
||||||
console.error('Error in fetchData:', error);
|
|
||||||
}
|
|
||||||
}, [metricName, selectedRange, useCustomRange, startDate, endDate, calculateStep, setupWebSocket]);
|
|
||||||
|
|
||||||
const processMetricsData = useCallback((response) => {
|
const groupBySecond = (points) => {
|
||||||
const { metric, data } = response;
|
|
||||||
if (metric !== metricName) return;
|
|
||||||
|
|
||||||
if (!Array.isArray(data)) {
|
|
||||||
console.error('Invalid data format:', data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Processing metrics data:', data);
|
|
||||||
|
|
||||||
const now = Math.floor(Date.now() / 1000);
|
|
||||||
const rangeSeconds = useCustomRange
|
|
||||||
? Math.floor(endDate.getTime() / 1000) - Math.floor(startDate.getTime() / 1000)
|
|
||||||
: selectedRange.value;
|
|
||||||
|
|
||||||
const instancesData = {};
|
|
||||||
|
|
||||||
data.forEach(item => {
|
|
||||||
const instance = item.instance || 'default';
|
|
||||||
const timestamp = item.timestamp;
|
|
||||||
const value = parseFloat(item.value);
|
|
||||||
|
|
||||||
if (!instancesData[instance]) {
|
|
||||||
instancesData[instance] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatted = formatTime(timestamp, rangeSeconds);
|
|
||||||
instancesData[instance].push({
|
|
||||||
time: formatted.display, // для отображения
|
|
||||||
value: value,
|
|
||||||
timestamp: timestamp, // для сортировки
|
|
||||||
originalTime: formatted // для группировки
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Группируем точки с одинаковым временем (в пределах секунды)
|
|
||||||
Object.keys(instancesData).forEach(instance => {
|
|
||||||
const grouped = [];
|
const grouped = [];
|
||||||
const timeMap = {};
|
const timeMap = {};
|
||||||
|
|
||||||
instancesData[instance].forEach(point => {
|
points.forEach(point => {
|
||||||
const timeKey = Math.floor(point.timestamp / 1000); // группируем по секундам
|
const timeKey = Math.floor(point.timestamp / 1000);
|
||||||
if (!timeMap[timeKey]) {
|
if (!timeMap[timeKey]) {
|
||||||
timeMap[timeKey] = {
|
timeMap[timeKey] = { ...point, count: 1 };
|
||||||
...point,
|
|
||||||
count: 1
|
|
||||||
};
|
|
||||||
grouped.push(timeMap[timeKey]);
|
grouped.push(timeMap[timeKey]);
|
||||||
} else {
|
} else {
|
||||||
// Усредняем значения для точек в одну секунду
|
|
||||||
timeMap[timeKey].value = (timeMap[timeKey].value * timeMap[timeKey].count + point.value) /
|
timeMap[timeKey].value = (timeMap[timeKey].value * timeMap[timeKey].count + point.value) /
|
||||||
(timeMap[timeKey].count + 1);
|
(timeMap[timeKey].count + 1);
|
||||||
timeMap[timeKey].count += 1;
|
timeMap[timeKey].count += 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
instancesData[instance] = grouped.sort((a, b) => a.timestamp - b.timestamp);
|
return grouped;
|
||||||
|
};
|
||||||
|
|
||||||
|
const processMetricsData = useCallback((response) => {
|
||||||
|
if (response.metric !== metricName || !Array.isArray(response.data)) return;
|
||||||
|
|
||||||
|
setChartData(prev => {
|
||||||
|
const newData = { ...(prev || {}) };
|
||||||
|
|
||||||
|
// Добавление новых точек
|
||||||
|
response.data.forEach(item => {
|
||||||
|
const instance = item.instance || 'default';
|
||||||
|
if (!newData[instance]) newData[instance] = [];
|
||||||
|
|
||||||
|
if (!newData[instance].some(p => p.timestamp === item.timestamp)) {
|
||||||
|
newData[instance].push({
|
||||||
|
time: formatTime(item.timestamp, selectedRange.value).display,
|
||||||
|
value: parseFloat(item.value),
|
||||||
|
timestamp: item.timestamp
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Processed chart data:', instancesData);
|
// Группировка и ограничение
|
||||||
setChartData(instancesData);
|
Object.keys(newData).forEach(instance => {
|
||||||
setSelectedGraphRange(null);
|
newData[instance] = groupBySecond(newData[instance])
|
||||||
setFilteredData(null);
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
}, [metricName, formatTime, useCustomRange, startDate, endDate, selectedRange.value]);
|
.slice(-1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
return Object.keys(newData).length ? newData : prev;
|
||||||
|
});
|
||||||
|
}, [metricName, selectedRange.value, formatTime]);
|
||||||
|
|
||||||
|
|
||||||
const handleRangeChange = useCallback((event) => {
|
const handleRangeChange = useCallback((event) => {
|
||||||
const selectedValue = event.target.value;
|
const selectedValue = event.target.value;
|
||||||
const range = TIME_RANGES.find(r => r.value === parseInt(selectedValue, 10));
|
const range = TIME_RANGES.find(r => r.value === parseInt(selectedValue, 10));
|
||||||
|
|
@ -234,14 +206,26 @@ const PrometheusChart = ({ metricName }) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!socketRef.current?.connected) return;
|
if (!socketRef.current?.connected) return;
|
||||||
|
|
||||||
|
const fetchDataWrapper = () => {
|
||||||
|
try {
|
||||||
|
fetchData();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error in interval fetch:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Сразу запросить данные
|
||||||
|
fetchDataWrapper();
|
||||||
|
|
||||||
|
// Установить интервал
|
||||||
|
intervalRef.current = setInterval(fetchDataWrapper, selectedRange.interval);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (intervalRef.current) {
|
||||||
clearInterval(intervalRef.current);
|
clearInterval(intervalRef.current);
|
||||||
fetchData();
|
intervalRef.current = null;
|
||||||
|
}
|
||||||
intervalRef.current = setInterval(() => {
|
};
|
||||||
fetchData();
|
|
||||||
}, selectedRange.interval);
|
|
||||||
|
|
||||||
return () => clearInterval(intervalRef.current);
|
|
||||||
}, [fetchData, selectedRange.interval]);
|
}, [fetchData, selectedRange.interval]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue