mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM][Transactions] Test trace summary (#207115)
Closes #206947 ## Summary This PR adds tests for trace summary (Otel / APM cases) and changes the `styled-components` to `css`.
This commit is contained in:
parent
4d539f0f5c
commit
8b97ad0b13
10 changed files with 116 additions and 21 deletions
|
@ -213,6 +213,7 @@ export type ApmFields = Fields<{
|
|||
}>;
|
||||
'url.original': string;
|
||||
'url.domain': string;
|
||||
'url.full': string;
|
||||
}> &
|
||||
ApmApplicationMetricFields &
|
||||
ExperimentalFields;
|
||||
|
|
|
@ -25,6 +25,9 @@ export class Transaction extends BaseSpan {
|
|||
'processor.event': 'transaction',
|
||||
'transaction.id': generateShortId(),
|
||||
'transaction.sampled': true,
|
||||
'http.request.method': 'GET',
|
||||
'http.response.status_code': 200,
|
||||
'url.full': 'elastic.co',
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ interface OtelSharedResourceAttributes {
|
|||
'telemetry.sdk.language'?: string;
|
||||
'telemetry.sdk.name'?: string;
|
||||
'telemetry.sdk.version'?: string;
|
||||
'some.resource.attribute'?: string;
|
||||
}
|
||||
|
||||
export interface OtelDocument extends Fields {
|
||||
|
@ -165,6 +164,9 @@ class Otel extends Serializable<OtelDocument> {
|
|||
'transaction.root': true,
|
||||
'transaction.sampled': true,
|
||||
'transaction.type': 'unknown',
|
||||
'http.request.method': 'POST',
|
||||
'http.response.status_code': 200,
|
||||
'url.full': 'elastic.co',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'generic.otel',
|
||||
|
|
|
@ -24,6 +24,9 @@ export interface OtelTransactionDocument extends OtelDocument {
|
|||
'transaction.root'?: boolean;
|
||||
'transaction.sampled'?: boolean;
|
||||
'transaction.type'?: string;
|
||||
'http.response.status_code'?: number;
|
||||
'http.request.method'?: string;
|
||||
'url.full'?: string;
|
||||
};
|
||||
status?: {
|
||||
code?: string;
|
||||
|
|
|
@ -95,6 +95,8 @@ describe('simple trace', () => {
|
|||
'container.id': 'instance-1',
|
||||
'event.outcome': 'success',
|
||||
'host.name': 'instance-1',
|
||||
'http.request.method': 'GET',
|
||||
'http.response.status_code': 200,
|
||||
'processor.event': 'transaction',
|
||||
'processor.name': 'transaction',
|
||||
'service.environment': 'production',
|
||||
|
@ -107,6 +109,7 @@ describe('simple trace', () => {
|
|||
'transaction.name': 'GET /api/product/list',
|
||||
'transaction.type': 'request',
|
||||
'transaction.sampled': true,
|
||||
'url.full': 'elastic.co',
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -20,6 +22,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459200050,
|
||||
|
@ -89,6 +92,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -101,6 +106,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459260050,
|
||||
|
@ -170,6 +176,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -182,6 +190,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459320050,
|
||||
|
@ -251,6 +260,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -263,6 +274,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459380050,
|
||||
|
@ -332,6 +344,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -344,6 +358,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459440050,
|
||||
|
@ -413,6 +428,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -425,6 +442,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459500050,
|
||||
|
@ -494,6 +512,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -506,6 +526,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459560050,
|
||||
|
@ -575,6 +596,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -587,6 +610,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459620050,
|
||||
|
@ -656,6 +680,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -668,6 +694,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459680050,
|
||||
|
@ -737,6 +764,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -749,6 +778,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459740050,
|
||||
|
@ -818,6 +848,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -830,6 +862,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459800050,
|
||||
|
@ -899,6 +932,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -911,6 +946,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459860050,
|
||||
|
@ -980,6 +1016,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -992,6 +1030,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459920050,
|
||||
|
@ -1061,6 +1100,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -1073,6 +1114,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609459980050,
|
||||
|
@ -1142,6 +1184,8 @@ Array [
|
|||
"container.id": "instance-1",
|
||||
"event.outcome": "success",
|
||||
"host.name": "instance-1",
|
||||
"http.request.method": "GET",
|
||||
"http.response.status_code": 200,
|
||||
"processor.event": "transaction",
|
||||
"processor.name": "transaction",
|
||||
"service.environment": "production",
|
||||
|
@ -1154,6 +1198,7 @@ Array [
|
|||
"transaction.name": "GET /api/product/list",
|
||||
"transaction.sampled": true,
|
||||
"transaction.type": "request",
|
||||
"url.full": "elastic.co",
|
||||
},
|
||||
Object {
|
||||
"@timestamp": 1609460040050,
|
||||
|
|
|
@ -20,6 +20,12 @@ const baseUrl = url.format({
|
|||
query: { rangeFrom: start, rangeTo: end },
|
||||
});
|
||||
|
||||
const transactionTabPath = '/app/apm/services/sendotlp-synth/transactions/view';
|
||||
const transactionUrl = url.format({
|
||||
pathname: transactionTabPath,
|
||||
query: { rangeFrom: start, rangeTo: end, transactionName: 'parent-synth' },
|
||||
});
|
||||
|
||||
describe('Service Overview', () => {
|
||||
before(() => {
|
||||
synthtraceOtel.index(
|
||||
|
@ -117,6 +123,13 @@ describe('Service Overview', () => {
|
|||
cy.contains('a', 'parent-synth').click();
|
||||
cy.contains('h5', 'parent-synth');
|
||||
});
|
||||
it('shows transaction summary', () => {
|
||||
cy.visitKibana(transactionUrl);
|
||||
|
||||
cy.getByTestSubj('apmHttpInfoRequestMethod').should('exist');
|
||||
cy.getByTestSubj('apmHttpInfoUrl').should('exist');
|
||||
cy.getByTestSubj('apmHttpStatusBadge').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('errors', () => {
|
||||
|
|
|
@ -123,6 +123,21 @@ describe('Transaction details', () => {
|
|||
cy.url().should('include', 'opbeans-java/errors');
|
||||
});
|
||||
|
||||
describe('Trace sample summary', () => {
|
||||
it('shows transaction summary', () => {
|
||||
cy.visitKibana(
|
||||
`/app/apm/services/opbeans-node/transactions/view?${new URLSearchParams({
|
||||
...timeRange,
|
||||
transactionName: 'GET /api/product/:id',
|
||||
})}`
|
||||
);
|
||||
|
||||
cy.getByTestSubj('apmHttpInfoRequestMethod').should('exist');
|
||||
cy.getByTestSubj('apmHttpInfoUrl').should('exist');
|
||||
cy.getByTestSubj('apmHttpStatusBadge').should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when navigating to a trace sample', () => {
|
||||
it('keeps the same trace sample after reloading the page', () => {
|
||||
cy.visitKibana(
|
||||
|
|
|
@ -5,21 +5,20 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiBadge, EuiToolTip } from '@elastic/eui';
|
||||
import { EuiBadge, EuiToolTip, useEuiTheme } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { truncate, unit } from '../../../../utils/style';
|
||||
import { css } from '@emotion/react';
|
||||
import { unit } from '../../../../utils/style';
|
||||
import { HttpStatusBadge } from '../http_status_badge';
|
||||
|
||||
const HttpInfoBadge = styled(EuiBadge)`
|
||||
margin-right: ${({ theme }) => theme.euiTheme.size.xs};
|
||||
`;
|
||||
|
||||
const Url = styled('span')`
|
||||
const urlStyles = css`
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
${truncate(unit * 24)};
|
||||
max-width: ${unit * 24}px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
`;
|
||||
interface HttpInfoProps {
|
||||
method?: string;
|
||||
|
@ -27,11 +26,9 @@ interface HttpInfoProps {
|
|||
url: string;
|
||||
}
|
||||
|
||||
const Span = styled('span')`
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
export function HttpInfoSummaryItem({ status, method, url }: HttpInfoProps) {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
@ -41,18 +38,29 @@ export function HttpInfoSummaryItem({ status, method, url }: HttpInfoProps) {
|
|||
});
|
||||
|
||||
return (
|
||||
<Span>
|
||||
<HttpInfoBadge title={undefined}>
|
||||
<span
|
||||
css={css`
|
||||
whitespace: nowrap;
|
||||
`}
|
||||
>
|
||||
<EuiBadge
|
||||
title={undefined}
|
||||
css={{
|
||||
marginRight: `${euiTheme.size.xs}`,
|
||||
}}
|
||||
>
|
||||
{method && (
|
||||
<EuiToolTip content={methodLabel}>
|
||||
<>{method.toUpperCase()}</>
|
||||
<span data-test-subj="apmHttpInfoRequestMethod">{method.toUpperCase()}</span>
|
||||
</EuiToolTip>
|
||||
)}{' '}
|
||||
<EuiToolTip content={url}>
|
||||
<Url>{url}</Url>
|
||||
<span data-test-subj="apmHttpInfoUrl" css={urlStyles}>
|
||||
{url}
|
||||
</span>
|
||||
</EuiToolTip>
|
||||
</HttpInfoBadge>
|
||||
</EuiBadge>
|
||||
{status && <HttpStatusBadge status={status} />}
|
||||
</Span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ export function HttpStatusBadge({ status }: HttpStatusBadgeProps) {
|
|||
return (
|
||||
<EuiToolTip content={label}>
|
||||
<EuiBadge color={useGetStatusColor(status) || 'default'}>
|
||||
{status} {statusCodes[status.toString()]}
|
||||
<span data-test-subj="apmHttpStatusBadge">
|
||||
{status} {statusCodes[status.toString()]}
|
||||
</span>
|
||||
</EuiBadge>
|
||||
</EuiToolTip>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue