mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ML] Show at least one correlation value and consolidate correlations columns (#126683)
* Remove score column for failed transactions * Show at least one correlated value * Add very low badge for fallback transactions * Match two columns * Update constants & i18n * Update failed transactions * Fix types * Change to immutable * Add tooltip * [ML] Fix types * [ML] Fix translation Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
5b682e093c
commit
3a4c6de7a5
19 changed files with 328 additions and 108 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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',
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.apm.correlations.failedTransactions.correlationsTable.scoreTooltip',
|
||||
{
|
||||
defaultMessage: 'Score',
|
||||
defaultMessage:
|
||||
'The score [0-1] of an attribute; the greater the score, the more an attribute contributes to failed transactions.',
|
||||
}
|
||||
)}
|
||||
</>
|
||||
>
|
||||
<>
|
||||
{i18n.translate(
|
||||
'xpack.apm.correlations.failedTransactions.correlationsTable.scoreLabel',
|
||||
{
|
||||
defaultMessage: 'Score',
|
||||
}
|
||||
)}
|
||||
<EuiIcon
|
||||
size="s"
|
||||
color="subdued"
|
||||
type="questionInCircle"
|
||||
className="eui-alignTop"
|
||||
/>
|
||||
</>
|
||||
</EuiToolTip>
|
||||
),
|
||||
render: (_, { normalizedScore }) => {
|
||||
return (
|
||||
<>
|
||||
<ImpactBar size="m" value={normalizedScore * 100} />
|
||||
</>
|
||||
);
|
||||
return <div>{asPreciseDecimal(normalizedScore, 2)}</div>;
|
||||
},
|
||||
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 ? (
|
||||
<EuiBadge color={label.color}>{label.impact}</EuiBadge>
|
||||
) : 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<FailedTransactionsCorrelation | null>(null);
|
||||
|
|
|
@ -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[] =
|
||||
[];
|
||||
|
|
|
@ -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 (
|
||||
<EuiBadge>
|
||||
<FormattedMessage
|
||||
id="xpack.apm.correlations.latencyCorrelations.fallbackCorrelationBadgeMessage"
|
||||
defaultMessage="Very low"
|
||||
/>
|
||||
</EuiBadge>
|
||||
);
|
||||
}
|
||||
|
||||
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 ? (
|
||||
<EuiBadge color={label.color}>{label.impact}</EuiBadge>
|
||||
) : null;
|
||||
},
|
||||
sortable: true,
|
||||
},
|
||||
|
||||
{
|
||||
field: 'fieldName',
|
||||
name: i18n.translate(
|
||||
|
|
|
@ -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<string>();
|
||||
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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export async function fetchTransactionDurationCorrelationWithHistogram(
|
|||
histogramRangeSteps: number[],
|
||||
totalDocCount: number,
|
||||
fieldValuePair: FieldValuePair
|
||||
): Promise<LatencyCorrelation | undefined> {
|
||||
) {
|
||||
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<LatencyCorrelation, 'histogram'>;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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.",
|
||||
|
|
|
@ -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}\"",
|
||||
|
|
|
@ -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}”",
|
||||
|
|
|
@ -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');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue