mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[APM] Adds support for metrics for latency distribution histogram (#136594)
* [APM] Adds support for metrics for latency distribution histogram (#132394) * PR feedback * Addresses feedback: - filters by existing duration field for metrics - get duration field and event type by chart type * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * fixed type errors and removed eventType from being passed to to function specifically for latency correlations * addressed PR feedback: - renamed enums to match established pattern - renamed `LatencyDistributionChartType.transactionDetails` to `*.traceSamples` to align with tab label - added explanatory line comments * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * rename `LatencyDistributionChartType.traceSamples` -> `*.transactionLatency` * renamed `LatencyDistributionChartType.dependencyLatency` -> `*.dependencyLatency` * filters the query passed into getOverallLatencyDistribution when using metrics data * fixes appendFilterQuery param types * renames searchAggregatedTransactions -> searchMetrics for latency distribution * removed unnecessary util function `appendFilterQuery`. * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * make the searchMetrics param required * fixes lint issue * moves the duration field filter to append to the given query at the tail functions for latency distribution Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
69dc7e2b77
commit
f903899ec0
22 changed files with 264 additions and 94 deletions
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as t from 'io-ts';
|
||||
|
||||
export enum LatencyDistributionChartType {
|
||||
transactionLatency = 'transactionLatency',
|
||||
latencyCorrelations = 'latencyCorrelations',
|
||||
failedTransactionsCorrelations = 'failedTransactionsCorrelations',
|
||||
dependencyLatency = 'dependencyLatency',
|
||||
}
|
||||
export const latencyDistributionChartTypeRt = t.union([
|
||||
t.literal(LatencyDistributionChartType.transactionLatency),
|
||||
t.literal(LatencyDistributionChartType.latencyCorrelations),
|
||||
t.literal(LatencyDistributionChartType.failedTransactionsCorrelations),
|
||||
t.literal(LatencyDistributionChartType.dependencyLatency),
|
||||
]);
|
|
@ -23,6 +23,7 @@ import type {
|
|||
FailedTransactionsCorrelation,
|
||||
FailedTransactionsCorrelationsResponse,
|
||||
} from '../../../../common/correlations/failed_transactions_correlations/types';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
|
||||
import { callApmApi } from '../../../services/rest/create_call_apm_api';
|
||||
|
||||
|
@ -95,6 +96,8 @@ export function useFailedTransactionsCorrelations() {
|
|||
body: {
|
||||
...fetchParams,
|
||||
percentileThreshold: DEFAULT_PERCENTILE_THRESHOLD,
|
||||
chartType:
|
||||
LatencyDistributionChartType.failedTransactionsCorrelations,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -113,6 +116,8 @@ export function useFailedTransactionsCorrelations() {
|
|||
fieldValue: EventOutcome.failure,
|
||||
},
|
||||
],
|
||||
chartType:
|
||||
LatencyDistributionChartType.failedTransactionsCorrelations,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import type {
|
|||
LatencyCorrelation,
|
||||
LatencyCorrelationsResponse,
|
||||
} from '../../../../common/correlations/latency_correlations/types';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
|
||||
import { callApmApi } from '../../../services/rest/create_call_apm_api';
|
||||
|
||||
|
@ -94,6 +95,7 @@ export function useLatencyCorrelations() {
|
|||
body: {
|
||||
...fetchParams,
|
||||
percentileThreshold: DEFAULT_PERCENTILE_THRESHOLD,
|
||||
chartType: LatencyDistributionChartType.latencyCorrelations,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { DEFAULT_PERCENTILE_THRESHOLD } from '../../../../../common/correlations/constants';
|
||||
import { EVENT_OUTCOME } from '../../../../../common/elasticsearch_fieldnames';
|
||||
import { EventOutcome } from '../../../../../common/event_outcome';
|
||||
import { LatencyDistributionChartType } from '../../../../../common/latency_distribution_chart_types';
|
||||
import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context';
|
||||
import { useFetcher, FETCH_STATUS } from '../../../../hooks/use_fetcher';
|
||||
import { isErrorMessage } from '../../correlations/utils/is_error_message';
|
||||
|
@ -44,6 +45,7 @@ export const useTransactionDistributionChartData = () => {
|
|||
body: {
|
||||
...params,
|
||||
percentileThreshold: DEFAULT_PERCENTILE_THRESHOLD,
|
||||
chartType: LatencyDistributionChartType.transactionLatency,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -99,6 +101,7 @@ export const useTransactionDistributionChartData = () => {
|
|||
fieldValue: EventOutcome.failure,
|
||||
},
|
||||
],
|
||||
chartType: LatencyDistributionChartType.transactionLatency,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -18,14 +18,15 @@ import {
|
|||
KS_TEST_THRESHOLD,
|
||||
} from '../../../../common/correlations/constants';
|
||||
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import { fetchDurationCorrelation } from './fetch_duration_correlation';
|
||||
import { fetchDurationRanges } from './fetch_duration_ranges';
|
||||
import { getEventType } from '../utils';
|
||||
|
||||
export async function fetchDurationCorrelationWithHistogram({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -39,7 +40,7 @@ export async function fetchDurationCorrelationWithHistogram({
|
|||
fieldValuePair,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
setup: Setup;
|
||||
eventType: ProcessorEvent;
|
||||
chartType: LatencyDistributionChartType;
|
||||
expectations: number[];
|
||||
ranges: estypes.AggregationsAggregationRange[];
|
||||
fractions: number[];
|
||||
|
@ -47,6 +48,8 @@ export async function fetchDurationCorrelationWithHistogram({
|
|||
totalDocCount: number;
|
||||
fieldValuePair: FieldValuePair;
|
||||
}) {
|
||||
const searchMetrics = false; // latency correlations does not search metrics documents
|
||||
const eventType = getEventType(chartType, searchMetrics);
|
||||
const queryWithFieldValuePair = {
|
||||
bool: {
|
||||
filter: [
|
||||
|
@ -74,13 +77,14 @@ export async function fetchDurationCorrelationWithHistogram({
|
|||
if (correlation > CORRELATION_THRESHOLD && ksTest < KS_TEST_THRESHOLD) {
|
||||
const { durationRanges: histogram } = await fetchDurationRanges({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query: queryWithFieldValuePair,
|
||||
rangeSteps: histogramRangeSteps,
|
||||
searchMetrics,
|
||||
});
|
||||
return {
|
||||
...fieldValuePair,
|
||||
|
|
|
@ -9,13 +9,10 @@ import { scaleLog } from 'd3-scale';
|
|||
|
||||
import { isFiniteNumber } from '@kbn/observability-plugin/common/utils/is_finite_number';
|
||||
import { CommonCorrelationsQueryParams } from '../../../../common/correlations/types';
|
||||
import {
|
||||
SPAN_DURATION,
|
||||
TRANSACTION_DURATION,
|
||||
} from '../../../../common/elasticsearch_fieldnames';
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import { getCommonCorrelationsQuery } from './get_common_correlations_query';
|
||||
import { getDurationField, getEventType } from '../utils';
|
||||
|
||||
const getHistogramRangeSteps = (min: number, max: number, steps: number) => {
|
||||
// A d3 based scale function as a helper to get equally distributed bins on a log scale.
|
||||
|
@ -27,29 +24,34 @@ const getHistogramRangeSteps = (min: number, max: number, steps: number) => {
|
|||
};
|
||||
|
||||
export const fetchDurationHistogramRangeSteps = async ({
|
||||
eventType,
|
||||
chartType,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
searchMetrics,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
eventType: ProcessorEvent;
|
||||
chartType: LatencyDistributionChartType;
|
||||
setup: Setup;
|
||||
searchMetrics: boolean;
|
||||
}): Promise<number[]> => {
|
||||
const { apmEventClient } = setup;
|
||||
|
||||
const steps = 100;
|
||||
const durationField = getDurationField(chartType, searchMetrics);
|
||||
|
||||
const durationField =
|
||||
eventType === ProcessorEvent.span ? SPAN_DURATION : TRANSACTION_DURATION;
|
||||
// when using metrics data, ensure we filter by docs with the appropriate duration field
|
||||
const filteredQuery = searchMetrics
|
||||
? { bool: { filter: [query, { exists: { field: durationField } }] } }
|
||||
: query;
|
||||
|
||||
const resp = await apmEventClient.search(
|
||||
'get_duration_histogram_range_steps',
|
||||
{
|
||||
apm: {
|
||||
events: [eventType],
|
||||
events: [getEventType(chartType, searchMetrics)],
|
||||
},
|
||||
body: {
|
||||
size: 0,
|
||||
|
@ -58,7 +60,7 @@ export const fetchDurationHistogramRangeSteps = async ({
|
|||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
query: filteredQuery,
|
||||
}),
|
||||
aggs: {
|
||||
duration_min: { min: { field: durationField } },
|
||||
|
|
|
@ -5,18 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
SPAN_DURATION,
|
||||
TRANSACTION_DURATION,
|
||||
} from '../../../../common/elasticsearch_fieldnames';
|
||||
import { SIGNIFICANT_VALUE_DIGITS } from '../../../../common/correlations/constants';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { getCommonCorrelationsQuery } from './get_common_correlations_query';
|
||||
import { CommonCorrelationsQueryParams } from '../../../../common/correlations/types';
|
||||
import { getDurationField, getEventType } from '../utils';
|
||||
|
||||
export const fetchDurationPercentiles = async ({
|
||||
eventType,
|
||||
chartType,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
|
@ -24,44 +21,51 @@ export const fetchDurationPercentiles = async ({
|
|||
kuery,
|
||||
query,
|
||||
percents,
|
||||
searchMetrics,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
eventType: ProcessorEvent;
|
||||
chartType: LatencyDistributionChartType;
|
||||
setup: Setup;
|
||||
percents?: number[];
|
||||
searchMetrics: boolean;
|
||||
}): Promise<{
|
||||
totalDocs: number;
|
||||
percentiles: Record<string, number>;
|
||||
}> => {
|
||||
const response = await setup.apmEventClient.search(
|
||||
'get_duration_percentiles',
|
||||
{
|
||||
apm: { events: [eventType] },
|
||||
body: {
|
||||
track_total_hits: true,
|
||||
query: getCommonCorrelationsQuery({
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
}),
|
||||
size: 0,
|
||||
aggs: {
|
||||
duration_percentiles: {
|
||||
percentiles: {
|
||||
hdr: {
|
||||
number_of_significant_value_digits: SIGNIFICANT_VALUE_DIGITS,
|
||||
},
|
||||
field:
|
||||
eventType === ProcessorEvent.span
|
||||
? SPAN_DURATION
|
||||
: TRANSACTION_DURATION,
|
||||
...(Array.isArray(percents) ? { percents } : {}),
|
||||
const durationField = getDurationField(chartType, searchMetrics);
|
||||
|
||||
// when using metrics data, ensure we filter by docs with the appropriate duration field
|
||||
const filteredQuery = searchMetrics
|
||||
? { bool: { filter: [query, { exists: { field: durationField } }] } }
|
||||
: query;
|
||||
|
||||
const params = {
|
||||
apm: { events: [getEventType(chartType, searchMetrics)] },
|
||||
body: {
|
||||
track_total_hits: true,
|
||||
query: getCommonCorrelationsQuery({
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query: filteredQuery,
|
||||
}),
|
||||
size: 0,
|
||||
aggs: {
|
||||
duration_percentiles: {
|
||||
percentiles: {
|
||||
hdr: {
|
||||
number_of_significant_value_digits: SIGNIFICANT_VALUE_DIGITS,
|
||||
},
|
||||
field: getDurationField(chartType, searchMetrics),
|
||||
...(Array.isArray(percents) ? { percents } : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
const response = await setup.apmEventClient.search(
|
||||
'get_duration_percentiles',
|
||||
params
|
||||
);
|
||||
|
||||
// return early with no results if the search didn't return any documents
|
||||
|
|
|
@ -7,14 +7,11 @@
|
|||
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { sumBy } from 'lodash';
|
||||
import {
|
||||
SPAN_DURATION,
|
||||
TRANSACTION_DURATION,
|
||||
} from '../../../../common/elasticsearch_fieldnames';
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import { getCommonCorrelationsQuery } from './get_common_correlations_query';
|
||||
import { Environment } from '../../../../common/environment_rt';
|
||||
import { getDurationField, getEventType } from '../utils';
|
||||
|
||||
export const fetchDurationRanges = async ({
|
||||
rangeSteps,
|
||||
|
@ -24,7 +21,8 @@ export const fetchDurationRanges = async ({
|
|||
environment,
|
||||
kuery,
|
||||
query,
|
||||
eventType,
|
||||
chartType,
|
||||
searchMetrics,
|
||||
}: {
|
||||
rangeSteps: number[];
|
||||
setup: Setup;
|
||||
|
@ -33,12 +31,19 @@ export const fetchDurationRanges = async ({
|
|||
environment: Environment;
|
||||
kuery: string;
|
||||
query: estypes.QueryDslQueryContainer;
|
||||
eventType: ProcessorEvent;
|
||||
chartType: LatencyDistributionChartType;
|
||||
searchMetrics: boolean;
|
||||
}): Promise<{
|
||||
totalDocCount: number;
|
||||
durationRanges: Array<{ key: number; doc_count: number }>;
|
||||
}> => {
|
||||
const { apmEventClient } = setup;
|
||||
const durationField = getDurationField(chartType, searchMetrics);
|
||||
|
||||
// when using metrics data, ensure we filter by docs with the appropriate duration field
|
||||
const filteredQuery = searchMetrics
|
||||
? { bool: { filter: [query, { exists: { field: durationField } }] } }
|
||||
: query;
|
||||
|
||||
const ranges = rangeSteps.reduce(
|
||||
(p, to) => {
|
||||
|
@ -54,7 +59,7 @@ export const fetchDurationRanges = async ({
|
|||
|
||||
const resp = await apmEventClient.search('get_duration_ranges', {
|
||||
apm: {
|
||||
events: [eventType],
|
||||
events: [getEventType(chartType, searchMetrics)],
|
||||
},
|
||||
body: {
|
||||
size: 0,
|
||||
|
@ -63,15 +68,12 @@ export const fetchDurationRanges = async ({
|
|||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
query: filteredQuery,
|
||||
}),
|
||||
aggs: {
|
||||
logspace_ranges: {
|
||||
range: {
|
||||
field:
|
||||
eventType === ProcessorEvent.span
|
||||
? SPAN_DURATION
|
||||
: TRANSACTION_DURATION,
|
||||
field: getDurationField(chartType, searchMetrics),
|
||||
ranges,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,14 +12,14 @@ import {
|
|||
PROCESSOR_EVENT,
|
||||
} from '../../../../common/elasticsearch_fieldnames';
|
||||
import { EventOutcome } from '../../../../common/event_outcome';
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import { getCommonCorrelationsQuery } from './get_common_correlations_query';
|
||||
import { fetchDurationRanges } from './fetch_duration_ranges';
|
||||
import { getEventType } from '../utils';
|
||||
|
||||
export const fetchFailedEventsCorrelationPValues = async ({
|
||||
setup,
|
||||
eventType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -29,12 +29,15 @@ export const fetchFailedEventsCorrelationPValues = async ({
|
|||
fieldName,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
setup: Setup;
|
||||
eventType: ProcessorEvent;
|
||||
rangeSteps: number[];
|
||||
fieldName: string;
|
||||
}) => {
|
||||
const { apmEventClient } = setup;
|
||||
|
||||
const chartType = LatencyDistributionChartType.failedTransactionsCorrelations;
|
||||
const searchMetrics = false; // failed transactions correlations does not search metrics documents
|
||||
const eventType = getEventType(chartType, searchMetrics);
|
||||
|
||||
const commonQuery = getCommonCorrelationsQuery({
|
||||
start,
|
||||
end,
|
||||
|
@ -103,7 +106,7 @@ export const fetchFailedEventsCorrelationPValues = async ({
|
|||
|
||||
const { durationRanges: histogram } = await fetchDurationRanges({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -114,6 +117,7 @@ export const fetchFailedEventsCorrelationPValues = async ({
|
|||
},
|
||||
},
|
||||
rangeSteps,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
result.push({
|
||||
|
|
|
@ -9,15 +9,14 @@ import { ERROR_CORRELATION_THRESHOLD } from '../../../../common/correlations/con
|
|||
import type { FailedTransactionsCorrelation } from '../../../../common/correlations/failed_transactions_correlations/types';
|
||||
|
||||
import { CommonCorrelationsQueryParams } from '../../../../common/correlations/types';
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import { splitAllSettledPromises } from '../utils';
|
||||
import { splitAllSettledPromises, getEventType } from '../utils';
|
||||
import { fetchDurationHistogramRangeSteps } from './fetch_duration_histogram_range_steps';
|
||||
import { fetchFailedEventsCorrelationPValues } from './fetch_failed_events_correlation_p_values';
|
||||
|
||||
export const fetchPValues = async ({
|
||||
setup,
|
||||
eventType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -26,17 +25,21 @@ export const fetchPValues = async ({
|
|||
fieldCandidates,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
setup: Setup;
|
||||
eventType: ProcessorEvent;
|
||||
fieldCandidates: string[];
|
||||
}) => {
|
||||
const chartType = LatencyDistributionChartType.failedTransactionsCorrelations;
|
||||
const searchMetrics = false; // failed transactions correlations does not search metrics documents
|
||||
const eventType = getEventType(chartType, searchMetrics);
|
||||
|
||||
const rangeSteps = await fetchDurationHistogramRangeSteps({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
const { fulfilled, rejected } = splitAllSettledPromises(
|
||||
|
@ -44,7 +47,6 @@ export const fetchPValues = async ({
|
|||
fieldCandidates.map((fieldName) =>
|
||||
fetchFailedEventsCorrelationPValues({
|
||||
setup,
|
||||
eventType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
|
|
@ -14,7 +14,7 @@ import type {
|
|||
FieldValuePair,
|
||||
} from '../../../../common/correlations/types';
|
||||
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../../lib/helpers/setup_request';
|
||||
import {
|
||||
computeExpectationsAndRanges,
|
||||
|
@ -25,10 +25,10 @@ import { fetchDurationCorrelationWithHistogram } from './fetch_duration_correlat
|
|||
import { fetchDurationFractions } from './fetch_duration_fractions';
|
||||
import { fetchDurationHistogramRangeSteps } from './fetch_duration_histogram_range_steps';
|
||||
import { fetchDurationRanges } from './fetch_duration_ranges';
|
||||
import { getEventType } from '../utils';
|
||||
|
||||
export const fetchSignificantCorrelations = async ({
|
||||
setup,
|
||||
eventType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -37,20 +37,24 @@ export const fetchSignificantCorrelations = async ({
|
|||
fieldValuePairs,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
setup: Setup;
|
||||
eventType: ProcessorEvent;
|
||||
fieldValuePairs: FieldValuePair[];
|
||||
}) => {
|
||||
// Create an array of ranges [2, 4, 6, ..., 98]
|
||||
const percentileAggregationPercents = range(2, 100, 2);
|
||||
const chartType = LatencyDistributionChartType.latencyCorrelations;
|
||||
const searchMetrics = false; // latency correlations does not search metrics documents
|
||||
const eventType = getEventType(chartType, searchMetrics);
|
||||
|
||||
const { percentiles: percentilesRecords } = await fetchDurationPercentiles({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
percents: percentileAggregationPercents,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
// We need to round the percentiles values
|
||||
|
@ -73,12 +77,13 @@ export const fetchSignificantCorrelations = async ({
|
|||
|
||||
const histogramRangeSteps = await fetchDurationHistogramRangeSteps({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
const { fulfilled, rejected } = splitAllSettledPromises(
|
||||
|
@ -86,7 +91,7 @@ export const fetchSignificantCorrelations = async ({
|
|||
fieldValuePairs.map((fieldValuePair) =>
|
||||
fetchDurationCorrelationWithHistogram({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -132,7 +137,7 @@ export const fetchSignificantCorrelations = async ({
|
|||
const { fieldName, fieldValue } = fallbackResult;
|
||||
const { durationRanges: histogram } = await fetchDurationRanges({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -143,6 +148,7 @@ export const fetchSignificantCorrelations = async ({
|
|||
},
|
||||
},
|
||||
rangeSteps: histogramRangeSteps,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
if (fallbackResult) {
|
||||
|
|
|
@ -349,7 +349,6 @@ const significantCorrelationsTransactionsRoute = createApmServerRoute({
|
|||
|
||||
return fetchSignificantCorrelations({
|
||||
setup,
|
||||
eventType: ProcessorEvent.transaction,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
@ -412,7 +411,6 @@ const pValuesTransactionsRoute = createApmServerRoute({
|
|||
|
||||
return fetchPValues({
|
||||
setup,
|
||||
eventType: ProcessorEvent.transaction,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
SPAN_DURATION,
|
||||
TRANSACTION_DURATION,
|
||||
TRANSACTION_DURATION_HISTOGRAM,
|
||||
} from '../../../../common/elasticsearch_fieldnames';
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
|
||||
const {
|
||||
transactionLatency,
|
||||
latencyCorrelations,
|
||||
failedTransactionsCorrelations,
|
||||
dependencyLatency,
|
||||
} = LatencyDistributionChartType;
|
||||
|
||||
export function getDurationField(
|
||||
chartType: LatencyDistributionChartType,
|
||||
searchMetrics: boolean
|
||||
) {
|
||||
switch (chartType) {
|
||||
case transactionLatency:
|
||||
if (searchMetrics) {
|
||||
return TRANSACTION_DURATION_HISTOGRAM;
|
||||
}
|
||||
return TRANSACTION_DURATION;
|
||||
case latencyCorrelations:
|
||||
return TRANSACTION_DURATION;
|
||||
case failedTransactionsCorrelations:
|
||||
return TRANSACTION_DURATION;
|
||||
case dependencyLatency:
|
||||
return SPAN_DURATION;
|
||||
default:
|
||||
return TRANSACTION_DURATION;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LatencyDistributionChartType } from '../../../../common/latency_distribution_chart_types';
|
||||
import { ProcessorEvent } from '../../../../common/processor_event';
|
||||
|
||||
const {
|
||||
transactionLatency,
|
||||
latencyCorrelations,
|
||||
failedTransactionsCorrelations,
|
||||
dependencyLatency,
|
||||
} = LatencyDistributionChartType;
|
||||
|
||||
export function getEventType(
|
||||
chartType: LatencyDistributionChartType,
|
||||
searchMetrics: boolean
|
||||
): ProcessorEvent {
|
||||
switch (chartType) {
|
||||
case transactionLatency:
|
||||
if (searchMetrics) {
|
||||
return ProcessorEvent.metric;
|
||||
}
|
||||
return ProcessorEvent.transaction;
|
||||
case latencyCorrelations:
|
||||
return ProcessorEvent.transaction;
|
||||
case failedTransactionsCorrelations:
|
||||
return ProcessorEvent.transaction;
|
||||
case dependencyLatency:
|
||||
return ProcessorEvent.span;
|
||||
default:
|
||||
return ProcessorEvent.transaction;
|
||||
}
|
||||
}
|
|
@ -7,3 +7,5 @@
|
|||
|
||||
export { computeExpectationsAndRanges } from './compute_expectations_and_ranges';
|
||||
export { splitAllSettledPromises } from './split_all_settled_promises';
|
||||
export { getDurationField } from './get_duration_field';
|
||||
export { getEventType } from './get_event_type';
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { Environment } from '../../../common/environment_rt';
|
||||
import { EventOutcome } from '../../../common/event_outcome';
|
||||
import { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../lib/helpers/setup_request';
|
||||
import { getOverallLatencyDistribution } from '../latency_distribution/get_overall_latency_distribution';
|
||||
import { OverallLatencyDistributionResponse } from '../latency_distribution/types';
|
||||
|
@ -41,13 +41,14 @@ export async function getDependencyLatencyDistribution({
|
|||
failedSpansDistribution: OverallLatencyDistributionResponse;
|
||||
}> {
|
||||
const commonProps = {
|
||||
eventType: ProcessorEvent.span,
|
||||
chartType: LatencyDistributionChartType.dependencyLatency,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
percentileThreshold,
|
||||
searchMetrics: false,
|
||||
};
|
||||
|
||||
const commonQuery = {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { Environment } from '../../../common/environment_rt';
|
||||
|
||||
import { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { Setup } from '../../lib/helpers/setup_request';
|
||||
|
||||
import { withApmSpan } from '../../utils/with_apm_span';
|
||||
|
@ -18,9 +17,10 @@ import { fetchDurationHistogramRangeSteps } from '../correlations/queries/fetch_
|
|||
|
||||
import { getPercentileThresholdValue } from './get_percentile_threshold_value';
|
||||
import type { OverallLatencyDistributionResponse } from './types';
|
||||
import { LatencyDistributionChartType } from '../../../common/latency_distribution_chart_types';
|
||||
|
||||
export async function getOverallLatencyDistribution({
|
||||
eventType,
|
||||
chartType,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
|
@ -28,8 +28,9 @@ export async function getOverallLatencyDistribution({
|
|||
kuery,
|
||||
query,
|
||||
percentileThreshold,
|
||||
searchMetrics,
|
||||
}: {
|
||||
eventType: ProcessorEvent;
|
||||
chartType: LatencyDistributionChartType;
|
||||
setup: Setup;
|
||||
start: number;
|
||||
end: number;
|
||||
|
@ -37,6 +38,7 @@ export async function getOverallLatencyDistribution({
|
|||
kuery: string;
|
||||
query: estypes.QueryDslQueryContainer;
|
||||
percentileThreshold: number;
|
||||
searchMetrics: boolean;
|
||||
}) {
|
||||
return withApmSpan('get_overall_latency_distribution', async () => {
|
||||
const overallLatencyDistribution: OverallLatencyDistributionResponse = {};
|
||||
|
@ -44,7 +46,7 @@ export async function getOverallLatencyDistribution({
|
|||
// #1: get 95th percentile to be displayed as a marker in the log log chart
|
||||
overallLatencyDistribution.percentileThresholdValue =
|
||||
await getPercentileThresholdValue({
|
||||
eventType,
|
||||
chartType,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
|
@ -52,6 +54,7 @@ export async function getOverallLatencyDistribution({
|
|||
kuery,
|
||||
query,
|
||||
percentileThreshold,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
// finish early if we weren't able to identify the percentileThresholdValue.
|
||||
|
@ -61,13 +64,14 @@ export async function getOverallLatencyDistribution({
|
|||
|
||||
// #2: get histogram range steps
|
||||
const rangeSteps = await fetchDurationHistogramRangeSteps({
|
||||
eventType,
|
||||
chartType,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
if (!rangeSteps) {
|
||||
|
@ -77,7 +81,7 @@ export async function getOverallLatencyDistribution({
|
|||
// #3: get histogram chart data
|
||||
|
||||
const { totalDocCount, durationRanges } = await fetchDurationRanges({
|
||||
eventType,
|
||||
chartType,
|
||||
setup,
|
||||
start,
|
||||
end,
|
||||
|
@ -85,6 +89,7 @@ export async function getOverallLatencyDistribution({
|
|||
kuery,
|
||||
query,
|
||||
rangeSteps,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
overallLatencyDistribution.totalDocCount = totalDocCount;
|
||||
|
|
|
@ -6,32 +6,35 @@
|
|||
*/
|
||||
|
||||
import { CommonCorrelationsQueryParams } from '../../../common/correlations/types';
|
||||
import { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { LatencyDistributionChartType } from '../../../common/latency_distribution_chart_types';
|
||||
import { Setup } from '../../lib/helpers/setup_request';
|
||||
import { fetchDurationPercentiles } from '../correlations/queries/fetch_duration_percentiles';
|
||||
|
||||
export async function getPercentileThresholdValue({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
percentileThreshold,
|
||||
searchMetrics,
|
||||
}: CommonCorrelationsQueryParams & {
|
||||
setup: Setup;
|
||||
eventType: ProcessorEvent;
|
||||
chartType: LatencyDistributionChartType;
|
||||
percentileThreshold: number;
|
||||
searchMetrics: boolean;
|
||||
}) {
|
||||
const durationPercentiles = await fetchDurationPercentiles({
|
||||
setup,
|
||||
eventType,
|
||||
chartType,
|
||||
start,
|
||||
end,
|
||||
environment,
|
||||
kuery,
|
||||
query,
|
||||
searchMetrics,
|
||||
});
|
||||
|
||||
return durationPercentiles.percentiles[`${percentileThreshold}.0`];
|
||||
|
|
|
@ -11,6 +11,7 @@ import { termQuery } from '@kbn/observability-plugin/server';
|
|||
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { getOverallLatencyDistribution } from './get_overall_latency_distribution';
|
||||
import { setupRequest } from '../../lib/helpers/setup_request';
|
||||
import { getSearchAggregatedTransactions } from '../../lib/helpers/transactions';
|
||||
import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
|
||||
import { environmentRt, kueryRt, rangeRt } from '../default_api_types';
|
||||
import {
|
||||
|
@ -18,7 +19,10 @@ import {
|
|||
TRANSACTION_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { ProcessorEvent } from '../../../common/processor_event';
|
||||
import {
|
||||
latencyDistributionChartTypeRt,
|
||||
LatencyDistributionChartType,
|
||||
} from '../../../common/latency_distribution_chart_types';
|
||||
|
||||
const latencyOverallTransactionDistributionRoute = createApmServerRoute({
|
||||
endpoint: 'POST /internal/apm/latency/overall_distribution/transactions',
|
||||
|
@ -40,6 +44,7 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({
|
|||
rangeRt,
|
||||
t.type({
|
||||
percentileThreshold: toNumberRt,
|
||||
chartType: latencyDistributionChartTypeRt,
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
|
@ -59,11 +64,23 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({
|
|||
end,
|
||||
percentileThreshold,
|
||||
termFilters,
|
||||
chartType,
|
||||
} = resources.params.body;
|
||||
|
||||
// only the transaction latency distribution chart can use metrics data
|
||||
const searchAggregatedTransactions =
|
||||
chartType === LatencyDistributionChartType.transactionLatency
|
||||
? await getSearchAggregatedTransactions({
|
||||
...setup,
|
||||
kuery,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
: false;
|
||||
|
||||
return getOverallLatencyDistribution({
|
||||
setup,
|
||||
eventType: ProcessorEvent.transaction,
|
||||
chartType,
|
||||
environment,
|
||||
kuery,
|
||||
start,
|
||||
|
@ -82,6 +99,7 @@ const latencyOverallTransactionDistributionRoute = createApmServerRoute({
|
|||
},
|
||||
},
|
||||
percentileThreshold,
|
||||
searchMetrics: searchAggregatedTransactions,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -10,6 +10,7 @@ import expect from '@kbn/expect';
|
|||
import type { FailedTransactionsCorrelationsResponse } from '@kbn/apm-plugin/common/correlations/failed_transactions_correlations/types';
|
||||
import { EVENT_OUTCOME } from '@kbn/apm-plugin/common/elasticsearch_fieldnames';
|
||||
import { EventOutcome } from '@kbn/apm-plugin/common/event_outcome';
|
||||
import { LatencyDistributionChartType } from '@kbn/apm-plugin/common/latency_distribution_chart_types';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
// These tests go through the full sequence of queries required
|
||||
|
@ -34,6 +35,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
body: {
|
||||
...getOptions(),
|
||||
percentileThreshold: 95,
|
||||
chartType: LatencyDistributionChartType.failedTransactionsCorrelations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -50,6 +52,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
...getOptions(),
|
||||
percentileThreshold: 95,
|
||||
termFilters: [{ fieldName: EVENT_OUTCOME, fieldValue: EventOutcome.failure }],
|
||||
chartType: LatencyDistributionChartType.failedTransactionsCorrelations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -109,6 +112,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
body: {
|
||||
...getOptions(),
|
||||
percentileThreshold: 95,
|
||||
chartType: LatencyDistributionChartType.failedTransactionsCorrelations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -125,6 +129,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
...getOptions(),
|
||||
percentileThreshold: 95,
|
||||
termFilters: [{ fieldName: EVENT_OUTCOME, fieldValue: EventOutcome.failure }],
|
||||
chartType: LatencyDistributionChartType.failedTransactionsCorrelations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -13,6 +13,7 @@ import type {
|
|||
LatencyCorrelation,
|
||||
LatencyCorrelationsResponse,
|
||||
} from '@kbn/apm-plugin/common/correlations/latency_correlations/types';
|
||||
import { LatencyDistributionChartType } from '@kbn/apm-plugin/common/latency_distribution_chart_types';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
// These tests go through the full sequence of queries required
|
||||
|
@ -40,6 +41,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
body: {
|
||||
...getOptions(),
|
||||
percentileThreshold: 95,
|
||||
chartType: LatencyDistributionChartType.latencyCorrelations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -117,6 +119,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
body: {
|
||||
...getOptions(),
|
||||
percentileThreshold: 95,
|
||||
chartType: LatencyDistributionChartType.latencyCorrelations,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { LatencyDistributionChartType } from '@kbn/apm-plugin/common/latency_distribution_chart_types';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
export default function ApiTest({ getService }: FtrProviderContext) {
|
||||
|
@ -23,6 +24,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
end: '2021',
|
||||
kuery: '',
|
||||
percentileThreshold: 95,
|
||||
chartType: LatencyDistributionChartType.transactionLatency,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue