import { friendlyTitle, metricToFormatter } from './util/Utils.js'; import BaseTable from './BaseTable.jsx'; import ErrorModal from './ErrorModal.jsx'; import GrafanaLink from './GrafanaLink.jsx'; import Grid from '@material-ui/core/Grid'; import PropTypes from 'prop-types'; import React from 'react'; import SuccessRateMiniChart from './util/SuccessRateMiniChart.jsx'; import _ from 'lodash'; import { processedMetricsPropType } from './util/MetricUtils.jsx'; import { withContext } from './util/AppContext.jsx'; const columnDefinitions = (resource, showNamespaceColumn, PrefixedLink) => { let isAuthorityTable = resource === "authority"; let nsColumn = [ { title: "Namespace", key: "namespace", isNumeric: false, render: d => !d.namespace ? "---" : {d.namespace} } ]; let meshedColumn = { title: "Meshed", key: "meshed", isNumeric: true, render: d => !d.pods ? null : d.pods.meshedPods + "/" + d.pods.totalPods }; let columns = [ { title: friendlyTitle(resource).singular, key: "resource-title", isNumeric: false, render: d => { let nameContents; if (resource === "namespace") { nameContents = {d.name}; } else if (!d.added || isAuthorityTable) { nameContents = d.name; } else { nameContents = ( {d.name} ); } return ( {nameContents} { _.isEmpty(d.errors) ? null : } ); } }, { title: "Success Rate", key: "success-rate", isNumeric: true, render: d => }, { title: "Request Rate", key: "request-rate", isNumeric: true, render: d => metricToFormatter["NO_UNIT"](d.requestRate) }, { title: "P50 Latency", key: "p50_latency", isNumeric: true, render: d => metricToFormatter["LATENCY"](d.P50) }, { title: "P95 Latency", key: "p95_latency", isNumeric: true, render: d => metricToFormatter["LATENCY"](d.P95) }, { title: "P99 Latency", key: "p99_latency", isNumeric: true, render: d => metricToFormatter["LATENCY"](d.P99) }, { title: "TLS", key: "has_tls", isNumeric: true, render: d => _.isNil(d.tlsRequestPercent) || d.tlsRequestPercent.get() === -1 ? "---" : d.tlsRequestPercent.prettyRate() }, { title: "Grafana Dashboard", key: "grafanaDashboard", isNumeric: true, render: row => { if (!isAuthorityTable && (!row.added || _.get(row, "pods.totalPods") === "0") ) { return null; } return ( ); } } ]; // don't add the meshed column on a Authority MetricsTable if (!isAuthorityTable) { columns.splice(1, 0, meshedColumn); } if (!showNamespaceColumn) { return columns; } else { return _.concat(nsColumn, columns); } }; const preprocessMetrics = metrics => { let tableData = _.cloneDeep(metrics); _.each(tableData, datum => { _.each(datum.latency, (value, quantile) => { datum[quantile] = value; }); }); return tableData; }; class MetricsTable extends React.Component { static propTypes = { api: PropTypes.shape({ PrefixedLink: PropTypes.func.isRequired, }).isRequired, metrics: PropTypes.arrayOf(processedMetricsPropType), resource: PropTypes.string.isRequired, showNamespaceColumn: PropTypes.bool }; static defaultProps = { showNamespaceColumn: true, metrics: [] }; render() { const { metrics, resource, showNamespaceColumn, api } = this.props; let showNsColumn = resource === "namespace" ? false : showNamespaceColumn; let columns = columnDefinitions(resource, showNsColumn, api.PrefixedLink); let rows = preprocessMetrics(metrics); return ( ); } } export default withContext(MetricsTable);