[APM] Sanitize duration display issues w/ hidden root traces (#39207)

* [APM] Sanitize duration display issues w/ hidden root traces

Closes #35152.

This change make sure that if the parent transaction is not visible, and the top most visible transaction is async and longer than its parent:

- duration of trace is displayed as > 100% with a tooltip explaining _why_ this happens
- the x-axis highlight will use the duration of the topmost visible transaction rather than the parent

* Give trace label explanation a unique id

* Update tooltip label according to feedback

* Update x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/StickyTransactionProperties.tsx

Co-Authored-By: Casper Hübertz <casper@formgeist.com>
This commit is contained in:
Dario Gieselaar 2019-06-26 12:33:19 +02:00 committed by GitHub
parent 8c8ef33d36
commit 1483a6eeef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 26 deletions

View file

@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import { idx } from '@kbn/elastic-idx';
import { EuiToolTip } from '@elastic/eui';
import {
TRANSACTION_DURATION,
TRANSACTION_RESULT,
@ -79,7 +80,22 @@ export function StickyTransactionProperties({
defaultMessage: '% of trace'
}
),
val: asPercent(duration, totalDuration, NOT_AVAILABLE_LABEL),
val:
totalDuration !== undefined && duration > totalDuration ? (
<EuiToolTip
content={i18n.translate(
'xpack.apm.transactionDetails.percentOfTraceLabelExplanation',
{
defaultMessage:
'The % of trace exceeds 100% because this transaction takes longer than the root transaction.'
}
)}
>
<span>&gt;100%</span>
</EuiToolTip>
) : (
asPercent(duration, totalDuration, NOT_AVAILABLE_LABEL)
),
width: '25%'
},
{

View file

@ -136,7 +136,6 @@ export class Waterfall extends Component<Props> {
<Timeline
agentMarks={this.props.agentMarks}
duration={waterfall.duration}
traceRootDuration={waterfall.traceRootDuration}
height={waterfallHeight}
margins={TIMELINE_MARGINS}
/>

View file

@ -15,26 +15,26 @@ import { px } from '../../../../style/variables';
import { getTimeFormatter } from '../../../../utils/formatters';
import theme from '@elastic/eui/dist/eui_theme_light.json';
// Remove any tick that is too close to traceRootDuration
const getXAxisTickValues = (tickValues, traceRootDuration) => {
if (traceRootDuration == null) {
// Remove any tick that is too close to topTraceDuration
const getXAxisTickValues = (tickValues, topTraceDuration) => {
if (topTraceDuration == null) {
return tickValues;
}
const padding = (tickValues[1] - tickValues[0]) / 2;
const lowerBound = traceRootDuration - padding;
const upperBound = traceRootDuration + padding;
const lowerBound = topTraceDuration - padding;
const upperBound = topTraceDuration + padding;
return tickValues.filter(value => {
const isInRange = inRange(value, lowerBound, upperBound);
return !isInRange && value !== traceRootDuration;
return !isInRange && value !== topTraceDuration;
});
};
function TimelineAxis({ plotValues, agentMarks, traceRootDuration }) {
function TimelineAxis({ plotValues, agentMarks, topTraceDuration }) {
const { margins, tickValues, width, xDomain, xMax, xScale } = plotValues;
const tickFormat = getTimeFormatter(xMax);
const xAxisTickValues = getXAxisTickValues(tickValues, traceRootDuration);
const xAxisTickValues = getXAxisTickValues(tickValues, topTraceDuration);
return (
<Sticky disableCompensation>
@ -73,10 +73,10 @@ function TimelineAxis({ plotValues, agentMarks, traceRootDuration }) {
}}
/>
{traceRootDuration > 0 && (
{topTraceDuration > 0 && (
<LastTickValue
x={xScale(traceRootDuration)}
value={tickFormat(traceRootDuration)}
x={xScale(topTraceDuration)}
value={tickFormat(topTraceDuration)}
marginTop={28}
/>
)}

View file

@ -11,7 +11,7 @@ import theme from '@elastic/eui/dist/eui_theme_light.json';
class VerticalLines extends PureComponent {
render() {
const { traceRootDuration } = this.props;
const { topTraceDuration } = this.props;
const {
width,
height,
@ -47,9 +47,9 @@ class VerticalLines extends PureComponent {
style={{ stroke: theme.euiColorMediumShade }}
/>
{traceRootDuration > 0 && (
{topTraceDuration > 0 && (
<VerticalGridLines
tickValues={[traceRootDuration]}
tickValues={[topTraceDuration]}
style={{ stroke: theme.gray3euiColorMediumShade }}
/>
)}

View file

@ -14,14 +14,7 @@ import VerticalLines from './VerticalLines';
class Timeline extends PureComponent {
render() {
const {
width,
duration,
agentMarks,
traceRootDuration,
height,
margins
} = this.props;
const { width, duration, agentMarks, height, margins } = this.props;
if (duration == null || !width) {
return null;
}
@ -32,12 +25,12 @@ class Timeline extends PureComponent {
<TimelineAxis
plotValues={plotValues}
agentMarks={agentMarks}
traceRootDuration={traceRootDuration}
topTraceDuration={duration}
/>
<VerticalLines
plotValues={plotValues}
agentMarks={agentMarks}
traceRootDuration={traceRootDuration}
topTraceDuration={duration}
/>
</div>
);