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) => ( - - -
-
{metric.name}
-
- - {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 })