mirror of https://github.com/linkerd/linkerd2.git
174 lines
4.6 KiB
JavaScript
174 lines
4.6 KiB
JavaScript
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 ? "---" : <PrefixedLink to={"/namespaces/" + d.namespace}>{d.namespace}</PrefixedLink>
|
|
}
|
|
];
|
|
|
|
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 = <PrefixedLink to={"/namespaces/" + d.name}>{d.name}</PrefixedLink>;
|
|
} else if (!d.added || isAuthorityTable) {
|
|
nameContents = d.name;
|
|
} else {
|
|
nameContents = (
|
|
<PrefixedLink to={"/namespaces/" + d.namespace + "/" + resource + "s/" + d.name}>
|
|
{d.name}
|
|
</PrefixedLink>
|
|
);
|
|
}
|
|
return (
|
|
<Grid container alignItems="center" spacing={8}>
|
|
<Grid item>{nameContents}</Grid>
|
|
{ _.isEmpty(d.errors) ? null :
|
|
<Grid item><ErrorModal errors={d.errors} resourceName={d.name} resourceType={resource} /></Grid>}
|
|
</Grid>
|
|
);
|
|
}
|
|
},
|
|
{
|
|
title: "Success Rate",
|
|
key: "success-rate",
|
|
isNumeric: true,
|
|
render: d => <SuccessRateMiniChart sr={d.successRate} />
|
|
},
|
|
{
|
|
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 (
|
|
<GrafanaLink
|
|
name={row.name}
|
|
namespace={row.namespace}
|
|
resource={resource}
|
|
PrefixedLink={PrefixedLink} />
|
|
);
|
|
}
|
|
}
|
|
];
|
|
|
|
// 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 (
|
|
<BaseTable
|
|
tableRows={rows}
|
|
tableColumns={columns}
|
|
tableClassName="metric-table"
|
|
padding="dense" />
|
|
);
|
|
}
|
|
}
|
|
|
|
export default withContext(MetricsTable);
|