Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[APM] Hoist loading of waterfall and flatten it #24651

Merged
merged 10 commits into from
Oct 31, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
} from '../../../../style/variables';
import { get, capitalize, isEmpty } from 'lodash';
import { STATUS } from '../../../../constants';

import { StickyProperties } from '../../../shared/StickyProperties';
import { Tab, HeaderMedium } from '../../../shared/UIComponents';
import DiscoverButton from '../../../shared/DiscoverButton';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import { connect } from 'react-redux';
import { IReduxState } from '../../../store/rootReducer';
// @ts-ignore
import { getUrlParams } from '../../../store/urlParams';
import { TraceOverview as View } from './view';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { EuiCallOut, EuiLink, EuiSpacer, EuiText } from '@elastic/eui';
import React from 'react';
import { RRRRenderArgs } from 'react-redux-request';
import { RRRRenderResponse } from 'react-redux-request';
import { ITransactionGroup } from '../../../../typings/TransactionGroup';
// @ts-ignore
import { TraceListRequest } from '../../../store/reactReduxRequest/traceList';
Expand Down Expand Up @@ -37,7 +37,7 @@ export function TraceOverview(props: Props) {
<EuiSpacer />
<TraceListRequest
urlParams={urlParams}
render={({ data, status }: RRRRenderArgs<ITransactionGroup[]>) => (
render={({ data, status }: RRRRenderResponse<ITransactionGroup[]>) => (
<TraceList
items={data}
isLoading={status === 'LOADING'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

import { get } from 'lodash';
import React from 'react';
import { connect } from 'react-redux';
import { selectWaterfallRoot } from 'x-pack/plugins/apm/public/store/selectors/waterfall';
import {
REQUEST_URL_FULL,
TRANSACTION_DURATION,
Expand All @@ -17,35 +15,33 @@ import {
import { Transaction } from '../../../../../typings/Transaction';
// @ts-ignore
import { asTime } from '../../../../utils/formatters';
// @ts-ignore
import {
IStickyProperty,
StickyProperties
} from '../../../shared/StickyProperties';

function getDurationPercent(
transactionDuration: number,
rootDuration?: number
totalDuration?: number
) {
if (rootDuration === undefined || rootDuration === 0) {
if (!totalDuration) {
return '';
}
return ((transactionDuration / rootDuration) * 100).toFixed(2) + '%';
return ((transactionDuration / totalDuration) * 100).toFixed(2) + '%';
}

interface Props {
transaction: Transaction;
root?: Transaction;
totalDuration?: number;
}

export function StickyTransactionPropertiesComponent({
export function StickyTransactionProperties({
transaction,
root
totalDuration
}: Props) {
const timestamp = get(transaction, '@timestamp');
const timestamp = transaction['@timestamp'];
const url = get(transaction, REQUEST_URL_FULL, 'N/A');
const duration = transaction.transaction.duration.us;
const rootDuration = root && root.transaction.duration.us;
const stickyProperties: IStickyProperty[] = [
{
label: 'Timestamp',
Expand All @@ -69,7 +65,7 @@ export function StickyTransactionPropertiesComponent({
},
{
label: '% of trace',
val: getDurationPercent(duration, rootDuration),
val: getDurationPercent(duration, totalDuration),
width: '25%'
},
{
Expand All @@ -89,11 +85,3 @@ export function StickyTransactionPropertiesComponent({

return <StickyProperties stickyProperties={stickyProperties} />;
}

const mapStateToProps = (state: any, props: Partial<Props>) => ({
root: selectWaterfallRoot(state, props)
});

export const StickyTransactionProperties = connect<{}, {}, Props>(
mapStateToProps
)(StickyTransactionPropertiesComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
PropertiesTable
} from '../../../shared/PropertiesTable';
import { WaterfallContainer } from './WaterfallContainer';
import { IWaterfall } from './WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';

const TableContainer = styled.div`
padding: ${px(units.plus)} ${px(units.plus)} 0;
Expand All @@ -44,11 +45,15 @@ interface TransactionPropertiesTableProps {
location: any;
transaction: Transaction;
urlParams: IUrlParams;
waterfall: IWaterfall;
}

export const TransactionPropertiesTable: React.SFC<
TransactionPropertiesTableProps
> = ({ location, transaction, urlParams }) => {
export function TransactionPropertiesTable({
location,
transaction,
urlParams,
waterfall
}: TransactionPropertiesTableProps) {
const tabs = getTabs(transaction);
const currentTab = getCurrentTab(tabs, urlParams.detailTab);
const agentName = transaction.context.service.agent.name;
Expand Down Expand Up @@ -84,6 +89,7 @@ export const TransactionPropertiesTable: React.SFC<
transaction={transaction}
location={location}
urlParams={urlParams}
waterfall={waterfall}
/>
)}

Expand All @@ -98,4 +104,4 @@ export const TransactionPropertiesTable: React.SFC<
)}
</div>
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiTitle } from '@elastic/eui';
import React from 'react';
import styled from 'styled-components';
import { px, unit } from '../../../../../style/variables';
Expand All @@ -13,7 +14,7 @@ import Legend from '../../../../shared/charts/Legend';
const Legends = styled.div`
display: flex;

div {
> * {
margin-right: ${px(unit)};
&:last-child {
margin-right: 0;
Expand All @@ -30,6 +31,9 @@ interface Props {
export function ServiceLegends({ serviceColors }: Props) {
return (
<Legends>
<EuiTitle size="xxxs">
<span>Services</span>
</EuiTitle>
{Object.entries(serviceColors).map(([label, color]) => (
<Legend key={color} color={color} text={label} />
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ import {
SERVICE_NAME,
TRANSACTION_NAME
} from 'x-pack/plugins/apm/common/constants';
// @ts-ignore
import { StickyProperties } from 'x-pack/plugins/apm/public/components/shared/StickyProperties';
import { TransactionLink } from 'x-pack/plugins/apm/public/components/shared/TransactionLink';
import { KibanaLink } from 'x-pack/plugins/apm/public/utils/url';
import { Transaction } from 'x-pack/plugins/apm/typings/Transaction';

interface Props {
transaction: Transaction;
transaction?: Transaction;
}

export function FlyoutTopLevelProperties({ transaction }: Props) {
if (!transaction) {
return null;
}

const stickyProperties = [
{
label: 'Service',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { first } from 'lodash';
import { Span } from '../../../../../../../../typings/Span';
// @ts-ignore
import { asMillis } from '../../../../../../../utils/formatters';
// @ts-ignore
import { StickyProperties } from '../../../../../../shared/StickyProperties';

function getSpanLabel(type: string) {
Expand All @@ -32,10 +31,14 @@ function getPrimaryType(type: string) {

interface Props {
span: Span;
totalDuration: number;
totalDuration?: number;
}

export function StickySpanProperties({ span, totalDuration }: Props) {
if (!totalDuration) {
return null;
}

const spanName = span.span.name;
const spanDuration = span.span.duration.us;
const relativeDuration = spanDuration / totalDuration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ function getDiscoverQuery(span: Span) {

interface Props {
span?: Span;
parentTransaction: Transaction;
totalDuration: number;
parentTransaction?: Transaction;
totalDuration?: number;
onClose: () => void;
}

Expand All @@ -70,7 +70,7 @@ export function SpanFlyout({
return null;
}
const stackframes = span.span.stacktrace;
const codeLanguage = get(span, SERVICE_LANGUAGE_NAME);
const codeLanguage: string = get(span, SERVICE_LANGUAGE_NAME);
const dbContext = span.context.db;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ export function TransactionFlyout({
<EuiFlyoutBody>
<FlyoutTopLevelProperties transaction={transactionDoc} />
<EuiHorizontalRule />
<StickyTransactionProperties transaction={transactionDoc} />
<StickyTransactionProperties
transaction={transactionDoc}
totalDuration={waterfall.traceRootDuration}
/>
<EuiHorizontalRule />
<TransactionPropertiesTableForFlyout
transaction={transactionDoc}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ interface ITimelineMargins {

interface IWaterfallItemProps {
timelineMargins: ITimelineMargins;
totalDuration: number;
totalDuration?: number;
item: IWaterfallItem;
color: string;
isSelected: boolean;
Expand All @@ -111,8 +111,12 @@ export function WaterfallItem({
isSelected,
onClick
}: IWaterfallItemProps) {
if (!totalDuration) {
return null;
}

const width = (item.duration / totalDuration) * 100;
const left = (item.offset / totalDuration) * 100;
const left = ((item.offset + item.skew) / totalDuration) * 100;
const Label = item.docType === 'transaction' ? TransactionLabel : SpanLabel;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Component, Fragment } from 'react';
import React, { Component } from 'react';
// @ts-ignore
import { StickyContainer } from 'react-sticky';
import styled from 'styled-components';
Expand Down Expand Up @@ -62,26 +62,19 @@ export class Waterfall extends Component<Props> {
});
};

public renderWaterfall = (item?: IWaterfallItem) => {
if (!item) {
return null;
}

public getWaterfallItem = (item: IWaterfallItem) => {
const { serviceColors, waterfall, urlParams }: Props = this.props;

return (
<Fragment key={item.id}>
<WaterfallItem
timelineMargins={TIMELINE_MARGINS}
color={serviceColors[item.serviceName]}
item={item}
totalDuration={waterfall.duration}
isSelected={item.id === urlParams.waterfallItemId}
onClick={() => this.onOpenFlyout(item)}
/>

{item.children && item.children.map(this.renderWaterfall)}
</Fragment>
<WaterfallItem
key={item.id}
timelineMargins={TIMELINE_MARGINS}
color={serviceColors[item.serviceName]}
item={item}
totalDuration={waterfall.duration}
isSelected={item.id === urlParams.waterfallItemId}
onClick={() => this.onOpenFlyout(item)}
/>
);
};

Expand All @@ -98,11 +91,15 @@ export class Waterfall extends Component<Props> {

switch (currentItem.docType) {
case 'span':
const parentTransaction = waterfall.getTransactionById(
currentItem.parentId
);

return (
<SpanFlyout
totalDuration={waterfall.duration}
span={currentItem.span}
parentTransaction={currentItem.parentTransaction}
parentTransaction={parentTransaction}
onClose={this.onCloseFlyout}
/>
);
Expand All @@ -124,7 +121,7 @@ export class Waterfall extends Component<Props> {
public render() {
const { waterfall } = this.props;
const itemContainerHeight = 58; // TODO: This is a nasty way to calculate the height of the svg element. A better approach should be found
const waterfallHeight = itemContainerHeight * waterfall.childrenCount;
const waterfallHeight = itemContainerHeight * waterfall.items.length;

return (
<Container>
Expand All @@ -140,7 +137,7 @@ export class Waterfall extends Component<Props> {
paddingTop: TIMELINE_MARGINS.top
}}
>
{this.renderWaterfall(waterfall.root)}
{waterfall.items.map(this.getWaterfallItem)}
</div>
</StickyContainer>

Expand Down
Loading