diff --git a/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/constants.ts b/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/constants.ts
index 09e3e22a1d352..8a838360b3d44 100644
--- a/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/constants.ts
+++ b/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/constants.ts
@@ -7,23 +7,17 @@
import { i18n } from '@kbn/i18n';
-export const FAILED_TRANSACTIONS_IMPACT_THRESHOLD = {
- HIGH: i18n.translate(
- 'xpack.apm.correlations.failedTransactions.highImpactText',
- {
- defaultMessage: 'High',
- }
- ),
- MEDIUM: i18n.translate(
- 'xpack.apm.correlations.failedTransactions.mediumImpactText',
- {
- defaultMessage: 'Medium',
- }
- ),
- LOW: i18n.translate(
- 'xpack.apm.correlations.failedTransactions.lowImpactText',
- {
- defaultMessage: 'Low',
- }
- ),
+export const CORRELATIONS_IMPACT_THRESHOLD = {
+ HIGH: i18n.translate('xpack.apm.correlations.highImpactText', {
+ defaultMessage: 'High',
+ }),
+ MEDIUM: i18n.translate('xpack.apm.correlations.mediumImpactText', {
+ defaultMessage: 'Medium',
+ }),
+ LOW: i18n.translate('xpack.apm.correlations.lowImpactText', {
+ defaultMessage: 'Low',
+ }),
+ VERY_LOW: i18n.translate('xpack.apm.correlations.veryLowImpactText', {
+ defaultMessage: 'Very low',
+ }),
} as const;
diff --git a/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/types.ts b/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/types.ts
index 8b09d45c1e1b6..e63d3d6faa92e 100644
--- a/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/types.ts
+++ b/x-pack/plugins/apm/common/correlations/failed_transactions_correlations/types.ts
@@ -7,7 +7,7 @@
import { FieldValuePair, HistogramItem } from '../types';
-import { FAILED_TRANSACTIONS_IMPACT_THRESHOLD } from './constants';
+import { CORRELATIONS_IMPACT_THRESHOLD } from './constants';
import { FieldStats } from '../field_stats_types';
export interface FailedTransactionsCorrelation extends FieldValuePair {
@@ -22,7 +22,7 @@ export interface FailedTransactionsCorrelation extends FieldValuePair {
}
export type FailedTransactionsCorrelationsImpactThreshold =
- typeof FAILED_TRANSACTIONS_IMPACT_THRESHOLD[keyof typeof FAILED_TRANSACTIONS_IMPACT_THRESHOLD];
+ typeof CORRELATIONS_IMPACT_THRESHOLD[keyof typeof CORRELATIONS_IMPACT_THRESHOLD];
export interface FailedTransactionsCorrelationsResponse {
ccsWarning: boolean;
@@ -31,4 +31,5 @@ export interface FailedTransactionsCorrelationsResponse {
overallHistogram?: HistogramItem[];
errorHistogram?: HistogramItem[];
fieldStats?: FieldStats[];
+ fallbackResult?: FailedTransactionsCorrelation;
}
diff --git a/x-pack/plugins/apm/common/correlations/latency_correlations/types.ts b/x-pack/plugins/apm/common/correlations/latency_correlations/types.ts
index 23c91554b6547..cf20490774e18 100644
--- a/x-pack/plugins/apm/common/correlations/latency_correlations/types.ts
+++ b/x-pack/plugins/apm/common/correlations/latency_correlations/types.ts
@@ -10,8 +10,9 @@ import { FieldStats } from '../field_stats_types';
export interface LatencyCorrelation extends FieldValuePair {
correlation: number;
- histogram: HistogramItem[];
+ histogram?: HistogramItem[];
ksTest: number;
+ isFallbackResult?: boolean;
}
export interface LatencyCorrelationsResponse {
diff --git a/x-pack/plugins/apm/common/correlations/types.ts b/x-pack/plugins/apm/common/correlations/types.ts
index 402750b72b2ab..6884d8c627fd0 100644
--- a/x-pack/plugins/apm/common/correlations/types.ts
+++ b/x-pack/plugins/apm/common/correlations/types.ts
@@ -11,6 +11,7 @@ export interface FieldValuePair {
// but for example `http.response.status_code` which is part of
// of the list of predefined field candidates is of type long/number.
fieldValue: string | number;
+ isFallbackResult?: boolean;
}
export interface HistogramItem {
diff --git a/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx b/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx
index 6d20faae89a10..c970838f8b8c3 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/failed_transactions_correlations.tsx
@@ -28,7 +28,10 @@ import { i18n } from '@kbn/i18n';
import { useUiTracker } from '../../../../../observability/public';
-import { asPercent } from '../../../../common/utils/formatters';
+import {
+ asPercent,
+ asPreciseDecimal,
+} from '../../../../common/utils/formatters';
import { FailedTransactionsCorrelation } from '../../../../common/correlations/failed_transactions_correlations/types';
import { FieldStats } from '../../../../common/correlations/field_stats_types';
@@ -36,8 +39,6 @@ import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_
import { useLocalStorage } from '../../../hooks/use_local_storage';
import { FETCH_STATUS } from '../../../hooks/use_fetcher';
import { useTheme } from '../../../hooks/use_theme';
-
-import { ImpactBar } from '../../shared/impact_bar';
import { push } from '../../shared/links/url_helpers';
import { CorrelationsTable } from './correlations_table';
@@ -229,21 +230,33 @@ export function FailedTransactionsCorrelations({
width: '116px',
field: 'normalizedScore',
name: (
- <>
- {i18n.translate(
- 'xpack.apm.correlations.failedTransactions.correlationsTable.scoreLabel',
+
- ),
- render: (_, { normalizedScore }) => {
- return (
+ >
<>
-
+ {i18n.translate(
+ 'xpack.apm.correlations.failedTransactions.correlationsTable.scoreLabel',
+ {
+ defaultMessage: 'Score',
+ }
+ )}
+
>
- );
+
+ ),
+ render: (_, { normalizedScore }) => {
+ return
{asPreciseDecimal(normalizedScore, 2)}
;
},
sortable: true,
},
@@ -260,8 +273,11 @@ export function FailedTransactionsCorrelations({
)}
>
),
- render: (_, { pValue }) => {
- const label = getFailedTransactionsCorrelationImpactLabel(pValue);
+ render: (_, { pValue, isFallbackResult }) => {
+ const label = getFailedTransactionsCorrelationImpactLabel(
+ pValue,
+ isFallbackResult
+ );
return label ? (
{label.impact}
) : null;
@@ -377,18 +393,30 @@ export function FailedTransactionsCorrelations({
sort: { field: sortField, direction: sortDirection },
};
- const correlationTerms = useMemo(
- () =>
- orderBy(
- response.failedTransactionsCorrelations,
- // The smaller the p value the higher the impact
- // So we want to sort by the normalized score here
- // which goes from 0 -> 1
- sortField === 'pValue' ? 'normalizedScore' : sortField,
- sortDirection
- ),
- [response.failedTransactionsCorrelations, sortField, sortDirection]
- );
+ const correlationTerms = useMemo(() => {
+ if (
+ progress.loaded === 1 &&
+ response?.failedTransactionsCorrelations?.length === 0 &&
+ response.fallbackResult !== undefined
+ ) {
+ return [{ ...response.fallbackResult, isFallbackResult: true }];
+ }
+
+ return orderBy(
+ response.failedTransactionsCorrelations,
+ // The smaller the p value the higher the impact
+ // So we want to sort by the normalized score here
+ // which goes from 0 -> 1
+ sortField === 'pValue' ? 'normalizedScore' : sortField,
+ sortDirection
+ );
+ }, [
+ response.failedTransactionsCorrelations,
+ response.fallbackResult,
+ progress.loaded,
+ sortField,
+ sortDirection,
+ ]);
const [pinnedSignificantTerm, setPinnedSignificantTerm] =
useState(null);
diff --git a/x-pack/plugins/apm/public/components/app/correlations/get_transaction_distribution_chart_data.ts b/x-pack/plugins/apm/public/components/app/correlations/get_transaction_distribution_chart_data.ts
index 49ddd8aec0fe4..12799e5edc726 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/get_transaction_distribution_chart_data.ts
+++ b/x-pack/plugins/apm/public/components/app/correlations/get_transaction_distribution_chart_data.ts
@@ -7,11 +7,10 @@
import { i18n } from '@kbn/i18n';
import { EuiTheme } from '../../../../../../../src/plugins/kibana_react/common';
-import type {
- FieldValuePair,
- HistogramItem,
-} from '../../../../common/correlations/types';
+import type { HistogramItem } from '../../../../common/correlations/types';
import { TransactionDistributionChartData } from '../../shared/charts/transaction_distribution_chart';
+import { LatencyCorrelation } from '../../../../common/correlations/latency_correlations/types';
+import { FailedTransactionsCorrelation } from '../../../../common/correlations/failed_transactions_correlations/types';
export function getTransactionDistributionChartData({
euiTheme,
@@ -22,7 +21,7 @@ export function getTransactionDistributionChartData({
euiTheme: EuiTheme;
allTransactionsHistogram?: HistogramItem[];
failedTransactionsHistogram?: HistogramItem[];
- selectedTerm?: FieldValuePair & { histogram: HistogramItem[] };
+ selectedTerm?: LatencyCorrelation | FailedTransactionsCorrelation | undefined;
}) {
const transactionDistributionChartData: TransactionDistributionChartData[] =
[];
diff --git a/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx b/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx
index 5b37a14b4e4e5..f3734dae5d247 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx
+++ b/x-pack/plugins/apm/public/components/app/correlations/latency_correlations.tsx
@@ -17,12 +17,14 @@ import {
EuiSpacer,
EuiTitle,
EuiToolTip,
+ EuiBadge,
} from '@elastic/eui';
import { Direction } from '@elastic/eui/src/services/sort/sort_direction';
import { EuiTableSortingType } from '@elastic/eui/src/components/basic_table/table_types';
import { i18n } from '@kbn/i18n';
+import { FormattedMessage } from '@kbn/i18n-react';
import { useUiTracker } from '../../../../../observability/public';
import { asPreciseDecimal } from '../../../../common/utils/formatters';
@@ -48,6 +50,18 @@ import { getTransactionDistributionChartData } from './get_transaction_distribut
import { useTheme } from '../../../hooks/use_theme';
import { ChartTitleToolTip } from './chart_title_tool_tip';
import { MIN_TAB_TITLE_HEIGHT } from '../transaction_details/distribution';
+import { getLatencyCorrelationImpactLabel } from './utils/get_failed_transactions_correlation_impact_label';
+
+export function FallbackCorrelationBadge() {
+ return (
+
+
+
+ );
+}
export function LatencyCorrelations({ onFilter }: { onFilter: () => void }) {
const {
@@ -151,6 +165,31 @@ export function LatencyCorrelations({ onFilter }: { onFilter: () => void }) {
},
sortable: true,
},
+ {
+ width: '116px',
+ field: 'pValue',
+ name: (
+ <>
+ {i18n.translate(
+ 'xpack.apm.correlations.failedTransactions.correlationsTable.impactLabel',
+ {
+ defaultMessage: 'Impact',
+ }
+ )}
+ >
+ ),
+ render: (_, { correlation, isFallbackResult }) => {
+ const label = getLatencyCorrelationImpactLabel(
+ correlation,
+ isFallbackResult
+ );
+ return label ? (
+ {label.impact}
+ ) : null;
+ },
+ sortable: true,
+ },
+
{
field: 'fieldName',
name: i18n.translate(
diff --git a/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.ts b/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.ts
index 41a2afada6e65..26f63e1ab0c59 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.ts
+++ b/x-pack/plugins/apm/public/components/app/correlations/use_failed_transactions_correlations.ts
@@ -77,6 +77,7 @@ export function useFailedTransactionsCorrelations() {
// and histogram data for statistically significant results.
const responseUpdate: FailedTransactionsCorrelationsResponse = {
ccsWarning: false,
+ fallbackResult: undefined,
};
const [overallHistogramResponse, errorHistogramRespone] =
@@ -149,6 +150,7 @@ export function useFailedTransactionsCorrelations() {
const failedTransactionsCorrelations: FailedTransactionsCorrelation[] =
[];
+ let fallbackResult: FailedTransactionsCorrelation | undefined;
const fieldsToSample = new Set();
const chunkSize = 10;
let chunkLoadCounter = 0;
@@ -177,6 +179,21 @@ export function useFailedTransactionsCorrelations() {
getFailedTransactionsCorrelationsSortedByScore([
...failedTransactionsCorrelations,
]);
+ } else {
+ // If there's no significant correlations found and there's a fallback result
+ // Update the highest ranked/scored fall back result
+ if (pValues.fallbackResult) {
+ if (!fallbackResult) {
+ fallbackResult = pValues.fallbackResult;
+ } else {
+ if (
+ pValues.fallbackResult.normalizedScore >
+ fallbackResult.normalizedScore
+ ) {
+ fallbackResult = pValues.fallbackResult;
+ }
+ }
+ }
}
chunkLoadCounter++;
@@ -209,7 +226,12 @@ export function useFailedTransactionsCorrelations() {
);
responseUpdate.fieldStats = stats;
- setResponse({ ...responseUpdate, loaded: LOADED_DONE, isRunning: false });
+ setResponse({
+ ...responseUpdate,
+ fallbackResult,
+ loaded: LOADED_DONE,
+ isRunning: false,
+ });
setResponse.flush();
} catch (e) {
if (!abortCtrl.current.signal.aborted) {
diff --git a/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.ts b/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.ts
index 0e166344d0dec..428fdcda7cfc6 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.ts
+++ b/x-pack/plugins/apm/public/components/app/correlations/use_latency_correlations.ts
@@ -177,6 +177,7 @@ export function useLatencyCorrelations() {
chunkSize
);
+ const fallbackResults: LatencyCorrelation[] = [];
for (const fieldValuePairChunk of fieldValuePairChunks) {
const significantCorrelations = await callApmApi(
'POST /internal/apm/correlations/significant_correlations',
@@ -197,6 +198,12 @@ export function useLatencyCorrelations() {
);
responseUpdate.latencyCorrelations =
getLatencyCorrelationsSortedByCorrelation([...latencyCorrelations]);
+ } else {
+ // If there's no correlation results that matches the criteria
+ // Consider the fallback results
+ if (significantCorrelations.fallbackResult) {
+ fallbackResults.push(significantCorrelations.fallbackResult);
+ }
}
chunkLoadCounter++;
@@ -213,6 +220,23 @@ export function useLatencyCorrelations() {
}
}
+ if (latencyCorrelations.length === 0 && fallbackResults.length > 0) {
+ // Rank the fallback results and show at least one value
+ const sortedFallbackResults = fallbackResults
+ .filter((r) => r.correlation > 0)
+ .sort((a, b) => b.correlation - a.correlation);
+
+ responseUpdate.latencyCorrelations = sortedFallbackResults
+ .slice(0, 1)
+ .map((r) => ({ ...r, isFallbackResult: true }));
+ setResponse({
+ ...responseUpdate,
+ loaded:
+ LOADED_FIELD_VALUE_PAIRS +
+ (chunkLoadCounter / fieldValuePairChunks.length) *
+ PROGRESS_STEP_CORRELATIONS,
+ });
+ }
setResponse.flush();
const { stats } = await callApmApi(
diff --git a/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.test.ts b/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.test.ts
index d35833295703f..b85121ea94a9c 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.test.ts
+++ b/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.test.ts
@@ -6,19 +6,19 @@
*/
import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label';
-import { FAILED_TRANSACTIONS_IMPACT_THRESHOLD } from '../../../../../common/correlations/failed_transactions_correlations/constants';
+import { CORRELATIONS_IMPACT_THRESHOLD } from '../../../../../common/correlations/failed_transactions_correlations/constants';
const EXPECTED_RESULT = {
HIGH: {
- impact: FAILED_TRANSACTIONS_IMPACT_THRESHOLD.HIGH,
+ impact: CORRELATIONS_IMPACT_THRESHOLD.HIGH,
color: 'danger',
},
MEDIUM: {
- impact: FAILED_TRANSACTIONS_IMPACT_THRESHOLD.MEDIUM,
+ impact: CORRELATIONS_IMPACT_THRESHOLD.MEDIUM,
color: 'warning',
},
LOW: {
- impact: FAILED_TRANSACTIONS_IMPACT_THRESHOLD.LOW,
+ impact: CORRELATIONS_IMPACT_THRESHOLD.LOW,
color: 'default',
},
};
diff --git a/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.ts b/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.ts
index d5d0fd4dcae51..556c13d7467bb 100644
--- a/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.ts
+++ b/x-pack/plugins/apm/public/components/app/correlations/utils/get_failed_transactions_correlation_impact_label.ts
@@ -9,10 +9,11 @@ import {
FailedTransactionsCorrelation,
FailedTransactionsCorrelationsImpactThreshold,
} from '../../../../../common/correlations/failed_transactions_correlations/types';
-import { FAILED_TRANSACTIONS_IMPACT_THRESHOLD } from '../../../../../common/correlations/failed_transactions_correlations/constants';
+import { CORRELATIONS_IMPACT_THRESHOLD } from '../../../../../common/correlations/failed_transactions_correlations/constants';
export function getFailedTransactionsCorrelationImpactLabel(
- pValue: FailedTransactionsCorrelation['pValue']
+ pValue: FailedTransactionsCorrelation['pValue'],
+ isFallbackResult?: boolean
): {
impact: FailedTransactionsCorrelationsImpactThreshold;
color: string;
@@ -21,22 +22,64 @@ export function getFailedTransactionsCorrelationImpactLabel(
return null;
}
+ if (isFallbackResult)
+ return {
+ impact: CORRELATIONS_IMPACT_THRESHOLD.VERY_LOW,
+ color: 'default',
+ };
+
// The lower the p value, the higher the impact
if (pValue >= 0 && pValue < 1e-6)
return {
- impact: FAILED_TRANSACTIONS_IMPACT_THRESHOLD.HIGH,
+ impact: CORRELATIONS_IMPACT_THRESHOLD.HIGH,
color: 'danger',
};
if (pValue >= 1e-6 && pValue < 0.001)
return {
- impact: FAILED_TRANSACTIONS_IMPACT_THRESHOLD.MEDIUM,
+ impact: CORRELATIONS_IMPACT_THRESHOLD.MEDIUM,
color: 'warning',
};
if (pValue >= 0.001 && pValue < 0.02)
return {
- impact: FAILED_TRANSACTIONS_IMPACT_THRESHOLD.LOW,
+ impact: CORRELATIONS_IMPACT_THRESHOLD.LOW,
+ color: 'default',
+ };
+
+ return null;
+}
+
+export function getLatencyCorrelationImpactLabel(
+ correlation: FailedTransactionsCorrelation['pValue'],
+ isFallbackResult?: boolean
+): {
+ impact: FailedTransactionsCorrelationsImpactThreshold;
+ color: string;
+} | null {
+ if (correlation === null || correlation < 0) {
+ return null;
+ }
+
+ // The lower the p value, the higher the impact
+ if (isFallbackResult)
+ return {
+ impact: CORRELATIONS_IMPACT_THRESHOLD.VERY_LOW,
+ color: 'default',
+ };
+ if (correlation < 0.4)
+ return {
+ impact: CORRELATIONS_IMPACT_THRESHOLD.LOW,
color: 'default',
};
+ if (correlation < 0.6)
+ return {
+ impact: CORRELATIONS_IMPACT_THRESHOLD.MEDIUM,
+ color: 'warning',
+ };
+ if (correlation < 1)
+ return {
+ impact: CORRELATIONS_IMPACT_THRESHOLD.HIGH,
+ color: 'danger',
+ };
return null;
}
diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.ts
index 03b28b28d521a..5c6b8f3594aa0 100644
--- a/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.ts
+++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_correlation_with_histogram.ts
@@ -32,7 +32,7 @@ export async function fetchTransactionDurationCorrelationWithHistogram(
histogramRangeSteps: number[],
totalDocCount: number,
fieldValuePair: FieldValuePair
-): Promise {
+) {
const { correlation, ksTest } = await fetchTransactionDurationCorrelation(
esClient,
params,
@@ -43,23 +43,28 @@ export async function fetchTransactionDurationCorrelationWithHistogram(
[fieldValuePair]
);
- if (
- correlation !== null &&
- correlation > CORRELATION_THRESHOLD &&
- ksTest !== null &&
- ksTest < KS_TEST_THRESHOLD
- ) {
- const logHistogram = await fetchTransactionDurationRanges(
- esClient,
- params,
- histogramRangeSteps,
- [fieldValuePair]
- );
- return {
- ...fieldValuePair,
- correlation,
- ksTest,
- histogram: logHistogram,
- };
+ if (correlation !== null && ksTest !== null && !isNaN(ksTest)) {
+ if (correlation > CORRELATION_THRESHOLD && ksTest < KS_TEST_THRESHOLD) {
+ const logHistogram = await fetchTransactionDurationRanges(
+ esClient,
+ params,
+ histogramRangeSteps,
+ [fieldValuePair]
+ );
+ return {
+ ...fieldValuePair,
+ correlation,
+ ksTest,
+ histogram: logHistogram,
+ } as LatencyCorrelation;
+ } else {
+ return {
+ ...fieldValuePair,
+ correlation,
+ ksTest,
+ } as Omit;
+ }
}
+
+ return undefined;
}
diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_p_values.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_p_values.ts
index 7c471aebd0f7a..ee59925c47f27 100644
--- a/x-pack/plugins/apm/server/routes/correlations/queries/query_p_values.ts
+++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_p_values.ts
@@ -41,18 +41,39 @@ export const fetchPValues = async (
)
);
- const failedTransactionsCorrelations: FailedTransactionsCorrelation[] =
- fulfilled
- .flat()
- .filter(
- (record) =>
- record &&
- typeof record.pValue === 'number' &&
- record.pValue < ERROR_CORRELATION_THRESHOLD
- );
+ const flattenedResults = fulfilled.flat();
+
+ const failedTransactionsCorrelations: FailedTransactionsCorrelation[] = [];
+ let fallbackResult: FailedTransactionsCorrelation | undefined;
+
+ flattenedResults.forEach((record) => {
+ if (
+ record &&
+ typeof record.pValue === 'number' &&
+ record.pValue < ERROR_CORRELATION_THRESHOLD
+ ) {
+ failedTransactionsCorrelations.push(record);
+ } else {
+ // If there's no result matching the criteria
+ // Find the next highest/closest result to the threshold
+ // to use as a fallback result
+ if (!fallbackResult) {
+ fallbackResult = record;
+ } else {
+ if (
+ record.pValue !== null &&
+ fallbackResult &&
+ fallbackResult.pValue !== null &&
+ record.pValue < fallbackResult.pValue
+ ) {
+ fallbackResult = record;
+ }
+ }
+ }
+ });
const ccsWarning =
rejected.length > 0 && paramsWithIndex?.index.includes(':');
- return { failedTransactionsCorrelations, ccsWarning };
+ return { failedTransactionsCorrelations, ccsWarning, fallbackResult };
};
diff --git a/x-pack/plugins/apm/server/routes/correlations/queries/query_significant_correlations.ts b/x-pack/plugins/apm/server/routes/correlations/queries/query_significant_correlations.ts
index ed5ad1c278143..2fc1e69eab356 100644
--- a/x-pack/plugins/apm/server/routes/correlations/queries/query_significant_correlations.ts
+++ b/x-pack/plugins/apm/server/routes/correlations/queries/query_significant_correlations.ts
@@ -13,7 +13,7 @@ import type {
FieldValuePair,
CorrelationsParams,
} from '../../../../common/correlations/types';
-import { LatencyCorrelation } from '../../../../common/correlations/latency_correlations/types';
+import type { LatencyCorrelation } from '../../../../common/correlations/latency_correlations/types';
import {
computeExpectationsAndRanges,
@@ -25,6 +25,7 @@ import {
fetchTransactionDurationFractions,
fetchTransactionDurationHistogramRangeSteps,
fetchTransactionDurationPercentiles,
+ fetchTransactionDurationRanges,
} from './index';
export const fetchSignificantCorrelations = async (
@@ -76,12 +77,54 @@ export const fetchSignificantCorrelations = async (
)
);
- const latencyCorrelations: LatencyCorrelation[] = fulfilled.filter(
- (d): d is LatencyCorrelation => d !== undefined
- );
+ const latencyCorrelations = fulfilled.filter(
+ (d) => d && 'histogram' in d
+ ) as LatencyCorrelation[];
+ let fallbackResult: LatencyCorrelation | undefined =
+ latencyCorrelations.length > 0
+ ? undefined
+ : fulfilled
+ .filter((d) => !(d as LatencyCorrelation)?.histogram)
+ .reduce((d, result) => {
+ if (d?.correlation !== undefined) {
+ if (!result) {
+ result = d?.correlation > 0 ? d : undefined;
+ } else {
+ if (
+ d.correlation > 0 &&
+ d.ksTest > result.ksTest &&
+ d.correlation > result.correlation
+ ) {
+ result = d;
+ }
+ }
+ }
+ return result;
+ }, undefined);
+ if (latencyCorrelations.length === 0 && fallbackResult) {
+ const { fieldName, fieldValue } = fallbackResult;
+ const logHistogram = await fetchTransactionDurationRanges(
+ esClient,
+ paramsWithIndex,
+ histogramRangeSteps,
+ [{ fieldName, fieldValue }]
+ );
+
+ if (fallbackResult) {
+ fallbackResult = {
+ ...fallbackResult,
+ histogram: logHistogram,
+ };
+ }
+ }
const ccsWarning =
rejected.length > 0 && paramsWithIndex?.index.includes(':');
- return { latencyCorrelations, ccsWarning, totalDocCount };
+ return {
+ latencyCorrelations,
+ ccsWarning,
+ totalDocCount,
+ fallbackResult,
+ };
};
diff --git a/x-pack/plugins/apm/server/routes/correlations/route.ts b/x-pack/plugins/apm/server/routes/correlations/route.ts
index fd0bce7a62ff8..b0735c7c57b36 100644
--- a/x-pack/plugins/apm/server/routes/correlations/route.ts
+++ b/x-pack/plugins/apm/server/routes/correlations/route.ts
@@ -257,6 +257,7 @@ const significantCorrelationsRoute = createApmServerRoute({
>;
ccsWarning: boolean;
totalDocCount: number;
+ fallbackResult?: import('./../../../common/correlations/latency_correlations/types').LatencyCorrelation;
}> => {
const { context } = resources;
if (!isActivePlatinumLicense(context.licensing.license)) {
@@ -314,6 +315,7 @@ const pValuesRoute = createApmServerRoute({
import('./../../../common/correlations/failed_transactions_correlations/types').FailedTransactionsCorrelation
>;
ccsWarning: boolean;
+ fallbackResult?: import('./../../../common/correlations/failed_transactions_correlations/types').FailedTransactionsCorrelation;
}> => {
const { context } = resources;
if (!isActivePlatinumLicense(context.licensing.license)) {
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index b7240d8653f90..3aaea1021494d 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -5920,9 +5920,6 @@
"xpack.apm.correlations.failedTransactions.correlationsTable.impactLabel": "Impact",
"xpack.apm.correlations.failedTransactions.correlationsTable.pValueLabel": "Score",
"xpack.apm.correlations.failedTransactions.errorTitle": "Une erreur est survenue lors de l'exécution de corrélations sur les transactions ayant échoué",
- "xpack.apm.correlations.failedTransactions.highImpactText": "Élevé",
- "xpack.apm.correlations.failedTransactions.lowImpactText": "Bas",
- "xpack.apm.correlations.failedTransactions.mediumImpactText": "Moyen",
"xpack.apm.correlations.failedTransactions.panelTitle": "Transactions ayant échoué",
"xpack.apm.correlations.latencyCorrelations.correlationsTable.actionsLabel": "Filtre",
"xpack.apm.correlations.latencyCorrelations.correlationsTable.correlationColumnDescription": "Score de corrélation [0-1] d'un attribut ; plus le score est élevé, plus un attribut augmente la latence.",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 5a710d8f2c0df..22f1777bd67cc 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -6912,9 +6912,9 @@
"xpack.apm.correlations.failedTransactions.helpPopover.performanceExplanation": "この分析は多数の属性に対して統計検索を実行します。広い時間範囲やトランザクションスループットが高いサービスでは、時間がかかる場合があります。パフォーマンスを改善するには、時間範囲を絞り込みます。",
"xpack.apm.correlations.failedTransactions.helpPopover.tableExplanation": "表はスコア別に並べ替えられます。これは高、中、低影響度にマッピングされます。影響度が高い属性は、失敗したトランザクションの原因である可能性が高くなります。",
"xpack.apm.correlations.failedTransactions.helpPopover.title": "失敗したトランザクションの相関関係",
- "xpack.apm.correlations.failedTransactions.highImpactText": "高",
- "xpack.apm.correlations.failedTransactions.lowImpactText": "低",
- "xpack.apm.correlations.failedTransactions.mediumImpactText": "中",
+ "xpack.apm.correlations.highImpactText": "高",
+ "xpack.apm.correlations.lowImpactText": "低",
+ "xpack.apm.correlations.mediumImpactText": "中",
"xpack.apm.correlations.failedTransactions.panelTitle": "失敗したトランザクションの遅延分布",
"xpack.apm.correlations.failedTransactions.tableTitle": "相関関係",
"xpack.apm.correlations.fieldContextPopover.addFilterAriaLabel": "{fieldName}のフィルター:\"{value}\"",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 15ab16a10fe54..e270a12c50ef3 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -6927,9 +6927,9 @@
"xpack.apm.correlations.failedTransactions.helpPopover.performanceExplanation": "此分析会对大量属性执行统计搜索。对于较大时间范围和具有高事务吞吐量的服务,这可能需要些时间。减少时间范围以改善性能。",
"xpack.apm.correlations.failedTransactions.helpPopover.tableExplanation": "表按分数排序,分数映射高、中或低影响级别。具有高影响级别的属性更可能造成事务失败。",
"xpack.apm.correlations.failedTransactions.helpPopover.title": "失败事务相关性",
- "xpack.apm.correlations.failedTransactions.highImpactText": "高",
- "xpack.apm.correlations.failedTransactions.lowImpactText": "低",
- "xpack.apm.correlations.failedTransactions.mediumImpactText": "中",
+ "xpack.apm.correlations.highImpactText": "高",
+ "xpack.apm.correlations.lowImpactText": "低",
+ "xpack.apm.correlations.mediumImpactText": "中",
"xpack.apm.correlations.failedTransactions.panelTitle": "失败事务延迟分布",
"xpack.apm.correlations.failedTransactions.tableTitle": "相关性",
"xpack.apm.correlations.fieldContextPopover.addFilterAriaLabel": "筛留 {fieldName}:“{value}”",
diff --git a/x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts b/x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts
index e5062961e2f2c..1cdd59777c1c5 100644
--- a/x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/correlations/latency.spec.ts
@@ -254,7 +254,7 @@ export default function ApiTest({ getService }: FtrProviderContext) {
expect(correlation?.fieldValue).to.be('success');
expect(correlation?.correlation).to.be(0.6275246559191225);
expect(correlation?.ksTest).to.be(4.806503252860024e-13);
- expect(correlation?.histogram.length).to.be(101);
+ expect(correlation?.histogram?.length).to.be(101);
const fieldStats = finalRawResponse?.fieldStats?.[0];
expect(typeof fieldStats).to.be('object');