mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[APM] Add range query to transaction/span GETs (#161643)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
11cf01ea43
commit
6efac6268b
16 changed files with 149 additions and 33 deletions
|
@ -13,6 +13,7 @@ import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
|
|||
import { getRedirectToTransactionDetailPageUrl } from './get_redirect_to_transaction_detail_page_url';
|
||||
import { getRedirectToTracePageUrl } from './get_redirect_to_trace_page_url';
|
||||
import { useApmParams } from '../../../hooks/use_apm_params';
|
||||
import { useTimeRange } from '../../../hooks/use_time_range';
|
||||
|
||||
const CentralizedContainer = euiStyled.div`
|
||||
height: 100%;
|
||||
|
@ -25,6 +26,11 @@ export function TraceLink() {
|
|||
query: { rangeFrom, rangeTo },
|
||||
} = useApmParams('/link-to/trace/{traceId}');
|
||||
|
||||
const { start, end } = useTimeRange({
|
||||
rangeFrom: rangeFrom || new Date(0).toISOString(),
|
||||
rangeTo: rangeTo || new Date().toISOString(),
|
||||
});
|
||||
|
||||
const { data = { transaction: null }, status } = useFetcher(
|
||||
(callApmApi) => {
|
||||
if (traceId) {
|
||||
|
@ -35,12 +41,16 @@ export function TraceLink() {
|
|||
path: {
|
||||
traceId,
|
||||
},
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
[traceId]
|
||||
[traceId, start, end]
|
||||
);
|
||||
if (traceId && status === FETCH_STATUS.SUCCESS) {
|
||||
const to = data.transaction
|
||||
|
|
|
@ -94,6 +94,8 @@ interface Props {
|
|||
spanLinksCount: SpanLinksCount;
|
||||
flyoutDetailTab?: string;
|
||||
onClose: () => void;
|
||||
start: string;
|
||||
end: string;
|
||||
}
|
||||
|
||||
const INITIAL_DATA = {
|
||||
|
@ -109,14 +111,19 @@ export function SpanFlyout({
|
|||
onClose,
|
||||
spanLinksCount,
|
||||
flyoutDetailTab,
|
||||
start,
|
||||
end,
|
||||
}: Props) {
|
||||
const { data = INITIAL_DATA, status } = useFetcher(
|
||||
(callApmApi) => {
|
||||
return callApmApi('GET /internal/apm/traces/{traceId}/spans/{spanId}', {
|
||||
params: { path: { traceId, spanId }, query: { parentTransactionId } },
|
||||
params: {
|
||||
path: { traceId, spanId },
|
||||
query: { parentTransactionId, start, end },
|
||||
},
|
||||
});
|
||||
},
|
||||
[traceId, spanId, parentTransactionId]
|
||||
[traceId, spanId, parentTransactionId, start, end]
|
||||
);
|
||||
|
||||
const { span, parentTransaction } = data;
|
||||
|
|
|
@ -101,6 +101,8 @@ export const TransactionSpan: Story<Args> = () => {
|
|||
spanLinksCount={{ linkedChildren: 0, linkedParents: 0 }}
|
||||
parentTransactionId={data.spanEvent['parent.id']}
|
||||
onClose={() => {}}
|
||||
start="fake-time"
|
||||
end="fake-time"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -39,6 +39,8 @@ interface Props {
|
|||
rootTransactionDuration?: number;
|
||||
spanLinksCount: SpanLinksCount;
|
||||
flyoutDetailTab?: string;
|
||||
start: string;
|
||||
end: string;
|
||||
}
|
||||
|
||||
export function TransactionFlyout({
|
||||
|
@ -49,15 +51,17 @@ export function TransactionFlyout({
|
|||
rootTransactionDuration,
|
||||
spanLinksCount,
|
||||
flyoutDetailTab,
|
||||
start,
|
||||
end,
|
||||
}: Props) {
|
||||
const { data: transaction, status } = useFetcher(
|
||||
(callApmApi) => {
|
||||
return callApmApi(
|
||||
'GET /internal/apm/traces/{traceId}/transactions/{transactionId}',
|
||||
{ params: { path: { traceId, transactionId } } }
|
||||
{ params: { path: { traceId, transactionId }, query: { start, end } } }
|
||||
);
|
||||
},
|
||||
[traceId, transactionId]
|
||||
[traceId, transactionId, start, end]
|
||||
);
|
||||
|
||||
const isLoading = isPending(status);
|
||||
|
|
|
@ -84,6 +84,8 @@ export const Example: Story<Args> = () => {
|
|||
transactionId={data.transactionEvent['transaction.id']!}
|
||||
traceId={data.transactionEvent['trace.id']!}
|
||||
spanLinksCount={{ linkedChildren: 0, linkedParents: 0 }}
|
||||
start="fake-time"
|
||||
end="fake-time"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@ import { History } from 'history';
|
|||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useAnyOfApmParams } from '../../../../../../hooks/use_apm_params';
|
||||
import { useTimeRange } from '../../../../../../hooks/use_time_range';
|
||||
import { SpanFlyout } from './span_flyout';
|
||||
import { TransactionFlyout } from './transaction_flyout';
|
||||
import { IWaterfall } from './waterfall_helpers/waterfall_helpers';
|
||||
|
@ -32,7 +33,7 @@ export function WaterfallFlyout({
|
|||
}: Props) {
|
||||
const history = useHistory();
|
||||
const {
|
||||
query: { flyoutDetailTab },
|
||||
query: { flyoutDetailTab, rangeFrom, rangeTo },
|
||||
} = useAnyOfApmParams(
|
||||
'/services/{serviceName}/transactions/view',
|
||||
'/mobile-services/{serviceName}/transactions/view',
|
||||
|
@ -43,6 +44,8 @@ export function WaterfallFlyout({
|
|||
(item) => item.id === waterfallItemId
|
||||
);
|
||||
|
||||
const { start, end } = useTimeRange({ rangeFrom, rangeTo });
|
||||
|
||||
if (!currentItem) {
|
||||
return null;
|
||||
}
|
||||
|
@ -63,6 +66,8 @@ export function WaterfallFlyout({
|
|||
onClose={() => toggleFlyout({ history })}
|
||||
spanLinksCount={currentItem.spanLinksCount}
|
||||
flyoutDetailTab={flyoutDetailTab}
|
||||
start={start}
|
||||
end={end}
|
||||
/>
|
||||
);
|
||||
case 'transaction':
|
||||
|
@ -75,6 +80,8 @@ export function WaterfallFlyout({
|
|||
errorCount={waterfall.getErrorCount(currentItem.id)}
|
||||
spanLinksCount={currentItem.spanLinksCount}
|
||||
flyoutDetailTab={flyoutDetailTab}
|
||||
start={start}
|
||||
end={end}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
|
|
|
@ -12,6 +12,7 @@ import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
|||
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
|
||||
import { getRedirectToTransactionDetailPageUrl } from '../trace_link/get_redirect_to_transaction_detail_page_url';
|
||||
import { useApmParams } from '../../../hooks/use_apm_params';
|
||||
import { useTimeRange } from '../../../hooks/use_time_range';
|
||||
|
||||
const CentralizedContainer = euiStyled.div`
|
||||
height: 100%;
|
||||
|
@ -24,6 +25,11 @@ export function TransactionLink() {
|
|||
query: { rangeFrom, rangeTo, waterfallItemId },
|
||||
} = useApmParams('/link-to/transaction/{transactionId}');
|
||||
|
||||
const { start, end } = useTimeRange({
|
||||
rangeFrom: rangeFrom || new Date(0).toISOString(),
|
||||
rangeTo: rangeTo || new Date().toISOString(),
|
||||
});
|
||||
|
||||
const { data = { transaction: null }, status } = useFetcher(
|
||||
(callApmApi) => {
|
||||
if (transactionId) {
|
||||
|
@ -32,11 +38,15 @@ export function TransactionLink() {
|
|||
path: {
|
||||
transactionId,
|
||||
},
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
[transactionId]
|
||||
[transactionId, start, end]
|
||||
);
|
||||
if (transactionId && status === FETCH_STATUS.SUCCESS) {
|
||||
if (data.transaction) {
|
||||
|
|
|
@ -343,14 +343,13 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({
|
|||
]);
|
||||
const coreContext = await context.core;
|
||||
|
||||
const { serviceName, start, end } = params.query;
|
||||
const { serviceName } = params.query;
|
||||
const searchAggregatedTransactions = await getSearchTransactionsEvents({
|
||||
apmEventClient,
|
||||
config,
|
||||
kuery: '',
|
||||
start,
|
||||
end,
|
||||
});
|
||||
|
||||
const size = await coreContext.uiSettings.client.get<number>(
|
||||
maxSuggestions
|
||||
);
|
||||
|
|
|
@ -103,6 +103,8 @@ const tracesByIdRoute = createApmServerRoute({
|
|||
transactionId: entryTransactionId,
|
||||
traceId,
|
||||
apmEventClient,
|
||||
start,
|
||||
end,
|
||||
}),
|
||||
]);
|
||||
return {
|
||||
|
@ -118,6 +120,7 @@ const rootTransactionByTraceIdRoute = createApmServerRoute({
|
|||
path: t.type({
|
||||
traceId: t.string,
|
||||
}),
|
||||
query: rangeRt,
|
||||
}),
|
||||
options: { tags: ['access:apm'] },
|
||||
handler: async (
|
||||
|
@ -125,10 +128,16 @@ const rootTransactionByTraceIdRoute = createApmServerRoute({
|
|||
): Promise<{
|
||||
transaction: Transaction;
|
||||
}> => {
|
||||
const { params } = resources;
|
||||
const { traceId } = params.path;
|
||||
const {
|
||||
params: {
|
||||
path: { traceId },
|
||||
query: { start, end },
|
||||
},
|
||||
} = resources;
|
||||
|
||||
const apmEventClient = await getApmEventClient(resources);
|
||||
return getRootTransactionByTraceId(traceId, apmEventClient);
|
||||
|
||||
return getRootTransactionByTraceId({ traceId, apmEventClient, start, end });
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -138,6 +147,7 @@ const transactionByIdRoute = createApmServerRoute({
|
|||
path: t.type({
|
||||
transactionId: t.string,
|
||||
}),
|
||||
query: rangeRt,
|
||||
}),
|
||||
options: { tags: ['access:apm'] },
|
||||
handler: async (
|
||||
|
@ -145,11 +155,21 @@ const transactionByIdRoute = createApmServerRoute({
|
|||
): Promise<{
|
||||
transaction: Transaction;
|
||||
}> => {
|
||||
const { params } = resources;
|
||||
const { transactionId } = params.path;
|
||||
const {
|
||||
params: {
|
||||
path: { transactionId },
|
||||
query: { start, end },
|
||||
},
|
||||
} = resources;
|
||||
|
||||
const apmEventClient = await getApmEventClient(resources);
|
||||
return {
|
||||
transaction: await getTransaction({ transactionId, apmEventClient }),
|
||||
transaction: await getTransaction({
|
||||
transactionId,
|
||||
apmEventClient,
|
||||
start,
|
||||
end,
|
||||
}),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -239,16 +259,23 @@ const transactionFromTraceByIdRoute = createApmServerRoute({
|
|||
traceId: t.string,
|
||||
transactionId: t.string,
|
||||
}),
|
||||
query: rangeRt,
|
||||
}),
|
||||
options: { tags: ['access:apm'] },
|
||||
handler: async (resources): Promise<Transaction> => {
|
||||
const { params } = resources;
|
||||
const { transactionId, traceId } = params.path;
|
||||
const {
|
||||
path: { transactionId, traceId },
|
||||
query: { start, end },
|
||||
} = params;
|
||||
|
||||
const apmEventClient = await getApmEventClient(resources);
|
||||
return await getTransaction({
|
||||
transactionId,
|
||||
traceId,
|
||||
apmEventClient,
|
||||
start,
|
||||
end,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -260,7 +287,10 @@ const spanFromTraceByIdRoute = createApmServerRoute({
|
|||
traceId: t.string,
|
||||
spanId: t.string,
|
||||
}),
|
||||
query: t.union([t.partial({ parentTransactionId: t.string }), t.undefined]),
|
||||
query: t.intersection([
|
||||
rangeRt,
|
||||
t.union([t.partial({ parentTransactionId: t.string }), t.undefined]),
|
||||
]),
|
||||
}),
|
||||
options: { tags: ['access:apm'] },
|
||||
handler: async (
|
||||
|
@ -270,14 +300,19 @@ const spanFromTraceByIdRoute = createApmServerRoute({
|
|||
parentTransaction?: Transaction;
|
||||
}> => {
|
||||
const { params } = resources;
|
||||
const { spanId, traceId } = params.path;
|
||||
const { parentTransactionId } = params.query;
|
||||
const {
|
||||
path: { spanId, traceId },
|
||||
query: { start, end, parentTransactionId },
|
||||
} = params;
|
||||
|
||||
const apmEventClient = await getApmEventClient(resources);
|
||||
return await getSpan({
|
||||
spanId,
|
||||
parentTransactionId,
|
||||
traceId,
|
||||
apmEventClient,
|
||||
start,
|
||||
end,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -21,10 +21,20 @@ Object {
|
|||
"trace.id": "bar",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"range": Object {
|
||||
"@timestamp": Object {
|
||||
"format": "epoch_millis",
|
||||
"gte": 0,
|
||||
"lte": 50000,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
"size": 1,
|
||||
"terminate_after": 1,
|
||||
"track_total_hits": false,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { termQuery } from '@kbn/observability-plugin/server';
|
||||
import { rangeQuery, termQuery } from '@kbn/observability-plugin/server';
|
||||
import { ProcessorEvent } from '@kbn/observability-plugin/common';
|
||||
import { SPAN_ID, TRACE_ID } from '../../../../common/es_fields/apm';
|
||||
import { asMutableArray } from '../../../../common/utils/as_mutable_array';
|
||||
|
@ -19,11 +19,15 @@ export async function getSpan({
|
|||
traceId,
|
||||
parentTransactionId,
|
||||
apmEventClient,
|
||||
start,
|
||||
end,
|
||||
}: {
|
||||
spanId: string;
|
||||
traceId: string;
|
||||
parentTransactionId?: string;
|
||||
apmEventClient: APMEventClient;
|
||||
start: number;
|
||||
end: number;
|
||||
}): Promise<{ span?: Span; parentTransaction?: Transaction }> {
|
||||
const [spanResp, parentTransaction] = await Promise.all([
|
||||
apmEventClient.search('get_span', {
|
||||
|
@ -33,11 +37,13 @@ export async function getSpan({
|
|||
body: {
|
||||
track_total_hits: false,
|
||||
size: 1,
|
||||
terminate_after: 1,
|
||||
query: {
|
||||
bool: {
|
||||
filter: asMutableArray([
|
||||
{ term: { [SPAN_ID]: spanId } },
|
||||
...termQuery(TRACE_ID, traceId),
|
||||
...rangeQuery(start, end),
|
||||
]),
|
||||
},
|
||||
},
|
||||
|
@ -48,6 +54,8 @@ export async function getSpan({
|
|||
apmEventClient,
|
||||
transactionId: parentTransactionId,
|
||||
traceId,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
: undefined,
|
||||
]);
|
||||
|
|
|
@ -21,8 +21,8 @@ export async function getTransaction({
|
|||
transactionId: string;
|
||||
traceId?: string;
|
||||
apmEventClient: APMEventClient;
|
||||
start?: number;
|
||||
end?: number;
|
||||
start: number;
|
||||
end: number;
|
||||
}) {
|
||||
const resp = await apmEventClient.search('get_transaction', {
|
||||
apm: {
|
||||
|
@ -31,12 +31,13 @@ export async function getTransaction({
|
|||
body: {
|
||||
track_total_hits: false,
|
||||
size: 1,
|
||||
terminate_after: 1,
|
||||
query: {
|
||||
bool: {
|
||||
filter: asMutableArray([
|
||||
{ term: { [TRANSACTION_ID]: transactionId } },
|
||||
...termQuery(TRACE_ID, traceId),
|
||||
...(start && end ? rangeQuery(start, end) : []),
|
||||
...rangeQuery(start, end),
|
||||
]),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -6,13 +6,21 @@
|
|||
*/
|
||||
|
||||
import { ProcessorEvent } from '@kbn/observability-plugin/common';
|
||||
import { rangeQuery } from '@kbn/observability-plugin/server';
|
||||
import { TRACE_ID, PARENT_ID } from '../../../../common/es_fields/apm';
|
||||
import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client';
|
||||
|
||||
export async function getRootTransactionByTraceId(
|
||||
traceId: string,
|
||||
apmEventClient: APMEventClient
|
||||
) {
|
||||
export async function getRootTransactionByTraceId({
|
||||
traceId,
|
||||
apmEventClient,
|
||||
start,
|
||||
end,
|
||||
}: {
|
||||
traceId: string;
|
||||
apmEventClient: APMEventClient;
|
||||
start: number;
|
||||
end: number;
|
||||
}) {
|
||||
const params = {
|
||||
apm: {
|
||||
events: [ProcessorEvent.transaction as const],
|
||||
|
@ -20,6 +28,7 @@ export async function getRootTransactionByTraceId(
|
|||
body: {
|
||||
track_total_hits: false,
|
||||
size: 1,
|
||||
terminate_after: 1,
|
||||
query: {
|
||||
bool: {
|
||||
should: [
|
||||
|
@ -33,7 +42,10 @@ export async function getRootTransactionByTraceId(
|
|||
},
|
||||
},
|
||||
],
|
||||
filter: [{ term: { [TRACE_ID]: traceId } }],
|
||||
filter: [
|
||||
{ term: { [TRACE_ID]: traceId } },
|
||||
...rangeQuery(start, end),
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -60,8 +60,6 @@ export interface APMRouteHandlerResources {
|
|||
params: {
|
||||
query: {
|
||||
_inspect: boolean;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
};
|
||||
config: APMConfig;
|
||||
|
|
|
@ -30,7 +30,11 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
endpoint: `GET /internal/apm/traces/{traceId}/spans/{spanId}`,
|
||||
params: {
|
||||
path: { traceId, spanId },
|
||||
query: { parentTransactionId },
|
||||
query: {
|
||||
parentTransactionId,
|
||||
start: new Date(start).toISOString(),
|
||||
end: new Date(end).toISOString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,7 +27,14 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
return await apmApiClient.readUser({
|
||||
endpoint: `GET /internal/apm/traces/{traceId}/transactions/{transactionId}`,
|
||||
params: {
|
||||
path: { traceId, transactionId },
|
||||
path: {
|
||||
traceId,
|
||||
transactionId,
|
||||
},
|
||||
query: {
|
||||
start: new Date(start).toISOString(),
|
||||
end: new Date(end).toISOString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue