Skip to content

Commit

Permalink
[APM] closes elastic#29563 by rendering related errors link with erro…
Browse files Browse the repository at this point in the history
…r count in transaction flyout
  • Loading branch information
ogupte committed Feb 8, 2019
1 parent 37b5ba9 commit deb8e2b
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export function TransactionFlyout({
return null;
}

const waterfallItem = waterfall.itemsById[transactionDoc.transaction.id];

return (
<EuiPortal>
<ResponsiveFlyout onClose={onClose} ownFocus={true} maxWidth={false}>
Expand Down Expand Up @@ -134,6 +136,11 @@ export function TransactionFlyout({
<FlyoutTopLevelProperties transaction={transactionDoc} />
<EuiHorizontalRule />
<StickyTransactionProperties
errorCount={
waterfallItem.docType === 'transaction'
? waterfallItem.errorCount
: undefined
}
transaction={transactionDoc}
totalDuration={waterfall.traceRootDuration}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Array [
],
"docType": "transaction",
"duration": 9480,
"errorCount": 0,
"id": "a",
"name": "APIRestController#products",
"offset": 0,
Expand Down Expand Up @@ -83,6 +84,7 @@ Array [
],
"docType": "transaction",
"duration": 3581,
"errorCount": 0,
"id": "c",
"name": "APIRestController#productsRemote",
"offset": 3000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ describe('waterfall_helpers', () => {
offset: 0,
skew: 0,
docType: 'transaction',
transaction: {} as Transaction
transaction: {} as Transaction,
errorCount: 0
},
{
id: 'a',
Expand All @@ -86,7 +87,8 @@ describe('waterfall_helpers', () => {
offset: 0,
skew: 0,
docType: 'transaction',
transaction: {} as Transaction
transaction: {} as Transaction,
errorCount: 0
}
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
uniq,
zipObject
} from 'lodash';
import { TraceAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_trace';
import { StringMap } from 'x-pack/plugins/apm/typings/common';
import { Span } from '../../../../../../../../typings/es_schemas/Span';
import { Transaction } from '../../../../../../../../typings/es_schemas/Transaction';
Expand Down Expand Up @@ -73,6 +74,7 @@ interface IWaterfallItemBase {
interface IWaterfallItemTransaction extends IWaterfallItemBase {
transaction: Transaction;
docType: 'transaction';
errorCount: number;
}

interface IWaterfallItemSpan extends IWaterfallItemBase {
Expand All @@ -83,7 +85,8 @@ interface IWaterfallItemSpan extends IWaterfallItemBase {
export type IWaterfallItem = IWaterfallItemSpan | IWaterfallItemTransaction;

function getTransactionItem(
transaction: Transaction
transaction: Transaction,
transactionErrorCounts: TraceAPIResponse['transactionErrorCounts']
): IWaterfallItemTransaction {
return {
id: transaction.transaction.id,
Expand All @@ -95,7 +98,8 @@ function getTransactionItem(
offset: 0,
skew: 0,
docType: 'transaction',
transaction
transaction,
errorCount: transactionErrorCounts[transaction.transaction.id] || 0
};
}

Expand Down Expand Up @@ -230,8 +234,9 @@ function createGetTransactionById(itemsById: IWaterfallIndex) {
}

export function getWaterfall(
hits: Array<Span | Transaction>,
entryTransaction: Transaction
hits: TraceAPIResponse['trace'],
entryTransaction: Transaction,
transactionErrorCounts: TraceAPIResponse['transactionErrorCounts']
): IWaterfall {
if (isEmpty(hits)) {
return {
Expand All @@ -255,7 +260,7 @@ export function getWaterfall(
case 'span':
return getSpanItem(hit as Span);
case 'transaction':
return getTransactionItem(hit as Transaction);
return getTransactionItem(hit as Transaction, transactionErrorCounts);
default:
throw new Error(`Unknown type ${docType}`);
}
Expand All @@ -264,7 +269,10 @@ export function getWaterfall(
const childrenByParentId = groupBy(filteredHits, hit =>
hit.parentId ? hit.parentId : 'root'
);
const entryTransactionItem = getTransactionItem(entryTransaction);
const entryTransactionItem = getTransactionItem(
entryTransaction,
transactionErrorCounts
);
const itemsById: IWaterfallIndex = indexBy(filteredHits, 'id');
const items = getWaterfallItems(childrenByParentId, entryTransactionItem);
const traceRoot = getTraceRoot(childrenByParentId);
Expand Down
12 changes: 10 additions & 2 deletions x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,16 @@ export function WaterfallRequest({ urlParams, transaction, render }: Props) {
id={ID}
fn={loadTrace}
args={[{ traceId, start, end }]}
render={({ args, data = [], status }) => {
const waterfall = getWaterfall(data, transaction);
render={({
args,
data = { trace: [], transactionErrorCounts: {} },
status
}) => {
const waterfall = getWaterfall(
data.trace,
transaction,
data.transactionErrorCounts
);
return render({ args, data: waterfall, status });
}}
/>
Expand Down
62 changes: 59 additions & 3 deletions x-pack/plugins/apm/server/lib/traces/get_trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,27 @@ import { Span } from '../../../typings/es_schemas/Span';
import { Transaction } from '../../../typings/es_schemas/Transaction';
import { Setup } from '../helpers/setup_request';

export type TraceAPIResponse = Array<Transaction | Span>;
export interface TransactionErrorCounts {
[transactionId: string]: number;
}
export type TraceItems = Array<Transaction | Span>;
export interface TraceAPIResponse {
trace: TraceItems;
transactionErrorCounts: TransactionErrorCounts;
}

interface TraceErrorsAggregationBucket {
key: string;
errors: {
doc_count: number;
};
}

interface TraceAggregationResponse {
transactions: {
buckets: TraceErrorsAggregationBucket[];
};
}

export async function getTrace(
traceId: string,
Expand All @@ -37,10 +57,46 @@ export async function getTrace(
}
]
}
},
aggs: {
transactions: {
terms: {
field: 'transaction.id'
},
aggs: {
errors: {
filter: {
term: {
'processor.event': 'error'
}
}
}
}
}
}
}
};

const resp = await client<Span | Transaction>('search', params);
return resp.hits.hits.map(hit => hit._source);
const resp = await client<Span | Transaction, TraceAggregationResponse>(
'search',
params
);
const trace = resp.hits.hits.map(hit => hit._source);
const transactionErrorCounts = resp.aggregations.transactions.buckets.reduce(
(
acc: object,
{ key, errors: { doc_count } }: TraceErrorsAggregationBucket
) => {
return {
...acc,
[key]: doc_count
};
},
{}
);

return {
trace,
transactionErrorCounts
};
}

0 comments on commit deb8e2b

Please sign in to comment.