diff --git a/frontend/src/pages/sys-admin/statistic/statistic-metrics.js b/frontend/src/pages/sys-admin/statistic/statistic-metrics.js
index c6b613f24f..6922c96595 100644
--- a/frontend/src/pages/sys-admin/statistic/statistic-metrics.js
+++ b/frontend/src/pages/sys-admin/statistic/statistic-metrics.js
@@ -4,11 +4,34 @@ import { systemAdminAPI } from '../../../utils/system-admin-api';
import MainPanelTopbar from '../main-panel-topbar';
import StatisticNav from './statistic-nav';
import { gettext } from '../../../utils/constants';
+import { Tooltip } from 'reactstrap';
class ComponentMetricsTable extends Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ hoveredRow: null,
+ tooltipOpen: null
+ };
+ }
+
+ toggleTooltip = (id) => {
+ this.setState(prevState => ({
+ tooltipOpen: prevState.tooltipOpen === id ? null : id
+ }));
+ };
+
+ handleRowHover = (id) => {
+ this.setState({ hoveredRow: id });
+ };
+
+ handleRowLeave = () => {
+ this.setState({ hoveredRow: null });
+ };
+
render() {
const { componentName, metrics } = this.props;
-
+ const { hoveredRow, tooltipOpen } = this.state;
return (
<>
@@ -19,22 +42,55 @@ class ComponentMetricsTable extends Component {
{metrics.map((metric) => (
- metric.data_points.map((point, pointIndex) => (
-
-
-
- |
- {point.labels.node} |
- {point.value} |
-
-
- {dayjs(point.labels.collected_at).format('YYYY-MM-DD HH:mm:ss')}
-
- |
-
- ))
+ metric.data_points.map((point, pointIndex) => {
+ const rowId = `${metric.name}-${point.labels.node}-${pointIndex}`;
+ return (
+
+ this.handleRowHover(rowId)}
+ onMouseLeave={this.handleRowLeave}
+ >
+
+
+ {metric.name.substring(metric.name.indexOf('_') + 1)}
+ {metric.help && (
+ <>
+
+
+ this.toggleTooltip(rowId)}
+ target={rowId}
+ delay={{ show: 200, hide: 0 }}
+ fade={true}
+ className="metric-tooltip"
+ hideArrow={true}
+ >
+ {metric.help}
+
+ >
+ )}
+
+
+ |
+ {point.labels.node} |
+ {point.value} |
+
+
+ {dayjs(point.labels.collected_at).format('YYYY-MM-DD HH:mm:ss')}
+
+ |
+
+ );
+ })
))}
>
);
@@ -227,6 +283,15 @@ const style = `
color: #666;
font-size: 14px;
}
+
+ .sf3-font-help {
+ font-size: 14px;
+ color: #666;
+ margin-left: 4px;
+ opacity: 0.7;
+ transition: opacity 0.2s;
+
+ }
`;
diff --git a/seahub/api2/endpoints/admin/statistics.py b/seahub/api2/endpoints/admin/statistics.py
index fae5a32800..cb9f385906 100644
--- a/seahub/api2/endpoints/admin/statistics.py
+++ b/seahub/api2/endpoints/admin/statistics.py
@@ -487,16 +487,14 @@ def parse_prometheus_metrics(metrics_raw):
"""
Ensure metric entry exists in formatted metrics dict
"""
- formatted_name = '_'.join(raw_name.split('_')[1:])
- if formatted_name not in formatted_metrics_dict:
- formatted_metrics_dict[formatted_name] = {
- 'name': formatted_name,
+ if raw_name not in formatted_metrics_dict:
+ formatted_metrics_dict[raw_name] = {
+ 'name': raw_name,
'help': '',
'type': '',
- 'data_points': [],
- 'original_name': raw_name
+ 'data_points': []
}
- return formatted_name
+ return raw_name
def parse_labels(line):
"""
@@ -535,23 +533,23 @@ def parse_prometheus_metrics(metrics_raw):
parts = line.split(' ', 3)
if len(parts) > 3:
metric_name, help_text = parts[2], parts[3]
- formatted_name = ensure_metric_exists(metric_name)
- formatted_metrics_dict[formatted_name]['help'] = help_text
+ ensure_metric_exists(metric_name)
+ formatted_metrics_dict[metric_name]['help'] = help_text
elif line.startswith('# TYPE'):
parts = line.split(' ')
if len(parts) > 3:
metric_name, metric_type = parts[2], parts[3]
- formatted_name = ensure_metric_exists(metric_name)
- formatted_metrics_dict[formatted_name]['type'] = metric_type
+ ensure_metric_exists(metric_name)
+ formatted_metrics_dict[metric_name]['type'] = metric_type
elif not line.startswith('#'):
# handle metric data
parsed_data = parse_metric_line(line)
if parsed_data:
metric_name, labels, value = parsed_data
- formatted_name = ensure_metric_exists(metric_name)
- formatted_metrics_dict[formatted_name]['data_points'].append({
+ ensure_metric_exists(metric_name)
+ formatted_metrics_dict[metric_name]['data_points'].append({
'labels': labels,
'value': value
})