mirror of https://github.com/linkerd/linkerd2.git
Tap web UI: Fix latency formatting (#1429)
* Nicely format tap latencies to be more readable * Various whitespace cleanups
This commit is contained in:
parent
f510d7ea08
commit
38c4b2937a
|
@ -50,7 +50,6 @@ class ErrorMessage extends React.Component {
|
|||
<div><b>Error:</b> {status} {statusText}</div>
|
||||
{ !error ? null : <div><b>Message:</b> {error}</div> }
|
||||
<div><b>URL:</b> {url}</div>
|
||||
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<div className="dismiss" onClick={this.hideMessage} role="presentation">Dismiss X</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import BaseTable from './BaseTable.jsx';
|
||||
import { formatLatency } from './util/Utils.js';
|
||||
import { formatLatencySec } from './util/Utils.js';
|
||||
import React from 'react';
|
||||
import { Col, Icon, Row } from 'antd';
|
||||
|
||||
|
@ -157,9 +157,8 @@ let tapColumns = filterOptions => [
|
|||
}
|
||||
];
|
||||
|
||||
let formatTapLatency = str => {
|
||||
let millis = parseFloat(str.replace("s", "")) * 1000;
|
||||
return formatLatency(millis);
|
||||
const formatTapLatency = str => {
|
||||
return formatLatencySec(str.replace("s", ""));
|
||||
};
|
||||
|
||||
// hide verbose information
|
||||
|
|
|
@ -5,7 +5,9 @@ import React from 'react';
|
|||
import 'whatwg-fetch';
|
||||
|
||||
const checkFetchOk = resp => {
|
||||
if (resp.ok) { return resp; }
|
||||
if (resp.ok) {
|
||||
return resp;
|
||||
}
|
||||
|
||||
return resp.json().then(error => {
|
||||
throw {
|
||||
|
@ -15,7 +17,6 @@ const checkFetchOk = resp => {
|
|||
error: error.error
|
||||
};
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// makeCancelable from @istarkov
|
||||
|
@ -115,7 +116,6 @@ const ApiHelpers = (pathPrefix, defaultMetricsWindow = '1m') => {
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
// prefix all links in the app with `pathPrefix`
|
||||
class PrefixedLink extends React.Component {
|
||||
static defaultProps = {
|
||||
|
|
|
@ -11,23 +11,37 @@ export const rowGutter = 3 * baseWidth;
|
|||
* Number formatters
|
||||
*/
|
||||
const successRateFormatter = d3.format(".2%");
|
||||
const latencySecFormatter = d3.format(".3f");
|
||||
const latencyFormatter = d3.format(",");
|
||||
|
||||
export const formatLatency = m => {
|
||||
export const formatLatencyMs = m => {
|
||||
if (_.isNil(m)) {
|
||||
return "---";
|
||||
} else if (m < 1000) {
|
||||
return `${latencyFormatter(m)} ms`;
|
||||
} else {
|
||||
return `${latencySecFormatter(m / 1000)} s`;
|
||||
return `${formatLatencySec(m / 1000)}`;
|
||||
}
|
||||
};
|
||||
|
||||
const niceLatency = l => latencyFormatter(Math.round(l));
|
||||
|
||||
export const formatLatencySec = latency => {
|
||||
let s = parseFloat(latency);
|
||||
if (_.isNil(s)) {
|
||||
return "---";
|
||||
} else if (s === parseFloat(0.0)) {
|
||||
return "0 s";
|
||||
} else if (s < 0.001) {
|
||||
return `${niceLatency(s * 1000 * 1000)} µs`;
|
||||
} else if (s < 1.0) {
|
||||
return `${niceLatency(s * 1000)} ms`;
|
||||
} else {
|
||||
return `${niceLatency(s)} s`;
|
||||
}
|
||||
};
|
||||
|
||||
export const metricToFormatter = {
|
||||
"REQUEST_RATE": m => _.isNil(m) ? "---" : styleNum(m, " RPS", true),
|
||||
"SUCCESS_RATE": m => _.isNil(m) ? "---" : successRateFormatter(m),
|
||||
"LATENCY": formatLatency,
|
||||
"LATENCY": formatLatencyMs,
|
||||
"UNTRUNCATED": m => styleNum(m, "", false)
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import { expect } from 'chai';
|
||||
import { metricToFormatter, styleNum, toClassName } from '../js/components/util/Utils.js';
|
||||
import {
|
||||
formatLatencySec,
|
||||
metricToFormatter,
|
||||
styleNum,
|
||||
toClassName
|
||||
} from '../js/components/util/Utils.js';
|
||||
|
||||
// introduce some binary floating point rounding errors, like ya do
|
||||
function float(num) {
|
||||
|
@ -74,9 +79,9 @@ describe('Utils', () => {
|
|||
});
|
||||
|
||||
it('formats latency greater than 1s as s', () => {
|
||||
expect(metricToFormatter["LATENCY"](1000)).to.equal('1.000 s');
|
||||
expect(metricToFormatter["LATENCY"](9999)).to.equal('9.999 s');
|
||||
expect(metricToFormatter["LATENCY"](99999)).to.equal('99.999 s');
|
||||
expect(metricToFormatter["LATENCY"](1000)).to.equal('1 s');
|
||||
expect(metricToFormatter["LATENCY"](9999)).to.equal('10 s');
|
||||
expect(metricToFormatter["LATENCY"](99999)).to.equal('100 s');
|
||||
});
|
||||
|
||||
it('formats success rate', () => {
|
||||
|
@ -86,6 +91,16 @@ describe('Utils', () => {
|
|||
expect(metricToFormatter["SUCCESS_RATE"](0.9999)).to.equal('99.99%');
|
||||
expect(metricToFormatter["SUCCESS_RATE"](4)).to.equal('400.00%');
|
||||
});
|
||||
|
||||
it('formats latencies expressed as seconds into a more appropriate display unit', () => {
|
||||
expect(formatLatencySec("0.002837700")).to.equal("3 ms");
|
||||
expect(formatLatencySec("0.000")).to.equal("0 s");
|
||||
expect(formatLatencySec("0.000000797")).to.equal("1 µs");
|
||||
expect(formatLatencySec("0.000231910")).to.equal("232 µs");
|
||||
expect(formatLatencySec("0.000988600")).to.equal("989 µs");
|
||||
expect(formatLatencySec("0.005598200")).to.equal("6 ms");
|
||||
expect(formatLatencySec("3.029409200")).to.equal("3 s");
|
||||
});
|
||||
});
|
||||
|
||||
describe('toClassName', () => {
|
||||
|
|
Loading…
Reference in New Issue