mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ML] AIOps Log Rate Analysis: Rename SignificantTerm to SignificantItem. (#169756)
Log rate analysis now supports both keywords and log patterns derived from text fields. The type `SignificantTerm` originally was used for the results of the `significant_terms` agg to get the p-values for keyword fields. Since it's now used for both cases (keyword fields and log patterns) this PR renames the type and related variables etc. to `SignificantItem` (we used the wording `item` already in some cases in the context of groups).
This commit is contained in:
parent
33757f64ca
commit
9b29b1898e
66 changed files with 512 additions and 506 deletions
|
@ -18,17 +18,17 @@ export type {
|
|||
NumericHistogramField,
|
||||
} from './src/fetch_histograms_for_fields';
|
||||
export { isMultiBucketAggregate } from './src/is_multi_bucket_aggregate';
|
||||
export { isSignificantTerm } from './src/type_guards';
|
||||
export { SIGNIFICANT_TERM_TYPE } from './src/types';
|
||||
export { isSignificantItem } from './src/type_guards';
|
||||
export { SIGNIFICANT_ITEM_TYPE } from './src/types';
|
||||
export type {
|
||||
AggCardinality,
|
||||
SignificantTerm,
|
||||
SignificantTermGroup,
|
||||
SignificantTermGroupItem,
|
||||
SignificantTermGroupHistogram,
|
||||
SignificantTermHistogram,
|
||||
SignificantTermHistogramItem,
|
||||
SignificantTermType,
|
||||
SignificantItem,
|
||||
SignificantItemGroup,
|
||||
SignificantItemGroupItem,
|
||||
SignificantItemGroupHistogram,
|
||||
SignificantItemHistogram,
|
||||
SignificantItemHistogramItem,
|
||||
SignificantItemType,
|
||||
HistogramField,
|
||||
NumericColumnStats,
|
||||
NumericColumnStatsMap,
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isSignificantTerm } from './type_guards';
|
||||
import { isSignificantItem } from './type_guards';
|
||||
|
||||
describe('isSignificantTerm', () => {
|
||||
it('identifies significant terms', () => {
|
||||
expect(isSignificantTerm({})).toBeFalsy();
|
||||
expect(isSignificantTerm({ fieldName: 'response_code' })).toBeFalsy();
|
||||
expect(isSignificantTerm({ fieldValue: '500' })).toBeFalsy();
|
||||
describe('isSignificantItem', () => {
|
||||
it('identifies significant items', () => {
|
||||
expect(isSignificantItem({})).toBeFalsy();
|
||||
expect(isSignificantItem({ fieldName: 'response_code' })).toBeFalsy();
|
||||
expect(isSignificantItem({ fieldValue: '500' })).toBeFalsy();
|
||||
expect(
|
||||
isSignificantTerm({
|
||||
isSignificantItem({
|
||||
key: 'response_code:500',
|
||||
type: 'keyword',
|
||||
fieldName: 'response_code',
|
||||
|
|
|
@ -7,17 +7,17 @@
|
|||
|
||||
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
||||
|
||||
import type { SignificantTerm } from './types';
|
||||
import type { SignificantItem } from './types';
|
||||
|
||||
/**
|
||||
* Type guard for a significant term.
|
||||
* Type guard for a significant item.
|
||||
* Note this is used as a custom type within Log Rate Analysis
|
||||
* for a p-value based variant, not a generic significant terms
|
||||
* aggregation type.
|
||||
* @param arg The unknown type to be evaluated
|
||||
* @returns whether arg is of type SignificantTerm
|
||||
* @returns whether arg is of type SignificantItem
|
||||
*/
|
||||
export function isSignificantTerm(arg: unknown): arg is SignificantTerm {
|
||||
export function isSignificantItem(arg: unknown): arg is SignificantItem {
|
||||
return isPopulatedObject(arg, [
|
||||
'key',
|
||||
'type',
|
||||
|
|
|
@ -88,25 +88,25 @@ export interface HistogramField {
|
|||
}
|
||||
|
||||
/**
|
||||
* Enumeration of significant term types.
|
||||
* Enumeration of significant item types.
|
||||
*/
|
||||
export const SIGNIFICANT_TERM_TYPE = {
|
||||
export const SIGNIFICANT_ITEM_TYPE = {
|
||||
KEYWORD: 'keyword',
|
||||
LOG_PATTERN: 'log_pattern',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Type for significant term type keys.
|
||||
* Type for significant item type keys.
|
||||
*/
|
||||
type SignificantTermTypeKeys = keyof typeof SIGNIFICANT_TERM_TYPE;
|
||||
type SignificantItemTypeKeys = keyof typeof SIGNIFICANT_ITEM_TYPE;
|
||||
|
||||
/**
|
||||
* Represents the type of significant term as determined by the SIGNIFICANT_TERM_TYPE enumeration.
|
||||
* Represents the type of significant item as determined by the SIGNIFICANT_ITEM_TYPE enumeration.
|
||||
*/
|
||||
export type SignificantTermType = typeof SIGNIFICANT_TERM_TYPE[SignificantTermTypeKeys];
|
||||
export type SignificantItemType = typeof SIGNIFICANT_ITEM_TYPE[SignificantItemTypeKeys];
|
||||
|
||||
/**
|
||||
* Represents significant term metadata for a field/value pair.
|
||||
* Represents significant item metadata for a field/value pair.
|
||||
* This interface is used as a custom type within Log Rate Analysis
|
||||
* for a p-value based variant, not related to the generic
|
||||
* significant terms aggregation type.
|
||||
|
@ -114,42 +114,42 @@ export type SignificantTermType = typeof SIGNIFICANT_TERM_TYPE[SignificantTermTy
|
|||
* @interface
|
||||
* @extends FieldValuePair
|
||||
*/
|
||||
export interface SignificantTerm extends FieldValuePair {
|
||||
/** The key associated with the significant term. */
|
||||
export interface SignificantItem extends FieldValuePair {
|
||||
/** The key associated with the significant item. */
|
||||
key: string;
|
||||
|
||||
/** The type of the significant term. */
|
||||
type: SignificantTermType;
|
||||
/** The type of the significant item. */
|
||||
type: SignificantItemType;
|
||||
|
||||
/** The document count for the significant term. */
|
||||
/** The document count for the significant item. */
|
||||
doc_count: number;
|
||||
|
||||
/** The background count for the significant term. */
|
||||
/** The background count for the significant item. */
|
||||
bg_count: number;
|
||||
|
||||
/** The total document count for all terms. */
|
||||
/** The total document count for all items. */
|
||||
total_doc_count: number;
|
||||
|
||||
/** The total background count for all terms. */
|
||||
/** The total background count for all items. */
|
||||
total_bg_count: number;
|
||||
|
||||
/** The score associated with the significant term. */
|
||||
/** The score associated with the significant item. */
|
||||
score: number;
|
||||
|
||||
/** The p-value for the significant term, or null if not available. */
|
||||
/** The p-value for the significant item, or null if not available. */
|
||||
pValue: number | null;
|
||||
|
||||
/** The normalized score for the significant term. */
|
||||
/** The normalized score for the significant item. */
|
||||
normalizedScore: number;
|
||||
|
||||
/** An optional histogram of significant term items. */
|
||||
histogram?: SignificantTermHistogramItem[];
|
||||
/** An optional histogram for the significant item. */
|
||||
histogram?: SignificantItemHistogramItem[];
|
||||
|
||||
/** Indicates if the significant term is unique within a group. */
|
||||
/** Indicates if the significant item is unique within a group. */
|
||||
unique?: boolean;
|
||||
}
|
||||
|
||||
interface SignificantTermHistogramItemBase {
|
||||
interface SignificantItemHistogramItemBase {
|
||||
/** The document count for this item in the overall context. */
|
||||
doc_count_overall: number;
|
||||
|
||||
|
@ -163,12 +163,12 @@ interface SignificantTermHistogramItemBase {
|
|||
/**
|
||||
* @deprecated since version 2 of internal log rate analysis REST API endpoint
|
||||
*/
|
||||
interface SignificantTermHistogramItemV1 extends SignificantTermHistogramItemBase {
|
||||
interface SignificantItemHistogramItemV1 extends SignificantItemHistogramItemBase {
|
||||
/** The document count for this item in the significant term context. */
|
||||
doc_count_significant_term: number;
|
||||
}
|
||||
|
||||
interface SignificantTermHistogramItemV2 extends SignificantTermHistogramItemBase {
|
||||
interface SignificantItemHistogramItemV2 extends SignificantItemHistogramItemBase {
|
||||
/** The document count for this histogram item in the significant item context. */
|
||||
doc_count_significant_item: number;
|
||||
}
|
||||
|
@ -176,41 +176,41 @@ interface SignificantTermHistogramItemV2 extends SignificantTermHistogramItemBas
|
|||
/**
|
||||
* Represents a data item in a significant term histogram.
|
||||
*/
|
||||
export type SignificantTermHistogramItem =
|
||||
| SignificantTermHistogramItemV1
|
||||
| SignificantTermHistogramItemV2;
|
||||
export type SignificantItemHistogramItem =
|
||||
| SignificantItemHistogramItemV1
|
||||
| SignificantItemHistogramItemV2;
|
||||
|
||||
/**
|
||||
* Represents histogram data for a field/value pair.
|
||||
* @interface
|
||||
*/
|
||||
export interface SignificantTermHistogram extends FieldValuePair {
|
||||
/** An array of significant term histogram items. */
|
||||
histogram: SignificantTermHistogramItem[];
|
||||
export interface SignificantItemHistogram extends FieldValuePair {
|
||||
/** An array of significant item histogram items. */
|
||||
histogram: SignificantItemHistogramItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents histogram data for a group of field/value pairs.
|
||||
* @interface
|
||||
*/
|
||||
export interface SignificantTermGroupHistogram {
|
||||
export interface SignificantItemGroupHistogram {
|
||||
/** The identifier for the group. */
|
||||
id: string;
|
||||
|
||||
/** An array of significant term histogram items. */
|
||||
histogram: SignificantTermHistogramItem[];
|
||||
/** An array of significant item histogram items. */
|
||||
histogram: SignificantItemHistogramItem[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an item in a significant term group.
|
||||
* Represents an item in a significant item group.
|
||||
* @interface
|
||||
*/
|
||||
export interface SignificantTermGroupItem extends FieldValuePair {
|
||||
/** The key associated with the significant term. */
|
||||
export interface SignificantItemGroupItem extends FieldValuePair {
|
||||
/** The key associated with the significant item. */
|
||||
key: string;
|
||||
|
||||
/** The type of the significant term. */
|
||||
type: SignificantTermType;
|
||||
/** The type of the significant item. */
|
||||
type: SignificantItemType;
|
||||
|
||||
/** The document count associated with this item. */
|
||||
docCount: number;
|
||||
|
@ -223,15 +223,15 @@ export interface SignificantTermGroupItem extends FieldValuePair {
|
|||
}
|
||||
|
||||
/**
|
||||
* Represents a significant term group.
|
||||
* Represents a significant item group.
|
||||
* @interface
|
||||
*/
|
||||
export interface SignificantTermGroup {
|
||||
export interface SignificantItemGroup {
|
||||
/** The identifier for the item. */
|
||||
id: string;
|
||||
|
||||
/** An array of significant term group items. */
|
||||
group: SignificantTermGroupItem[];
|
||||
/** An array of significant item group items. */
|
||||
group: SignificantItemGroupItem[];
|
||||
|
||||
/** The document count associated with this item. */
|
||||
docCount: number;
|
||||
|
@ -239,6 +239,6 @@ export interface SignificantTermGroup {
|
|||
/** The p-value for this item, or null if not available. */
|
||||
pValue: number | null;
|
||||
|
||||
/** An optional array of significant term histogram items. */
|
||||
histogram?: SignificantTermHistogramItem[];
|
||||
/** An optional array of significant item histogram items. */
|
||||
histogram?: SignificantItemHistogramItem[];
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
export const finalSignificantTermGroups: SignificantTermGroup[] = [
|
||||
export const finalSignificantItemGroups: SignificantItemGroup[] = [
|
||||
{
|
||||
docCount: 632,
|
||||
group: [
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
export const finalSignificantTermGroupsTextfield: SignificantTermGroup[] = [
|
||||
export const finalSignificantItemGroupsTextfield: SignificantItemGroup[] = [
|
||||
{
|
||||
docCount: 636,
|
||||
group: [
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
export const significantTermGroups: SignificantTermGroup[] = [
|
||||
export const significantItemGroups: SignificantItemGroup[] = [
|
||||
{
|
||||
id: '2038579476',
|
||||
group: [
|
|
@ -5,9 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
export const significantLogPatterns: SignificantTerm[] = [
|
||||
// Named significantLogPatterns since all these items are of type `log_pattern`.
|
||||
export const significantLogPatterns: SignificantItem[] = [
|
||||
{
|
||||
bg_count: 0,
|
||||
doc_count: 1266,
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
export const significantTerms: SignificantTerm[] = [
|
||||
// Named significantTerms since all these items are of type `keyword`.
|
||||
export const significantTerms: SignificantItem[] = [
|
||||
{
|
||||
key: 'user:Peter',
|
||||
type: 'keyword',
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
export const significantTermGroups: SignificantTermGroup[] = [
|
||||
export const significantItemGroups: SignificantItemGroup[] = [
|
||||
{
|
||||
id: 'group-1',
|
||||
group: [
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
|
||||
import type {
|
||||
SignificantTerm,
|
||||
SignificantTermHistogram,
|
||||
SignificantTermGroup,
|
||||
SignificantTermGroupHistogram,
|
||||
SignificantItem,
|
||||
SignificantItemHistogram,
|
||||
SignificantItemGroup,
|
||||
SignificantItemGroupHistogram,
|
||||
} from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { AiopsLogRateAnalysisApiVersion as ApiVersion } from './schema';
|
||||
|
@ -40,108 +40,108 @@ export const API_ACTION_NAME = {
|
|||
} as const;
|
||||
export type ApiActionName = typeof API_ACTION_NAME[keyof typeof API_ACTION_NAME];
|
||||
|
||||
interface ApiActionAddSignificantTerms<T extends ApiVersion> {
|
||||
interface ApiActionAddSignificantItems<T extends ApiVersion> {
|
||||
type: T extends '1'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_TERMS
|
||||
: T extends '2'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS
|
||||
: never;
|
||||
payload: SignificantTerm[];
|
||||
payload: SignificantItem[];
|
||||
}
|
||||
|
||||
export function addSignificantTermsAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantTerms<T>['payload'],
|
||||
export function addSignificantItemsAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantItems<T>['payload'],
|
||||
version: T
|
||||
): ApiActionAddSignificantTerms<T> {
|
||||
): ApiActionAddSignificantItems<T> {
|
||||
if (version === '1') {
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_TERMS,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTerms<T>;
|
||||
} as ApiActionAddSignificantItems<T>;
|
||||
}
|
||||
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTerms<T>;
|
||||
} as ApiActionAddSignificantItems<T>;
|
||||
}
|
||||
|
||||
interface ApiActionAddSignificantTermsHistogram<T extends ApiVersion> {
|
||||
interface ApiActionAddSignificantItemsHistogram<T extends ApiVersion> {
|
||||
type: T extends '1'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_TERMS_HISTOGRAM
|
||||
: T extends '2'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS_HISTOGRAM
|
||||
: never;
|
||||
payload: SignificantTermHistogram[];
|
||||
payload: SignificantItemHistogram[];
|
||||
}
|
||||
|
||||
export function addSignificantTermsHistogramAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantTermsHistogram<T>['payload'],
|
||||
export function addSignificantItemsHistogramAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantItemsHistogram<T>['payload'],
|
||||
version: T
|
||||
): ApiActionAddSignificantTermsHistogram<T> {
|
||||
): ApiActionAddSignificantItemsHistogram<T> {
|
||||
if (version === '1') {
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_TERMS_HISTOGRAM,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTermsHistogram<T>;
|
||||
} as ApiActionAddSignificantItemsHistogram<T>;
|
||||
}
|
||||
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS_HISTOGRAM,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTermsHistogram<T>;
|
||||
} as ApiActionAddSignificantItemsHistogram<T>;
|
||||
}
|
||||
|
||||
interface ApiActionAddSignificantTermsGroup<T extends ApiVersion> {
|
||||
interface ApiActionAddSignificantItemsGroup<T extends ApiVersion> {
|
||||
type: T extends '1'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_TERMS_GROUP
|
||||
: T extends '2'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS_GROUP
|
||||
: never;
|
||||
payload: SignificantTermGroup[];
|
||||
payload: SignificantItemGroup[];
|
||||
}
|
||||
|
||||
export function addSignificantTermsGroupAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantTermsGroup<T>['payload'],
|
||||
export function addSignificantItemsGroupAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantItemsGroup<T>['payload'],
|
||||
version: T
|
||||
): ApiActionAddSignificantTermsGroup<T> {
|
||||
): ApiActionAddSignificantItemsGroup<T> {
|
||||
if (version === '1') {
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_TERMS_GROUP,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTermsGroup<T>;
|
||||
} as ApiActionAddSignificantItemsGroup<T>;
|
||||
}
|
||||
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS_GROUP,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTermsGroup<T>;
|
||||
} as ApiActionAddSignificantItemsGroup<T>;
|
||||
}
|
||||
|
||||
interface ApiActionAddSignificantTermsGroupHistogram<T extends ApiVersion> {
|
||||
interface ApiActionAddSignificantItemsGroupHistogram<T extends ApiVersion> {
|
||||
type: T extends '1'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_TERMS_GROUP_HISTOGRAM
|
||||
: T extends '2'
|
||||
? typeof API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS_GROUP_HISTOGRAM
|
||||
: never;
|
||||
payload: SignificantTermGroupHistogram[];
|
||||
payload: SignificantItemGroupHistogram[];
|
||||
}
|
||||
|
||||
export function addSignificantTermsGroupHistogramAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantTermsGroupHistogram<T>['payload'],
|
||||
export function addSignificantItemsGroupHistogramAction<T extends ApiVersion>(
|
||||
payload: ApiActionAddSignificantItemsGroupHistogram<T>['payload'],
|
||||
version: T
|
||||
): ApiActionAddSignificantTermsGroupHistogram<T> {
|
||||
): ApiActionAddSignificantItemsGroupHistogram<T> {
|
||||
if (version === '1') {
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_TERMS_GROUP_HISTOGRAM,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTermsGroupHistogram<T>;
|
||||
} as ApiActionAddSignificantItemsGroupHistogram<T>;
|
||||
}
|
||||
|
||||
return {
|
||||
type: API_ACTION_NAME.ADD_SIGNIFICANT_ITEMS_GROUP_HISTOGRAM,
|
||||
payload,
|
||||
} as ApiActionAddSignificantTermsGroupHistogram<T>;
|
||||
} as ApiActionAddSignificantItemsGroupHistogram<T>;
|
||||
}
|
||||
|
||||
interface ApiActionAddError {
|
||||
|
@ -211,10 +211,10 @@ export function updateLoadingStateAction(
|
|||
}
|
||||
|
||||
export type AiopsLogRateAnalysisApiAction<T extends ApiVersion> =
|
||||
| ApiActionAddSignificantTerms<T>
|
||||
| ApiActionAddSignificantTermsGroup<T>
|
||||
| ApiActionAddSignificantTermsHistogram<T>
|
||||
| ApiActionAddSignificantTermsGroupHistogram<T>
|
||||
| ApiActionAddSignificantItems<T>
|
||||
| ApiActionAddSignificantItemsGroup<T>
|
||||
| ApiActionAddSignificantItemsHistogram<T>
|
||||
| ApiActionAddSignificantItemsGroupHistogram<T>
|
||||
| ApiActionAddError
|
||||
| ApiActionPing
|
||||
| ApiActionResetAll
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
*/
|
||||
|
||||
import { significantTerms } from '../__mocks__/artificial_logs/significant_terms';
|
||||
import { finalSignificantTermGroups } from '../__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantItemGroups } from '../__mocks__/artificial_logs/final_significant_item_groups';
|
||||
|
||||
import {
|
||||
addSignificantTermsAction,
|
||||
addSignificantTermsGroupAction,
|
||||
addSignificantItemsAction,
|
||||
addSignificantItemsGroupAction,
|
||||
resetAllAction,
|
||||
resetGroupsAction,
|
||||
updateLoadingStateAction,
|
||||
|
@ -37,7 +37,7 @@ describe('streamReducer', () => {
|
|||
it('adds significant item, then resets all state again', () => {
|
||||
const state1 = streamReducer(
|
||||
initialState,
|
||||
addSignificantTermsAction(
|
||||
addSignificantItemsAction(
|
||||
[
|
||||
{
|
||||
key: 'the-field-name:the-field-value',
|
||||
|
@ -65,14 +65,14 @@ describe('streamReducer', () => {
|
|||
});
|
||||
|
||||
it('adds significant items and groups, then resets groups only', () => {
|
||||
const state1 = streamReducer(initialState, addSignificantTermsAction(significantTerms, '2'));
|
||||
const state1 = streamReducer(initialState, addSignificantItemsAction(significantTerms, '2'));
|
||||
|
||||
expect(state1.significantItems).toHaveLength(4);
|
||||
expect(state1.significantItemsGroups).toHaveLength(0);
|
||||
|
||||
const state2 = streamReducer(
|
||||
state1,
|
||||
addSignificantTermsGroupAction(finalSignificantTermGroups, '2')
|
||||
addSignificantItemsGroupAction(finalSignificantItemGroups, '2')
|
||||
);
|
||||
|
||||
expect(state2.significantItems).toHaveLength(4);
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { API_ACTION_NAME, AiopsLogRateAnalysisApiAction } from './log_rate_analysis/actions';
|
||||
|
||||
interface StreamState {
|
||||
ccsWarning: boolean;
|
||||
significantItems: SignificantTerm[];
|
||||
significantItemsGroups: SignificantTermGroup[];
|
||||
significantItems: SignificantItem[];
|
||||
significantItemsGroups: SignificantItemGroup[];
|
||||
errors: string[];
|
||||
loaded: number;
|
||||
loadingState: string;
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm, SignificantTermType, FieldValuePair } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemType, FieldValuePair } from '@kbn/ml-agg-utils';
|
||||
|
||||
export interface SignificantTermDuplicateGroup {
|
||||
keys: Pick<SignificantTerm, keyof SignificantTerm>;
|
||||
group: SignificantTerm[];
|
||||
export interface SignificantItemDuplicateGroup {
|
||||
keys: Pick<SignificantItem, keyof SignificantItem>;
|
||||
group: SignificantItem[];
|
||||
}
|
||||
|
||||
export type FieldValuePairCounts = Record<string, Record<string, number>>;
|
||||
|
@ -31,7 +31,7 @@ export interface FetchFrequentItemSetsResponse {
|
|||
|
||||
interface SimpleHierarchicalTreeNodeSet extends FieldValuePair {
|
||||
key: string;
|
||||
type: SignificantTermType;
|
||||
type: SignificantItemType;
|
||||
docCount: number;
|
||||
pValue: number | null;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { GroupTableItem } from '../../components/log_rate_analysis_results_table/types';
|
||||
|
||||
import { buildExtendedBaseFilterCriteria } from './build_extended_base_filter_criteria';
|
||||
|
||||
const selectedSignificantTermMock: SignificantTerm = {
|
||||
const selectedSignificantItemMock: SignificantItem = {
|
||||
key: 'meta.cloud.instance_id.keyword:1234',
|
||||
type: 'keyword',
|
||||
doc_count: 53408,
|
||||
|
@ -123,13 +123,13 @@ describe('query_utils', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('includes a term filter when including a selectedSignificantTerm', () => {
|
||||
it('includes a term filter when including a selectedSignificantItem', () => {
|
||||
const baseFilterCriteria = buildExtendedBaseFilterCriteria(
|
||||
'@timestamp',
|
||||
1640082000012,
|
||||
1640103600906,
|
||||
{ match_all: {} },
|
||||
selectedSignificantTermMock
|
||||
selectedSignificantItemMock
|
||||
);
|
||||
|
||||
expect(baseFilterCriteria).toEqual([
|
||||
|
@ -147,13 +147,13 @@ describe('query_utils', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('includes a term filter with must_not when excluding a selectedSignificantTerm', () => {
|
||||
it('includes a term filter with must_not when excluding a selectedSignificantItem', () => {
|
||||
const baseFilterCriteria = buildExtendedBaseFilterCriteria(
|
||||
'@timestamp',
|
||||
1640082000012,
|
||||
1640103600906,
|
||||
{ match_all: {} },
|
||||
selectedSignificantTermMock,
|
||||
selectedSignificantItemMock,
|
||||
false
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import type { Query } from '@kbn/es-query';
|
||||
import { type SignificantTerm, SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { type SignificantItem, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { buildBaseFilterCriteria } from '@kbn/ml-query-utils';
|
||||
|
||||
|
@ -30,8 +30,8 @@ export function buildExtendedBaseFilterCriteria(
|
|||
earliestMs?: number,
|
||||
latestMs?: number,
|
||||
query?: Query['query'],
|
||||
selectedSignificantTerm?: SignificantTerm,
|
||||
includeSelectedSignificantTerm = true,
|
||||
selectedSignificantItem?: SignificantItem,
|
||||
includeSelectedSignificantItem = true,
|
||||
selectedGroup?: GroupTableItem | null
|
||||
): estypes.QueryDslQueryContainer[] {
|
||||
const filterCriteria = buildBaseFilterCriteria(timeFieldName, earliestMs, latestMs, query);
|
||||
|
@ -41,7 +41,7 @@ export function buildExtendedBaseFilterCriteria(
|
|||
const allItems = selectedGroup.groupItemsSortedByUniqueness;
|
||||
for (const item of allItems) {
|
||||
const { fieldName, fieldValue, key, type, docCount } = item;
|
||||
if (type === SIGNIFICANT_TERM_TYPE.KEYWORD) {
|
||||
if (type === SIGNIFICANT_ITEM_TYPE.KEYWORD) {
|
||||
groupFilter.push({ term: { [fieldName]: fieldValue } });
|
||||
} else {
|
||||
groupFilter.push(
|
||||
|
@ -57,18 +57,18 @@ export function buildExtendedBaseFilterCriteria(
|
|||
}
|
||||
}
|
||||
|
||||
if (includeSelectedSignificantTerm) {
|
||||
if (selectedSignificantTerm) {
|
||||
if (selectedSignificantTerm.type === 'keyword') {
|
||||
if (includeSelectedSignificantItem) {
|
||||
if (selectedSignificantItem) {
|
||||
if (selectedSignificantItem.type === 'keyword') {
|
||||
filterCriteria.push({
|
||||
term: { [selectedSignificantTerm.fieldName]: selectedSignificantTerm.fieldValue },
|
||||
term: { [selectedSignificantItem.fieldName]: selectedSignificantItem.fieldValue },
|
||||
});
|
||||
} else {
|
||||
filterCriteria.push(
|
||||
getCategoryQuery(selectedSignificantTerm.fieldName, [
|
||||
getCategoryQuery(selectedSignificantItem.fieldName, [
|
||||
{
|
||||
key: `${selectedSignificantTerm.key}`,
|
||||
count: selectedSignificantTerm.doc_count,
|
||||
key: `${selectedSignificantItem.key}`,
|
||||
count: selectedSignificantItem.doc_count,
|
||||
examples: [],
|
||||
},
|
||||
])
|
||||
|
@ -77,13 +77,13 @@ export function buildExtendedBaseFilterCriteria(
|
|||
} else if (selectedGroup) {
|
||||
filterCriteria.push(...groupFilter);
|
||||
}
|
||||
} else if (selectedSignificantTerm && !includeSelectedSignificantTerm) {
|
||||
if (selectedSignificantTerm.type === 'keyword') {
|
||||
} else if (selectedSignificantItem && !includeSelectedSignificantItem) {
|
||||
if (selectedSignificantItem.type === 'keyword') {
|
||||
filterCriteria.push({
|
||||
bool: {
|
||||
must_not: [
|
||||
{
|
||||
term: { [selectedSignificantTerm.fieldName]: selectedSignificantTerm.fieldValue },
|
||||
term: { [selectedSignificantItem.fieldName]: selectedSignificantItem.fieldValue },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -92,10 +92,10 @@ export function buildExtendedBaseFilterCriteria(
|
|||
filterCriteria.push({
|
||||
bool: {
|
||||
must_not: [
|
||||
getCategoryQuery(selectedSignificantTerm.fieldName, [
|
||||
getCategoryQuery(selectedSignificantItem.fieldName, [
|
||||
{
|
||||
key: `${selectedSignificantTerm.key}`,
|
||||
count: selectedSignificantTerm.doc_count,
|
||||
key: `${selectedSignificantItem.key}`,
|
||||
count: selectedSignificantItem.doc_count,
|
||||
examples: [],
|
||||
},
|
||||
]),
|
||||
|
@ -103,7 +103,7 @@ export function buildExtendedBaseFilterCriteria(
|
|||
},
|
||||
});
|
||||
}
|
||||
} else if (selectedGroup && !includeSelectedSignificantTerm) {
|
||||
} else if (selectedGroup && !includeSelectedSignificantItem) {
|
||||
filterCriteria.push({
|
||||
bool: {
|
||||
must_not: [
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
type LogRateAnalysisType,
|
||||
type WindowParameters,
|
||||
} from '@kbn/aiops-utils';
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { useData } from '../../../hooks/use_data';
|
||||
|
||||
|
@ -35,11 +35,11 @@ import { useLogRateAnalysisResultsTableRowContext } from '../../log_rate_analysi
|
|||
const DEFAULT_SEARCH_QUERY = { match_all: {} };
|
||||
|
||||
export function getDocumentCountStatsSplitLabel(
|
||||
significantTerm?: SignificantTerm,
|
||||
significantItem?: SignificantItem,
|
||||
group?: GroupTableItem
|
||||
) {
|
||||
if (significantTerm) {
|
||||
return `${significantTerm?.fieldName}:${significantTerm?.fieldValue}`;
|
||||
if (significantItem) {
|
||||
return `${significantItem?.fieldName}:${significantItem?.fieldValue}`;
|
||||
} else if (group) {
|
||||
return i18n.translate('xpack.aiops.logRateAnalysis.page.documentCountStatsSplitGroupLabel', {
|
||||
defaultMessage: 'Selected group',
|
||||
|
@ -94,11 +94,11 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
}, [windowParameters]);
|
||||
|
||||
const {
|
||||
currentSelectedSignificantTerm,
|
||||
currentSelectedSignificantItem,
|
||||
currentSelectedGroup,
|
||||
setPinnedSignificantTerm,
|
||||
setPinnedSignificantItem,
|
||||
setPinnedGroup,
|
||||
setSelectedSignificantTerm,
|
||||
setSelectedSignificantItem,
|
||||
setSelectedGroup,
|
||||
} = useLogRateAnalysisResultsTableRowContext();
|
||||
|
||||
|
@ -107,7 +107,7 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
'log_rate_analysis',
|
||||
esSearchQuery,
|
||||
setGlobalState,
|
||||
currentSelectedSignificantTerm,
|
||||
currentSelectedSignificantItem,
|
||||
currentSelectedGroup,
|
||||
undefined,
|
||||
timeRange
|
||||
|
@ -132,9 +132,9 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
|
||||
function clearSelection() {
|
||||
setWindowParameters(undefined);
|
||||
setPinnedSignificantTerm(null);
|
||||
setPinnedSignificantItem(null);
|
||||
setPinnedGroup(null);
|
||||
setSelectedSignificantTerm(null);
|
||||
setSelectedSignificantItem(null);
|
||||
setSelectedGroup(null);
|
||||
setIsBrushCleared(true);
|
||||
setInitialAnalysisStart(undefined);
|
||||
|
@ -148,7 +148,7 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
documentCountStats={documentCountStats}
|
||||
documentCountStatsSplit={documentCountStatsCompare}
|
||||
documentCountStatsSplitLabel={getDocumentCountStatsSplitLabel(
|
||||
currentSelectedSignificantTerm,
|
||||
currentSelectedSignificantItem,
|
||||
currentSelectedGroup
|
||||
)}
|
||||
isBrushCleared={isBrushCleared}
|
||||
|
|
|
@ -37,7 +37,7 @@ export const LogRateAnalysisPage: FC<Props> = ({ stickyHistogram }) => {
|
|||
const { data: dataService } = useAiopsAppContext();
|
||||
const { dataView, savedSearch } = useDataSource();
|
||||
|
||||
const { currentSelectedSignificantTerm, currentSelectedGroup } =
|
||||
const { currentSelectedSignificantItem, currentSelectedGroup } =
|
||||
useLogRateAnalysisResultsTableRowContext();
|
||||
|
||||
const [aiopsListState, setAiopsListState] = usePageUrlState<AiOpsPageUrlState>(
|
||||
|
@ -88,7 +88,7 @@ export const LogRateAnalysisPage: FC<Props> = ({ stickyHistogram }) => {
|
|||
'log_rate_analysis',
|
||||
searchQuery,
|
||||
setGlobalState,
|
||||
currentSelectedSignificantTerm,
|
||||
currentSelectedSignificantItem,
|
||||
currentSelectedGroup
|
||||
);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ import {
|
|||
} from '@kbn/aiops-utils';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
import { initialState, streamReducer } from '../../../common/api/stream_reducer';
|
||||
|
@ -81,9 +81,9 @@ export interface LogRateAnalysisResultsData {
|
|||
/** The type of analysis, whether it's a spike or dip */
|
||||
analysisType: LogRateAnalysisType;
|
||||
/** Statistically significant field/value items. */
|
||||
significantTerms: SignificantTerm[];
|
||||
significantItems: SignificantItem[];
|
||||
/** Statistically significant groups of field/value items. */
|
||||
significantTermsGroups: SignificantTermGroup[];
|
||||
significantItemsGroups: SignificantItemGroup[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,8 +234,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
if (onAnalysisCompleted) {
|
||||
onAnalysisCompleted({
|
||||
analysisType,
|
||||
significantTerms: data.significantItems,
|
||||
significantTermsGroups: data.significantItemsGroups,
|
||||
significantItems: data.significantItems,
|
||||
significantItemsGroups: data.significantItemsGroups,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
const errors = useMemo(() => [...streamErrors, ...data.errors], [streamErrors, data.errors]);
|
||||
|
||||
// Start handler clears possibly hovered or pinned
|
||||
// significant terms on analysis refresh.
|
||||
// significant items on analysis refresh.
|
||||
function startHandler(continueAnalysis = false, resetGroupButton = true) {
|
||||
if (!continueAnalysis) {
|
||||
setOverrides(undefined);
|
||||
|
@ -482,7 +482,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
>
|
||||
{showLogRateAnalysisResultsTable && groupResults ? (
|
||||
<LogRateAnalysisResultsGroupsTable
|
||||
significantTerms={data.significantItems}
|
||||
significantItems={data.significantItems}
|
||||
groupTableItems={groupTableItems}
|
||||
loading={isRunning}
|
||||
dataView={dataView}
|
||||
|
@ -494,7 +494,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
) : null}
|
||||
{showLogRateAnalysisResultsTable && !groupResults ? (
|
||||
<LogRateAnalysisResultsTable
|
||||
significantTerms={data.significantItems}
|
||||
significantItems={data.significantItems}
|
||||
loading={isRunning}
|
||||
dataView={dataView}
|
||||
timeRangeMs={timeRangeMs}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { finalSignificantTermGroups } from '../../../common/__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantItemGroups } from '../../../common/__mocks__/artificial_logs/final_significant_item_groups';
|
||||
|
||||
import { getGroupTableItems } from './get_group_table_items';
|
||||
|
||||
describe('getGroupTableItems', () => {
|
||||
it('transforms groups into table items', () => {
|
||||
const groupTableItems = getGroupTableItems(finalSignificantTermGroups);
|
||||
const groupTableItems = getGroupTableItems(finalSignificantItemGroups);
|
||||
|
||||
expect(groupTableItems).toEqual([
|
||||
{
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
import { sortBy } from 'lodash';
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { GroupTableItem, GroupTableItemGroup } from './types';
|
||||
|
||||
export function getGroupTableItems(
|
||||
significantTermsGroups: SignificantTermGroup[]
|
||||
significantItemsGroups: SignificantItemGroup[]
|
||||
): GroupTableItem[] {
|
||||
const tableItems = significantTermsGroups.map(({ id, group, docCount, histogram, pValue }) => {
|
||||
const tableItems = significantItemsGroups.map(({ id, group, docCount, histogram, pValue }) => {
|
||||
const sortedGroup = sortBy(group, [(d) => d.fieldName]);
|
||||
const dedupedGroup: GroupTableItemGroup[] = [];
|
||||
|
||||
|
|
|
@ -5,21 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { finalSignificantTermGroups } from '../../../common/__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantItemGroups } from '../../../common/__mocks__/artificial_logs/final_significant_item_groups';
|
||||
import { significantTerms } from '../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
||||
import { getGroupTableItems } from './get_group_table_items';
|
||||
import { getTableItemAsKQL } from './get_table_item_as_kql';
|
||||
|
||||
describe('getTableItemAsKQL', () => {
|
||||
it('returns a KQL syntax for a significant term', () => {
|
||||
it('returns a KQL syntax for a significant item', () => {
|
||||
expect(getTableItemAsKQL(significantTerms[0])).toBe('user:Peter');
|
||||
expect(getTableItemAsKQL(significantTerms[1])).toBe('response_code:500');
|
||||
expect(getTableItemAsKQL(significantTerms[2])).toBe('url:home.php');
|
||||
expect(getTableItemAsKQL(significantTerms[3])).toBe('url:login.php');
|
||||
});
|
||||
it('returns a KQL syntax for a group of significant terms', () => {
|
||||
const groupTableItems = getGroupTableItems(finalSignificantTermGroups);
|
||||
it('returns a KQL syntax for a group of significant items', () => {
|
||||
const groupTableItems = getGroupTableItems(finalSignificantItemGroups);
|
||||
expect(getTableItemAsKQL(groupTableItems[0])).toBe('user:Peter AND url:login.php');
|
||||
expect(getTableItemAsKQL(groupTableItems[1])).toBe('response_code:500 AND url:home.php');
|
||||
expect(getTableItemAsKQL(groupTableItems[2])).toBe('url:login.php AND response_code:500');
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
*/
|
||||
|
||||
import { escapeKuery } from '@kbn/es-query';
|
||||
import { isSignificantTerm, type SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import { isSignificantItem, type SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { GroupTableItem } from './types';
|
||||
|
||||
export const getTableItemAsKQL = (tableItem: GroupTableItem | SignificantTerm) => {
|
||||
if (isSignificantTerm(tableItem)) {
|
||||
export const getTableItemAsKQL = (tableItem: GroupTableItem | SignificantItem) => {
|
||||
if (isSignificantItem(tableItem)) {
|
||||
return `${escapeKuery(tableItem.fieldName)}:${escapeKuery(String(tableItem.fieldValue))}`;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import type { FieldStatsServices } from '@kbn/unified-field-list/src/components/
|
|||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { type SignificantTerm, SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { type SignificantItem, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import type { TimeRange as TimeRangeMs } from '@kbn/ml-date-picker';
|
||||
|
||||
import { getCategoryQuery } from '../../../common/api/log_categorization/get_category_query';
|
||||
|
@ -56,7 +56,7 @@ const DEFAULT_SORT_DIRECTION = 'asc';
|
|||
const TRUNCATE_TEXT_LINES = 3;
|
||||
|
||||
interface LogRateAnalysisResultsTableProps {
|
||||
significantTerms: SignificantTerm[];
|
||||
significantItems: SignificantItem[];
|
||||
dataView: DataView;
|
||||
loading: boolean;
|
||||
isExpandedRow?: boolean;
|
||||
|
@ -69,7 +69,7 @@ interface LogRateAnalysisResultsTableProps {
|
|||
}
|
||||
|
||||
export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> = ({
|
||||
significantTerms,
|
||||
significantItems,
|
||||
dataView,
|
||||
loading,
|
||||
isExpandedRow,
|
||||
|
@ -84,16 +84,16 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
|
||||
const {
|
||||
pinnedGroup,
|
||||
pinnedSignificantTerm,
|
||||
pinnedSignificantItem,
|
||||
selectedGroup,
|
||||
selectedSignificantTerm,
|
||||
setPinnedSignificantTerm,
|
||||
setSelectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
setPinnedSignificantItem,
|
||||
setSelectedSignificantItem,
|
||||
} = useLogRateAnalysisResultsTableRowContext();
|
||||
|
||||
const [pageIndex, setPageIndex] = useState(0);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [sortField, setSortField] = useState<keyof SignificantTerm>(DEFAULT_SORT_FIELD);
|
||||
const [sortField, setSortField] = useState<keyof SignificantItem>(DEFAULT_SORT_FIELD);
|
||||
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(DEFAULT_SORT_DIRECTION);
|
||||
|
||||
const { data, uiSettings, fieldFormats, charts } = useAiopsAppContext();
|
||||
|
@ -112,7 +112,7 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
const viewInDiscoverAction = useViewInDiscoverAction(dataViewId);
|
||||
const viewInLogPatternAnalysisAction = useViewInLogPatternAnalysisAction(dataViewId);
|
||||
|
||||
const columns: Array<EuiBasicTableColumn<SignificantTerm>> = [
|
||||
const columns: Array<EuiBasicTableColumn<SignificantItem>> = [
|
||||
{
|
||||
'data-test-subj': 'aiopsLogRateAnalysisResultsTableColumnFieldName',
|
||||
field: 'fieldName',
|
||||
|
@ -121,7 +121,7 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
}),
|
||||
render: (_, { fieldName, fieldValue, key, type, doc_count: count }) => {
|
||||
const dslQuery =
|
||||
type === SIGNIFICANT_TERM_TYPE.KEYWORD
|
||||
type === SIGNIFICANT_ITEM_TYPE.KEYWORD
|
||||
? searchQuery
|
||||
: getCategoryQuery(fieldName, [
|
||||
{
|
||||
|
@ -132,17 +132,17 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
]);
|
||||
return (
|
||||
<>
|
||||
{type === SIGNIFICANT_TERM_TYPE.KEYWORD && (
|
||||
{type === SIGNIFICANT_ITEM_TYPE.KEYWORD && (
|
||||
<FieldStatsPopover
|
||||
dataView={dataView}
|
||||
fieldName={fieldName}
|
||||
fieldValue={type === SIGNIFICANT_TERM_TYPE.KEYWORD ? fieldValue : key}
|
||||
fieldValue={type === SIGNIFICANT_ITEM_TYPE.KEYWORD ? fieldValue : key}
|
||||
fieldStatsServices={fieldStatsServices}
|
||||
dslQuery={dslQuery}
|
||||
timeRangeMs={timeRangeMs}
|
||||
/>
|
||||
)}
|
||||
{type === SIGNIFICANT_TERM_TYPE.LOG_PATTERN && (
|
||||
{type === SIGNIFICANT_ITEM_TYPE.LOG_PATTERN && (
|
||||
<EuiToolTip
|
||||
content={i18n.translate(
|
||||
'xpack.aiops.fieldContextPopover.descriptionTooltipLogPattern',
|
||||
|
@ -351,12 +351,12 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
|
||||
const { pagination, pageOfItems, sorting } = useMemo(() => {
|
||||
const pageStart = pageIndex * pageSize;
|
||||
const itemCount = significantTerms?.length ?? 0;
|
||||
const itemCount = significantItems?.length ?? 0;
|
||||
|
||||
let items: SignificantTerm[] = significantTerms ?? [];
|
||||
let items: SignificantItem[] = significantItems ?? [];
|
||||
|
||||
const sortIteratees = [
|
||||
(item: SignificantTerm) => {
|
||||
(item: SignificantItem) => {
|
||||
if (item && typeof item[sortField] === 'string') {
|
||||
// @ts-ignore Object is possibly null or undefined
|
||||
return item[sortField].toLowerCase();
|
||||
|
@ -368,11 +368,11 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
|
||||
// Only if the table is sorted by p-value, add a secondary sort by doc count.
|
||||
if (sortField === 'pValue') {
|
||||
sortIteratees.push((item: SignificantTerm) => item.doc_count);
|
||||
sortIteratees.push((item: SignificantItem) => item.doc_count);
|
||||
sortDirections.push(sortDirection);
|
||||
}
|
||||
|
||||
items = orderBy(significantTerms, sortIteratees, sortDirections);
|
||||
items = orderBy(significantItems, sortIteratees, sortDirections);
|
||||
|
||||
return {
|
||||
pageOfItems: items.slice(pageStart, pageStart + pageSize),
|
||||
|
@ -389,59 +389,59 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
},
|
||||
},
|
||||
};
|
||||
}, [pageIndex, pageSize, sortField, sortDirection, significantTerms]);
|
||||
}, [pageIndex, pageSize, sortField, sortDirection, significantItems]);
|
||||
|
||||
useEffect(() => {
|
||||
// If no row is hovered or pinned or the user switched to a new page,
|
||||
// fall back to set the first row into a hovered state to make the
|
||||
// main document count chart show a comparison view by default.
|
||||
if (
|
||||
(selectedSignificantTerm === null ||
|
||||
!pageOfItems.some((item) => isEqual(item, selectedSignificantTerm))) &&
|
||||
pinnedSignificantTerm === null &&
|
||||
(selectedSignificantItem === null ||
|
||||
!pageOfItems.some((item) => isEqual(item, selectedSignificantItem))) &&
|
||||
pinnedSignificantItem === null &&
|
||||
pageOfItems.length > 0 &&
|
||||
selectedGroup === null &&
|
||||
pinnedGroup === null
|
||||
) {
|
||||
setSelectedSignificantTerm(pageOfItems[0]);
|
||||
setSelectedSignificantItem(pageOfItems[0]);
|
||||
}
|
||||
|
||||
// If a user switched pages and a pinned row is no longer visible
|
||||
// on the current page, set the status of pinned rows back to `null`.
|
||||
if (
|
||||
pinnedSignificantTerm !== null &&
|
||||
!pageOfItems.some((item) => isEqual(item, pinnedSignificantTerm)) &&
|
||||
pinnedSignificantItem !== null &&
|
||||
!pageOfItems.some((item) => isEqual(item, pinnedSignificantItem)) &&
|
||||
selectedGroup === null &&
|
||||
pinnedGroup === null
|
||||
) {
|
||||
setPinnedSignificantTerm(null);
|
||||
setPinnedSignificantItem(null);
|
||||
}
|
||||
}, [
|
||||
selectedGroup,
|
||||
selectedSignificantTerm,
|
||||
setSelectedSignificantTerm,
|
||||
setPinnedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
setSelectedSignificantItem,
|
||||
setPinnedSignificantItem,
|
||||
pageOfItems,
|
||||
pinnedGroup,
|
||||
pinnedSignificantTerm,
|
||||
pinnedSignificantItem,
|
||||
]);
|
||||
|
||||
// When the analysis results table unmounts,
|
||||
// make sure to reset any hovered or pinned rows.
|
||||
useEffect(
|
||||
() => () => {
|
||||
setSelectedSignificantTerm(null);
|
||||
setPinnedSignificantTerm(null);
|
||||
setSelectedSignificantItem(null);
|
||||
setPinnedSignificantItem(null);
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[]
|
||||
);
|
||||
|
||||
const getRowStyle = (significantTerm: SignificantTerm) => {
|
||||
const getRowStyle = (significantItem: SignificantItem) => {
|
||||
if (
|
||||
pinnedSignificantTerm &&
|
||||
pinnedSignificantTerm.fieldName === significantTerm.fieldName &&
|
||||
pinnedSignificantTerm.fieldValue === significantTerm.fieldValue
|
||||
pinnedSignificantItem &&
|
||||
pinnedSignificantItem.fieldName === significantItem.fieldName &&
|
||||
pinnedSignificantItem.fieldValue === significantItem.fieldValue
|
||||
) {
|
||||
return {
|
||||
backgroundColor: primaryBackgroundColor,
|
||||
|
@ -449,9 +449,9 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
}
|
||||
|
||||
if (
|
||||
selectedSignificantTerm &&
|
||||
selectedSignificantTerm.fieldName === significantTerm.fieldName &&
|
||||
selectedSignificantTerm.fieldValue === significantTerm.fieldValue
|
||||
selectedSignificantItem &&
|
||||
selectedSignificantItem.fieldName === significantItem.fieldName &&
|
||||
selectedSignificantItem.fieldValue === significantItem.fieldValue
|
||||
) {
|
||||
return {
|
||||
backgroundColor: euiTheme.euiColorLightestShade,
|
||||
|
@ -479,29 +479,29 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
|
|||
onChange={onChange}
|
||||
pagination={pagination.totalItemCount > pagination.pageSize ? pagination : undefined}
|
||||
loading={false}
|
||||
sorting={sorting as EuiTableSortingType<SignificantTerm>}
|
||||
rowProps={(significantTerm) => {
|
||||
sorting={sorting as EuiTableSortingType<SignificantItem>}
|
||||
rowProps={(significantItem) => {
|
||||
return {
|
||||
'data-test-subj': `aiopsLogRateAnalysisResultsTableRow row-${significantTerm.fieldName}-${significantTerm.fieldValue}`,
|
||||
'data-test-subj': `aiopsLogRateAnalysisResultsTableRow row-${significantItem.fieldName}-${significantItem.fieldValue}`,
|
||||
onClick: () => {
|
||||
if (
|
||||
significantTerm.fieldName === pinnedSignificantTerm?.fieldName &&
|
||||
significantTerm.fieldValue === pinnedSignificantTerm?.fieldValue
|
||||
significantItem.fieldName === pinnedSignificantItem?.fieldName &&
|
||||
significantItem.fieldValue === pinnedSignificantItem?.fieldValue
|
||||
) {
|
||||
setPinnedSignificantTerm(null);
|
||||
setPinnedSignificantItem(null);
|
||||
} else {
|
||||
setPinnedSignificantTerm(significantTerm);
|
||||
setPinnedSignificantItem(significantItem);
|
||||
}
|
||||
},
|
||||
onMouseEnter: () => {
|
||||
if (pinnedSignificantTerm === null) {
|
||||
setSelectedSignificantTerm(significantTerm);
|
||||
if (pinnedSignificantItem === null) {
|
||||
setSelectedSignificantItem(significantItem);
|
||||
}
|
||||
},
|
||||
onMouseLeave: () => {
|
||||
setSelectedSignificantTerm(null);
|
||||
setSelectedSignificantItem(null);
|
||||
},
|
||||
style: getRowStyle(significantTerm),
|
||||
style: getRowStyle(significantItem),
|
||||
};
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
import type { TimeRange as TimeRangeMs } from '@kbn/ml-date-picker';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
|
||||
|
@ -53,7 +53,7 @@ const DEFAULT_SORT_FIELD = 'pValue';
|
|||
const DEFAULT_SORT_DIRECTION = 'asc';
|
||||
|
||||
interface LogRateAnalysisResultsTableProps {
|
||||
significantTerms: SignificantTerm[];
|
||||
significantItems: SignificantItem[];
|
||||
groupTableItems: GroupTableItem[];
|
||||
loading: boolean;
|
||||
searchQuery: estypes.QueryDslQueryContainer;
|
||||
|
@ -66,7 +66,7 @@ interface LogRateAnalysisResultsTableProps {
|
|||
}
|
||||
|
||||
export const LogRateAnalysisResultsGroupsTable: FC<LogRateAnalysisResultsTableProps> = ({
|
||||
significantTerms,
|
||||
significantItems,
|
||||
groupTableItems,
|
||||
loading,
|
||||
dataView,
|
||||
|
@ -98,9 +98,9 @@ export const LogRateAnalysisResultsGroupsTable: FC<LogRateAnalysisResultsTablePr
|
|||
} else {
|
||||
itemIdToExpandedRowMapValues[item.id] = (
|
||||
<LogRateAnalysisResultsTable
|
||||
significantTerms={item.groupItemsSortedByUniqueness.reduce<SignificantTerm[]>(
|
||||
significantItems={item.groupItemsSortedByUniqueness.reduce<SignificantItem[]>(
|
||||
(p, groupItem) => {
|
||||
const st = significantTerms.find(
|
||||
const st = significantItems.find(
|
||||
(d) => d.fieldName === groupItem.fieldName && d.fieldValue === groupItem.fieldValue
|
||||
);
|
||||
|
||||
|
@ -139,7 +139,11 @@ export const LogRateAnalysisResultsGroupsTable: FC<LogRateAnalysisResultsTablePr
|
|||
isExpander: true,
|
||||
name: (
|
||||
<EuiScreenReaderOnly>
|
||||
<span>Expand rows</span>
|
||||
<span>
|
||||
{i18n.translate('xpack.aiops.logRateAnalysis.resultsTable.expandRowsLabel', {
|
||||
defaultMessage: 'Expand rows',
|
||||
})}
|
||||
</span>
|
||||
</EuiScreenReaderOnly>
|
||||
),
|
||||
render: (item: GroupTableItem) => (
|
||||
|
|
|
@ -15,23 +15,23 @@ import React, {
|
|||
type SetStateAction,
|
||||
} from 'react';
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { GroupTableItem } from './types';
|
||||
|
||||
type SignificantTermOrNull = SignificantTerm | null;
|
||||
type SignificantItemOrNull = SignificantItem | null;
|
||||
type GroupOrNull = GroupTableItem | null;
|
||||
|
||||
interface LogRateAnalysisResultsTableRow {
|
||||
pinnedSignificantTerm: SignificantTermOrNull;
|
||||
setPinnedSignificantTerm: Dispatch<SetStateAction<SignificantTermOrNull>>;
|
||||
pinnedSignificantItem: SignificantItemOrNull;
|
||||
setPinnedSignificantItem: Dispatch<SetStateAction<SignificantItemOrNull>>;
|
||||
pinnedGroup: GroupOrNull;
|
||||
setPinnedGroup: Dispatch<SetStateAction<GroupOrNull>>;
|
||||
selectedSignificantTerm: SignificantTermOrNull;
|
||||
setSelectedSignificantTerm: Dispatch<SetStateAction<SignificantTermOrNull>>;
|
||||
selectedSignificantItem: SignificantItemOrNull;
|
||||
setSelectedSignificantItem: Dispatch<SetStateAction<SignificantItemOrNull>>;
|
||||
selectedGroup: GroupOrNull;
|
||||
setSelectedGroup: Dispatch<SetStateAction<GroupOrNull>>;
|
||||
currentSelectedSignificantTerm?: SignificantTerm;
|
||||
currentSelectedSignificantItem?: SignificantItem;
|
||||
currentSelectedGroup?: GroupTableItem;
|
||||
clearAllRowState: () => void;
|
||||
}
|
||||
|
@ -42,20 +42,20 @@ export const logRateAnalysisResultsTableRowContext = createContext<
|
|||
|
||||
export const LogRateAnalysisResultsTableRowStateProvider: FC = ({ children }) => {
|
||||
// State that will be shared with all components
|
||||
const [pinnedSignificantTerm, setPinnedSignificantTerm] = useState<SignificantTermOrNull>(null);
|
||||
const [pinnedSignificantItem, setPinnedSignificantItem] = useState<SignificantItemOrNull>(null);
|
||||
const [pinnedGroup, setPinnedGroup] = useState<GroupOrNull>(null);
|
||||
const [selectedSignificantTerm, setSelectedSignificantTerm] =
|
||||
useState<SignificantTermOrNull>(null);
|
||||
const [selectedSignificantItem, setSelectedSignificantItem] =
|
||||
useState<SignificantItemOrNull>(null);
|
||||
const [selectedGroup, setSelectedGroup] = useState<GroupOrNull>(null);
|
||||
|
||||
// If a row is pinned, still overrule with a potentially hovered row.
|
||||
const currentSelectedSignificantTerm = useMemo(() => {
|
||||
if (selectedSignificantTerm) {
|
||||
return selectedSignificantTerm;
|
||||
} else if (pinnedSignificantTerm) {
|
||||
return pinnedSignificantTerm;
|
||||
const currentSelectedSignificantItem = useMemo(() => {
|
||||
if (selectedSignificantItem) {
|
||||
return selectedSignificantItem;
|
||||
} else if (pinnedSignificantItem) {
|
||||
return pinnedSignificantItem;
|
||||
}
|
||||
}, [pinnedSignificantTerm, selectedSignificantTerm]);
|
||||
}, [pinnedSignificantItem, selectedSignificantItem]);
|
||||
|
||||
// If a group is pinned, still overrule with a potentially hovered group.
|
||||
const currentSelectedGroup = useMemo(() => {
|
||||
|
@ -68,33 +68,33 @@ export const LogRateAnalysisResultsTableRowStateProvider: FC = ({ children }) =>
|
|||
|
||||
const contextValue: LogRateAnalysisResultsTableRow = useMemo(
|
||||
() => ({
|
||||
pinnedSignificantTerm,
|
||||
setPinnedSignificantTerm,
|
||||
pinnedSignificantItem,
|
||||
setPinnedSignificantItem,
|
||||
pinnedGroup,
|
||||
setPinnedGroup,
|
||||
selectedSignificantTerm,
|
||||
setSelectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
setSelectedSignificantItem,
|
||||
selectedGroup,
|
||||
setSelectedGroup,
|
||||
currentSelectedSignificantTerm,
|
||||
currentSelectedSignificantItem,
|
||||
currentSelectedGroup,
|
||||
clearAllRowState: () => {
|
||||
setPinnedSignificantTerm(null);
|
||||
setPinnedSignificantItem(null);
|
||||
setPinnedGroup(null);
|
||||
setSelectedSignificantTerm(null);
|
||||
setSelectedSignificantItem(null);
|
||||
setSelectedGroup(null);
|
||||
},
|
||||
}),
|
||||
[
|
||||
pinnedSignificantTerm,
|
||||
setPinnedSignificantTerm,
|
||||
pinnedSignificantItem,
|
||||
setPinnedSignificantItem,
|
||||
pinnedGroup,
|
||||
setPinnedGroup,
|
||||
selectedSignificantTerm,
|
||||
setSelectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
setSelectedSignificantItem,
|
||||
selectedGroup,
|
||||
setSelectedGroup,
|
||||
currentSelectedSignificantTerm,
|
||||
currentSelectedSignificantItem,
|
||||
currentSelectedGroup,
|
||||
]
|
||||
);
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
import type { EuiTableActionsColumnType } from '@elastic/eui';
|
||||
|
||||
import type { SignificantTerm, SignificantTermGroupItem } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroupItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
export type GroupTableItemGroup = Pick<
|
||||
SignificantTermGroupItem,
|
||||
SignificantItemGroupItem,
|
||||
'key' | 'type' | 'fieldName' | 'fieldValue' | 'docCount' | 'pValue' | 'duplicate'
|
||||
>;
|
||||
|
||||
|
@ -20,9 +20,9 @@ export interface GroupTableItem {
|
|||
pValue: number | null;
|
||||
uniqueItemsCount: number;
|
||||
groupItemsSortedByUniqueness: GroupTableItemGroup[];
|
||||
histogram: SignificantTerm['histogram'];
|
||||
histogram: SignificantItem['histogram'];
|
||||
}
|
||||
|
||||
export type TableItemAction = EuiTableActionsColumnType<
|
||||
SignificantTerm | GroupTableItem
|
||||
SignificantItem | GroupTableItem
|
||||
>['actions'][number];
|
||||
|
|
|
@ -10,9 +10,9 @@ import userEvent from '@testing-library/user-event';
|
|||
import { render, act } from '@testing-library/react';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { finalSignificantTermGroups } from '../../../common/__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantItemGroups } from '../../../common/__mocks__/artificial_logs/final_significant_item_groups';
|
||||
import { significantTerms } from '../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
||||
import { getGroupTableItems } from './get_group_table_items';
|
||||
|
@ -20,14 +20,14 @@ import { useCopyToClipboardAction } from './use_copy_to_clipboard_action';
|
|||
import type { GroupTableItem } from './types';
|
||||
|
||||
interface Action {
|
||||
render: (tableItem: SignificantTerm | GroupTableItem) => ReactElement;
|
||||
render: (tableItem: SignificantItem | GroupTableItem) => ReactElement;
|
||||
}
|
||||
|
||||
const execCommandMock = (global.document.execCommand = jest.fn());
|
||||
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
||||
|
||||
describe('useCopyToClipboardAction', () => {
|
||||
it('renders the action for a single significant term', async () => {
|
||||
it('renders the action for a single significant item', async () => {
|
||||
execCommandMock.mockImplementationOnce(() => true);
|
||||
const { result } = renderHook(() => useCopyToClipboardAction());
|
||||
const { findByText, getByTestId } = render(
|
||||
|
@ -57,7 +57,7 @@ describe('useCopyToClipboardAction', () => {
|
|||
|
||||
it('renders the action for a group of items', async () => {
|
||||
execCommandMock.mockImplementationOnce(() => true);
|
||||
const groupTableItems = getGroupTableItems(finalSignificantTermGroups);
|
||||
const groupTableItems = getGroupTableItems(finalSignificantItemGroups);
|
||||
const { result } = renderHook(useCopyToClipboardAction);
|
||||
const { findByText, getByText } = render((result.current as Action).render(groupTableItems[0]));
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import React from 'react';
|
|||
import { EuiCopy, EuiToolTip } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isSignificantTerm, type SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import { isSignificantItem, type SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { TableActionButton } from './table_action_button';
|
||||
import { getTableItemAsKQL } from './get_table_item_as_kql';
|
||||
|
@ -23,8 +23,8 @@ const copyToClipboardButtonLabel = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
const copyToClipboardSignificantTermMessage = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantTermMessage',
|
||||
const copyToClipboardSignificantItemMessage = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantItemMessage',
|
||||
{
|
||||
defaultMessage: 'Copy field/value pair as KQL syntax to clipboard',
|
||||
}
|
||||
|
@ -38,9 +38,9 @@ const copyToClipboardGroupMessage = i18n.translate(
|
|||
);
|
||||
|
||||
export const useCopyToClipboardAction = (): TableItemAction => ({
|
||||
render: (tableItem: SignificantTerm | GroupTableItem) => {
|
||||
const message = isSignificantTerm(tableItem)
|
||||
? copyToClipboardSignificantTermMessage
|
||||
render: (tableItem: SignificantItem | GroupTableItem) => {
|
||||
const message = isSignificantItem(tableItem)
|
||||
? copyToClipboardSignificantItemMessage
|
||||
: copyToClipboardGroupMessage;
|
||||
return (
|
||||
<EuiToolTip content={message}>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React, { useMemo } from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { SEARCH_QUERY_LANGUAGE } from '@kbn/ml-query-utils';
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
|
@ -65,7 +65,7 @@ export const useViewInDiscoverAction = (dataViewId?: string): TableItemAction =>
|
|||
}
|
||||
}, [application.capabilities.discover?.show, dataViewId, discoverLocator]);
|
||||
|
||||
const generateDiscoverUrl = async (groupTableItem: GroupTableItem | SignificantTerm) => {
|
||||
const generateDiscoverUrl = async (groupTableItem: GroupTableItem | SignificantItem) => {
|
||||
if (discoverLocator !== undefined) {
|
||||
const url = await discoverLocator.getRedirectUrl({
|
||||
indexPatternId: dataViewId,
|
||||
|
@ -82,7 +82,7 @@ export const useViewInDiscoverAction = (dataViewId?: string): TableItemAction =>
|
|||
};
|
||||
|
||||
return {
|
||||
render: (tableItem: SignificantTerm | GroupTableItem) => {
|
||||
render: (tableItem: SignificantItem | GroupTableItem) => {
|
||||
const tooltipText = discoverUrlError ? discoverUrlError : viewInDiscoverMessage;
|
||||
|
||||
const clickHandler = async () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import React, { useMemo } from 'react';
|
|||
import { SerializableRecord } from '@kbn/utility-types';
|
||||
import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isSignificantTerm, type SignificantTerm, SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { isSignificantItem, type SignificantItem, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { SEARCH_QUERY_LANGUAGE } from '@kbn/ml-query-utils';
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
|
@ -19,8 +19,8 @@ import { TableActionButton } from './table_action_button';
|
|||
import { getTableItemAsKQL } from './get_table_item_as_kql';
|
||||
import type { GroupTableItem, TableItemAction } from './types';
|
||||
|
||||
const isLogPattern = (tableItem: SignificantTerm | GroupTableItem) =>
|
||||
isSignificantTerm(tableItem) && tableItem.type === SIGNIFICANT_TERM_TYPE.LOG_PATTERN;
|
||||
const isLogPattern = (tableItem: SignificantItem | GroupTableItem) =>
|
||||
isSignificantItem(tableItem) && tableItem.type === SIGNIFICANT_ITEM_TYPE.LOG_PATTERN;
|
||||
|
||||
const viewInLogPatternAnalysisMessage = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInLogPatternAnalysis',
|
||||
|
@ -35,7 +35,7 @@ export const useViewInLogPatternAnalysisAction = (dataViewId?: string): TableIte
|
|||
const mlLocator = useMemo(() => share.url.locators.get('ML_APP_LOCATOR'), [share.url.locators]);
|
||||
|
||||
const generateLogPatternAnalysisUrl = async (
|
||||
groupTableItem: GroupTableItem | SignificantTerm
|
||||
groupTableItem: GroupTableItem | SignificantItem
|
||||
) => {
|
||||
if (mlLocator !== undefined) {
|
||||
const searchString = getTableItemAsKQL(groupTableItem);
|
||||
|
@ -85,7 +85,7 @@ export const useViewInLogPatternAnalysisAction = (dataViewId?: string): TableIte
|
|||
}, [dataViewId, mlLocator]);
|
||||
|
||||
return {
|
||||
render: (tableItem: SignificantTerm | GroupTableItem) => {
|
||||
render: (tableItem: SignificantItem | GroupTableItem) => {
|
||||
const message = logPatternAnalysisUrlError
|
||||
? logPatternAnalysisUrlError
|
||||
: viewInLogPatternAnalysisMessage;
|
||||
|
|
|
@ -20,14 +20,14 @@ import {
|
|||
import { EuiLoadingChart, EuiTextColor } from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { SignificantTermHistogramItem } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemHistogramItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
import { useEuiTheme } from '../../hooks/use_eui_theme';
|
||||
|
||||
interface MiniHistogramProps {
|
||||
chartData?: SignificantTermHistogramItem[];
|
||||
chartData?: SignificantItemHistogramItem[];
|
||||
isLoading: boolean;
|
||||
label: string;
|
||||
/** Optional color override for the default bar color for charts */
|
||||
|
|
|
@ -10,7 +10,7 @@ import { each, get } from 'lodash';
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
import type { Query } from '@kbn/es-query';
|
||||
import type { RandomSamplerWrapper } from '@kbn/ml-random-sampler-utils';
|
||||
|
||||
|
@ -34,8 +34,8 @@ export interface DocumentStatsSearchStrategyParams {
|
|||
timeFieldName?: string;
|
||||
runtimeFieldMap?: estypes.MappingRuntimeFields;
|
||||
fieldsToFetch?: string[];
|
||||
selectedSignificantTerm?: SignificantTerm;
|
||||
includeSelectedSignificantTerm?: boolean;
|
||||
selectedSignificantItem?: SignificantItem;
|
||||
includeSelectedSignificantItem?: boolean;
|
||||
selectedGroup?: GroupTableItem | null;
|
||||
trackTotalHits?: boolean;
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ export const getDocumentCountStatsRequest = (
|
|||
searchQuery,
|
||||
intervalMs,
|
||||
fieldsToFetch,
|
||||
selectedSignificantTerm,
|
||||
includeSelectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
includeSelectedSignificantItem,
|
||||
selectedGroup,
|
||||
trackTotalHits,
|
||||
} = params;
|
||||
|
@ -66,8 +66,8 @@ export const getDocumentCountStatsRequest = (
|
|||
earliestMs,
|
||||
latestMs,
|
||||
searchQuery,
|
||||
selectedSignificantTerm,
|
||||
includeSelectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
includeSelectedSignificantItem,
|
||||
selectedGroup
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import type { Moment } from 'moment';
|
|||
|
||||
import { useExecutionContext } from '@kbn/kibana-react-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { Dictionary } from '@kbn/ml-url-state';
|
||||
import { mlTimefilterRefresh$, useTimefilter } from '@kbn/ml-date-picker';
|
||||
|
@ -34,7 +34,7 @@ export const useData = (
|
|||
contextId: string,
|
||||
searchQuery: estypes.QueryDslQueryContainer,
|
||||
onUpdate?: (params: Dictionary<unknown>) => void,
|
||||
selectedSignificantTerm?: SignificantTerm,
|
||||
selectedSignificantItem?: SignificantItem,
|
||||
selectedGroup: GroupTableItem | null = null,
|
||||
barTarget: number = DEFAULT_BAR_TARGET,
|
||||
timeRange?: { min: Moment; max: Moment }
|
||||
|
@ -78,27 +78,27 @@ export const useData = (
|
|||
return fieldStatsRequest
|
||||
? {
|
||||
...fieldStatsRequest,
|
||||
selectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
selectedGroup,
|
||||
includeSelectedSignificantTerm: false,
|
||||
includeSelectedSignificantItem: false,
|
||||
}
|
||||
: undefined;
|
||||
}, [fieldStatsRequest, selectedSignificantTerm, selectedGroup]);
|
||||
}, [fieldStatsRequest, selectedSignificantItem, selectedGroup]);
|
||||
|
||||
const selectedSignificantTermStatsRequest = useMemo(() => {
|
||||
return fieldStatsRequest && (selectedSignificantTerm || selectedGroup)
|
||||
const selectedSignificantItemStatsRequest = useMemo(() => {
|
||||
return fieldStatsRequest && (selectedSignificantItem || selectedGroup)
|
||||
? {
|
||||
...fieldStatsRequest,
|
||||
selectedSignificantTerm,
|
||||
selectedSignificantItem,
|
||||
selectedGroup,
|
||||
includeSelectedSignificantTerm: true,
|
||||
includeSelectedSignificantItem: true,
|
||||
}
|
||||
: undefined;
|
||||
}, [fieldStatsRequest, selectedSignificantTerm, selectedGroup]);
|
||||
}, [fieldStatsRequest, selectedSignificantItem, selectedGroup]);
|
||||
|
||||
const documentStats = useDocumentCountStats(
|
||||
overallStatsRequest,
|
||||
selectedSignificantTermStatsRequest,
|
||||
selectedSignificantItemStatsRequest,
|
||||
lastRefresh
|
||||
);
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ export function useDocumentCountStats<TParams extends DocumentStatsSearchStrateg
|
|||
|
||||
const totalHitsParams = {
|
||||
...searchParams,
|
||||
selectedSignificantTerm: undefined,
|
||||
selectedSignificantItem: undefined,
|
||||
trackTotalHits: true,
|
||||
};
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
// To optimize the `frequent_item_sets` query, we identify duplicate significant terms by count attributes.
|
||||
// Note this is a compromise and not 100% accurate because there could be significant terms that
|
||||
// To optimize the `frequent_item_sets` query, we identify duplicate significant items by count attributes.
|
||||
// Note this is a compromise and not 100% accurate because there could be significant items that
|
||||
// have the exact same counts but still don't co-occur.
|
||||
export const duplicateIdentifier: Array<keyof SignificantTerm> = [
|
||||
export const duplicateIdentifier: Array<keyof SignificantItem> = [
|
||||
'doc_count',
|
||||
'bg_count',
|
||||
'total_doc_count',
|
||||
|
|
|
@ -12,12 +12,12 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
|||
|
||||
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import { type SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import { type SignificantItem } from '@kbn/ml-agg-utils';
|
||||
import { createRandomSamplerWrapper } from '@kbn/ml-random-sampler-utils';
|
||||
|
||||
import { RANDOM_SAMPLER_SEED, LOG_RATE_ANALYSIS_SETTINGS } from '../../../../common/constants';
|
||||
import type {
|
||||
SignificantTermDuplicateGroup,
|
||||
SignificantItemDuplicateGroup,
|
||||
ItemSet,
|
||||
FetchFrequentItemSetsResponse,
|
||||
} from '../../../../common/types';
|
||||
|
@ -29,10 +29,10 @@ interface FrequentItemSetsAggregation extends estypes.AggregationsSamplerAggrega
|
|||
}
|
||||
|
||||
export function groupDuplicates(
|
||||
cps: SignificantTerm[],
|
||||
uniqueFields: Array<keyof SignificantTerm>
|
||||
cps: SignificantItem[],
|
||||
uniqueFields: Array<keyof SignificantItem>
|
||||
) {
|
||||
const groups: SignificantTermDuplicateGroup[] = [];
|
||||
const groups: SignificantItemDuplicateGroup[] = [];
|
||||
|
||||
for (const cp of cps) {
|
||||
const compareAttributes = pick(cp, uniqueFields);
|
||||
|
@ -51,16 +51,16 @@ export function groupDuplicates(
|
|||
return groups;
|
||||
}
|
||||
|
||||
export function getShouldClauses(significantTerms: SignificantTerm[]) {
|
||||
export function getShouldClauses(significantItems: SignificantItem[]) {
|
||||
return Array.from(
|
||||
group(significantTerms, ({ fieldName }) => fieldName),
|
||||
group(significantItems, ({ fieldName }) => fieldName),
|
||||
([field, values]) => ({ terms: { [field]: values.map((d) => d.fieldValue) } })
|
||||
);
|
||||
}
|
||||
|
||||
export function getFrequentItemSetsAggFields(significantTerms: SignificantTerm[]) {
|
||||
export function getFrequentItemSetsAggFields(significantItems: SignificantItem[]) {
|
||||
return Array.from(
|
||||
group(significantTerms, ({ fieldName }) => fieldName),
|
||||
group(significantItems, ({ fieldName }) => fieldName),
|
||||
([field, values]) => ({ field, include: values.map((d) => String(d.fieldValue)) })
|
||||
);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ export async function fetchFrequentItemSets(
|
|||
client: ElasticsearchClient,
|
||||
index: string,
|
||||
searchQuery: estypes.QueryDslQueryContainer,
|
||||
significantTerms: SignificantTerm[],
|
||||
significantItems: SignificantItem[],
|
||||
timeFieldName: string,
|
||||
deviationMin: number,
|
||||
deviationMax: number,
|
||||
|
@ -80,7 +80,7 @@ export async function fetchFrequentItemSets(
|
|||
abortSignal?: AbortSignal
|
||||
): Promise<FetchFrequentItemSetsResponse> {
|
||||
// Sort significant terms by ascending p-value, necessary to apply the field limit correctly.
|
||||
const sortedSignificantTerms = significantTerms.slice().sort((a, b) => {
|
||||
const sortedSignificantItems = significantItems.slice().sort((a, b) => {
|
||||
return (a.pValue ?? 0) - (b.pValue ?? 0);
|
||||
});
|
||||
|
||||
|
@ -98,7 +98,7 @@ export async function fetchFrequentItemSets(
|
|||
},
|
||||
},
|
||||
],
|
||||
should: getShouldClauses(sortedSignificantTerms),
|
||||
should: getShouldClauses(sortedSignificantItems),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -108,7 +108,7 @@ export async function fetchFrequentItemSets(
|
|||
minimum_set_size: 2,
|
||||
size: 200,
|
||||
minimum_support: LOG_RATE_ANALYSIS_SETTINGS.FREQUENT_ITEMS_SETS_MINIMUM_SUPPORT,
|
||||
fields: getFrequentItemSetsAggFields(sortedSignificantTerms),
|
||||
fields: getFrequentItemSetsAggFields(sortedSignificantItems),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -177,7 +177,7 @@ export async function fetchFrequentItemSets(
|
|||
Object.entries(fis.key).forEach(([key, value]) => {
|
||||
result.set[key] = value[0];
|
||||
|
||||
const pValue = sortedSignificantTerms.find(
|
||||
const pValue = sortedSignificantItems.find(
|
||||
(t) => t.fieldName === key && t.fieldValue === value[0]
|
||||
)?.pValue;
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { uniq } from 'lodash';
|
|||
import { ElasticsearchClient } from '@kbn/core/server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import { criticalTableLookup, type Histogram } from '@kbn/ml-chi2test';
|
||||
import { type SignificantTerm, SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { type SignificantItem, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { Category } from '../../../../common/api/log_categorization/types';
|
||||
import type { AiopsLogRateAnalysisSchema } from '../../../../common/api/log_rate_analysis/schema';
|
||||
|
@ -83,7 +83,7 @@ export const fetchSignificantCategories = async (
|
|||
|
||||
if (categoriesOverall.length !== fieldNames.length) return [];
|
||||
|
||||
const significantCategories: SignificantTerm[] = [];
|
||||
const significantCategories: SignificantItem[] = [];
|
||||
|
||||
// Using for...of to allow `await` within the loop.
|
||||
for (const [i, fieldName] of fieldNames.entries()) {
|
||||
|
@ -152,7 +152,7 @@ export const fetchSignificantCategories = async (
|
|||
score,
|
||||
pValue,
|
||||
normalizedScore: getNormalizedScore(score),
|
||||
type: SIGNIFICANT_TERM_TYPE.LOG_PATTERN,
|
||||
type: SIGNIFICANT_ITEM_TYPE.LOG_PATTERN,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
|||
import { ElasticsearchClient } from '@kbn/core/server';
|
||||
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import { type SignificantTerm, SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { type SignificantItem, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import {
|
||||
createRandomSamplerWrapper,
|
||||
type RandomSamplerWrapper,
|
||||
|
@ -111,13 +111,13 @@ export const fetchSignificantTermPValues = async (
|
|||
sampleProbability: number = 1,
|
||||
emitError: (m: string) => void,
|
||||
abortSignal?: AbortSignal
|
||||
): Promise<SignificantTerm[]> => {
|
||||
): Promise<SignificantItem[]> => {
|
||||
const randomSamplerWrapper = createRandomSamplerWrapper({
|
||||
probability: sampleProbability,
|
||||
seed: RANDOM_SAMPLER_SEED,
|
||||
});
|
||||
|
||||
const result: SignificantTerm[] = [];
|
||||
const result: SignificantItem[] = [];
|
||||
|
||||
const settledPromises = await Promise.allSettled(
|
||||
fieldNames.map((fieldName) =>
|
||||
|
@ -168,7 +168,7 @@ export const fetchSignificantTermPValues = async (
|
|||
if (typeof pValue === 'number' && pValue < LOG_RATE_ANALYSIS_SETTINGS.P_VALUE_THRESHOLD) {
|
||||
result.push({
|
||||
key: `${fieldName}:${String(bucket.key)}`,
|
||||
type: SIGNIFICANT_TERM_TYPE.KEYWORD,
|
||||
type: SIGNIFICANT_ITEM_TYPE.KEYWORD,
|
||||
fieldName,
|
||||
fieldValue: String(bucket.key),
|
||||
doc_count: bucket.doc_count,
|
||||
|
|
|
@ -11,7 +11,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
|||
|
||||
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import type { FieldValuePair, SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { FieldValuePair, SignificantItem } from '@kbn/ml-agg-utils';
|
||||
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
|
||||
|
||||
import type { AiopsLogRateAnalysisSchema } from '../../../../common/api/log_rate_analysis/schema';
|
||||
|
@ -68,9 +68,9 @@ export async function fetchTerms2CategoriesCounts(
|
|||
esClient: ElasticsearchClient,
|
||||
params: AiopsLogRateAnalysisSchema,
|
||||
searchQuery: estypes.QueryDslQueryContainer,
|
||||
significantTerms: SignificantTerm[],
|
||||
significantTerms: SignificantItem[],
|
||||
itemSets: ItemSet[],
|
||||
significantCategories: SignificantTerm[],
|
||||
significantCategories: SignificantItem[],
|
||||
from: number,
|
||||
to: number,
|
||||
logger: Logger,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { significantTermGroups } from '../../../../common/__mocks__/farequote/significant_term_groups';
|
||||
import { significantItemGroups } from '../../../../common/__mocks__/farequote/significant_item_groups';
|
||||
import { fields } from '../../../../common/__mocks__/artificial_logs/fields';
|
||||
import { filteredFrequentItemSets } from '../../../../common/__mocks__/artificial_logs/filtered_frequent_item_sets';
|
||||
import { significantTerms } from '../../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
@ -16,7 +16,7 @@ import { getSimpleHierarchicalTreeLeaves } from './get_simple_hierarchical_tree_
|
|||
|
||||
describe('getFieldValuePairCounts', () => {
|
||||
it('returns a nested record with field/value pair counts for farequote', () => {
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantTermGroups);
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantItemGroups);
|
||||
|
||||
expect(fieldValuePairCounts).toEqual({
|
||||
airline: {
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { FieldValuePairCounts } from '../../../../common/types';
|
||||
|
||||
/**
|
||||
* Get a nested record of field/value pairs with counts
|
||||
*/
|
||||
export function getFieldValuePairCounts(cpgs: SignificantTermGroup[]): FieldValuePairCounts {
|
||||
export function getFieldValuePairCounts(cpgs: SignificantItemGroup[]): FieldValuePairCounts {
|
||||
return cpgs.reduce<FieldValuePairCounts>((p, { group }) => {
|
||||
group.forEach(({ fieldName, fieldValue }) => {
|
||||
if (p[fieldName] === undefined) {
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { finalSignificantTermGroups } from '../../../../common/__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantItemGroups } from '../../../../common/__mocks__/artificial_logs/final_significant_item_groups';
|
||||
|
||||
import { getGroupFilter } from './get_group_filter';
|
||||
|
||||
describe('getGroupFilter', () => {
|
||||
it('gets a query filter for the significant terms of a group', () => {
|
||||
expect(getGroupFilter(finalSignificantTermGroups[0])).toStrictEqual([
|
||||
it('gets a query filter for the significant items of a group', () => {
|
||||
expect(getGroupFilter(finalSignificantItemGroups[0])).toStrictEqual([
|
||||
{
|
||||
term: {
|
||||
url: 'login.php',
|
||||
|
|
|
@ -7,21 +7,21 @@
|
|||
|
||||
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { type SignificantTermGroup, SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { type SignificantItemGroup, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { getCategoryQuery } from '../../../../common/api/log_categorization/get_category_query';
|
||||
|
||||
// Transforms a list of significant terms from a group in a query filter.
|
||||
// Transforms a list of significant items from a group in a query filter.
|
||||
// Uses a `term` filter for single field value combinations.
|
||||
// For fields with multiple values it creates a single `terms` filter that includes
|
||||
// all values. This avoids queries not returning any results otherwise because
|
||||
// separate `term` filter for multiple values for the same field would rule each other out.
|
||||
export function getGroupFilter(
|
||||
significantTermGroup: SignificantTermGroup
|
||||
significantItemGroup: SignificantItemGroup
|
||||
): estypes.QueryDslQueryContainer[] {
|
||||
const groupKeywordFilter = Object.entries(
|
||||
significantTermGroup.group
|
||||
.filter((d) => d.type === SIGNIFICANT_TERM_TYPE.KEYWORD)
|
||||
significantItemGroup.group
|
||||
.filter((d) => d.type === SIGNIFICANT_ITEM_TYPE.KEYWORD)
|
||||
.reduce<Record<string, Array<string | number>>>((p, c) => {
|
||||
if (p[c.fieldName]) {
|
||||
p[c.fieldName].push(c.fieldValue);
|
||||
|
@ -35,8 +35,8 @@ export function getGroupFilter(
|
|||
return p;
|
||||
}, []);
|
||||
|
||||
const groupLogPatternFilter = significantTermGroup.group
|
||||
.filter((d) => d.type === SIGNIFICANT_TERM_TYPE.LOG_PATTERN)
|
||||
const groupLogPatternFilter = significantItemGroup.group
|
||||
.filter((d) => d.type === SIGNIFICANT_ITEM_TYPE.LOG_PATTERN)
|
||||
.map((d) =>
|
||||
getCategoryQuery(d.fieldName, [
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { significantTermGroups } from '../../../../common/__mocks__/artificial_logs/significant_term_groups';
|
||||
import { significantItemGroups } from '../../../../common/__mocks__/artificial_logs/significant_item_groups';
|
||||
import { significantTerms } from '../../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
||||
import { duplicateIdentifier } from './duplicate_identifier';
|
||||
|
@ -16,15 +16,15 @@ import { getMarkedDuplicates } from './get_marked_duplicates';
|
|||
|
||||
describe('getGroupsWithReaddedDuplicates', () => {
|
||||
it('gets groups with readded duplicates', () => {
|
||||
const groupedSignificantTerms = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
const groupedSignificantItems = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
(g) => g.group.length > 1
|
||||
);
|
||||
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantTermGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantTermGroups, fieldValuePairCounts);
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantItemGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantItemGroups, fieldValuePairCounts);
|
||||
const groupsWithReaddedDuplicates = getGroupsWithReaddedDuplicates(
|
||||
markedDuplicates,
|
||||
groupedSignificantTerms
|
||||
groupedSignificantItems
|
||||
);
|
||||
|
||||
expect(groupsWithReaddedDuplicates).toEqual([
|
||||
|
|
|
@ -7,20 +7,20 @@
|
|||
|
||||
import { uniqWith, isEqual } from 'lodash';
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { SignificantTermDuplicateGroup } from '../../../../common/types';
|
||||
import type { SignificantItemDuplicateGroup } from '../../../../common/types';
|
||||
|
||||
export function getGroupsWithReaddedDuplicates(
|
||||
groups: SignificantTermGroup[],
|
||||
groupedSignificantTerms: SignificantTermDuplicateGroup[]
|
||||
): SignificantTermGroup[] {
|
||||
groups: SignificantItemGroup[],
|
||||
groupedSignificantItems: SignificantItemDuplicateGroup[]
|
||||
): SignificantItemGroup[] {
|
||||
return groups.map((g) => {
|
||||
const group = [...g.group];
|
||||
|
||||
for (const groupItem of g.group) {
|
||||
const { duplicate } = groupItem;
|
||||
const duplicates = groupedSignificantTerms.find((d) =>
|
||||
const duplicates = groupedSignificantItems.find((d) =>
|
||||
d.group.some(
|
||||
(dg) => dg.fieldName === groupItem.fieldName && dg.fieldValue === groupItem.fieldValue
|
||||
)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { significantTermGroups } from '../../../../common/__mocks__/farequote/significant_term_groups';
|
||||
import { significantItemGroups } from '../../../../common/__mocks__/farequote/significant_item_groups';
|
||||
import { fields } from '../../../../common/__mocks__/artificial_logs/fields';
|
||||
import { filteredFrequentItemSets } from '../../../../common/__mocks__/artificial_logs/filtered_frequent_item_sets';
|
||||
import { significantTerms } from '../../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
@ -16,9 +16,9 @@ import { getSimpleHierarchicalTree } from './get_simple_hierarchical_tree';
|
|||
import { getSimpleHierarchicalTreeLeaves } from './get_simple_hierarchical_tree_leaves';
|
||||
|
||||
describe('markDuplicates', () => {
|
||||
it('marks duplicates based on significant terms groups for farequote', () => {
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantTermGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantTermGroups, fieldValuePairCounts);
|
||||
it('marks duplicates based on significant items groups for farequote', () => {
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantItemGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantItemGroups, fieldValuePairCounts);
|
||||
|
||||
expect(markedDuplicates).toEqual([
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ describe('markDuplicates', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('marks duplicates based on significant terms groups for artificial logs', () => {
|
||||
it('marks duplicates based on significant items groups for artificial logs', () => {
|
||||
const simpleHierarchicalTree = getSimpleHierarchicalTree(
|
||||
filteredFrequentItemSets,
|
||||
true,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { FieldValuePairCounts } from '../../../../common/types';
|
||||
|
||||
|
@ -13,9 +13,9 @@ import type { FieldValuePairCounts } from '../../../../common/types';
|
|||
* Analyse duplicate field/value pairs in groups.
|
||||
*/
|
||||
export function getMarkedDuplicates(
|
||||
cpgs: SignificantTermGroup[],
|
||||
cpgs: SignificantItemGroup[],
|
||||
fieldValuePairCounts: FieldValuePairCounts
|
||||
): SignificantTermGroup[] {
|
||||
): SignificantItemGroup[] {
|
||||
return cpgs.map((cpg) => {
|
||||
return {
|
||||
...cpg,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { significantTermGroups } from '../../../../common/__mocks__/artificial_logs/significant_term_groups';
|
||||
import { significantItemGroups } from '../../../../common/__mocks__/artificial_logs/significant_item_groups';
|
||||
import { significantTerms } from '../../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
||||
import { duplicateIdentifier } from './duplicate_identifier';
|
||||
|
@ -13,27 +13,27 @@ import { getGroupsWithReaddedDuplicates } from './get_groups_with_readded_duplic
|
|||
import { groupDuplicates } from './fetch_frequent_item_sets';
|
||||
import { getFieldValuePairCounts } from './get_field_value_pair_counts';
|
||||
import { getMarkedDuplicates } from './get_marked_duplicates';
|
||||
import { getMissingSignificantTerms } from './get_missing_significant_terms';
|
||||
import { getMissingSignificantItems } from './get_missing_significant_items';
|
||||
|
||||
describe('getMissingSignificantTerms', () => {
|
||||
it('get missing significant terms', () => {
|
||||
const groupedSignificantTerms = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
describe('getMissingSignificantItems', () => {
|
||||
it('get missing significant items', () => {
|
||||
const groupedSignificantItems = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
(g) => g.group.length > 1
|
||||
);
|
||||
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantTermGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantTermGroups, fieldValuePairCounts);
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantItemGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantItemGroups, fieldValuePairCounts);
|
||||
const groupsWithReaddedDuplicates = getGroupsWithReaddedDuplicates(
|
||||
markedDuplicates,
|
||||
groupedSignificantTerms
|
||||
groupedSignificantItems
|
||||
);
|
||||
|
||||
const missingSignificantTerms = getMissingSignificantTerms(
|
||||
const missingSignificantItems = getMissingSignificantItems(
|
||||
significantTerms,
|
||||
groupsWithReaddedDuplicates
|
||||
);
|
||||
|
||||
expect(missingSignificantTerms).toEqual([
|
||||
expect(missingSignificantItems).toEqual([
|
||||
{
|
||||
key: 'user:Peter',
|
||||
type: 'keyword',
|
|
@ -5,14 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
export function getMissingSignificantTerms(
|
||||
significantTerms: SignificantTerm[],
|
||||
significantTermGroups: SignificantTermGroup[]
|
||||
export function getMissingSignificantItems(
|
||||
significantItems: SignificantItem[],
|
||||
significantItemGroups: SignificantItemGroup[]
|
||||
) {
|
||||
return significantTerms.filter((cp) => {
|
||||
return !significantTermGroups.some((cpg) => {
|
||||
return significantItems.filter((cp) => {
|
||||
return !significantItemGroups.some((cpg) => {
|
||||
return cpg.group.some((d) => d.fieldName === cp.fieldName && d.fieldValue === cp.fieldValue);
|
||||
});
|
||||
});
|
|
@ -10,20 +10,20 @@ import { orderBy } from 'lodash';
|
|||
import { fields } from '../../../../common/__mocks__/artificial_logs/fields';
|
||||
import { frequentItemSets } from '../../../../common/__mocks__/artificial_logs/frequent_item_sets';
|
||||
import { significantTerms } from '../../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
import { finalSignificantTermGroups } from '../../../../common/__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantItemGroups } from '../../../../common/__mocks__/artificial_logs/final_significant_item_groups';
|
||||
|
||||
import { getSignificantTermGroups } from './get_significant_term_groups';
|
||||
import { getSignificantItemGroups } from './get_significant_item_groups';
|
||||
|
||||
describe('getSignificantTermGroups', () => {
|
||||
it('gets significant terms groups', () => {
|
||||
const significantTermGroups = getSignificantTermGroups(
|
||||
describe('getSignificantItemGroups', () => {
|
||||
it('gets significant items groups', () => {
|
||||
const significantItemGroups = getSignificantItemGroups(
|
||||
frequentItemSets,
|
||||
significantTerms,
|
||||
fields
|
||||
);
|
||||
|
||||
expect(orderBy(significantTermGroups, ['docCount'])).toEqual(
|
||||
orderBy(finalSignificantTermGroups, ['docCount'])
|
||||
expect(orderBy(significantItemGroups, ['docCount'])).toEqual(
|
||||
orderBy(finalSignificantItemGroups, ['docCount'])
|
||||
);
|
||||
});
|
||||
});
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import { duplicateIdentifier } from './duplicate_identifier';
|
||||
import { groupDuplicates } from './fetch_frequent_item_sets';
|
||||
|
@ -13,18 +13,18 @@ import { getFieldValuePairCounts } from './get_field_value_pair_counts';
|
|||
import { getMarkedDuplicates } from './get_marked_duplicates';
|
||||
import { getSimpleHierarchicalTree } from './get_simple_hierarchical_tree';
|
||||
import { getSimpleHierarchicalTreeLeaves } from './get_simple_hierarchical_tree_leaves';
|
||||
import { getMissingSignificantTerms } from './get_missing_significant_terms';
|
||||
import { transformSignificantTermToGroup } from './transform_significant_term_to_group';
|
||||
import { getMissingSignificantItems } from './get_missing_significant_items';
|
||||
import { transformSignificantItemToGroup } from './transform_significant_item_to_group';
|
||||
import type { ItemSet } from '../../../../common/types';
|
||||
|
||||
export function getSignificantTermGroups(
|
||||
export function getSignificantItemGroups(
|
||||
itemsets: ItemSet[],
|
||||
significantTerms: SignificantTerm[],
|
||||
significantItems: SignificantItem[],
|
||||
fields: string[]
|
||||
): SignificantTermGroup[] {
|
||||
// We use the grouped significant terms to later repopulate
|
||||
): SignificantItemGroup[] {
|
||||
// We use the grouped significant items to later repopulate
|
||||
// the `frequent_item_sets` result with the missing duplicates.
|
||||
const groupedSignificantTerms = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
const groupedSignificantItems = groupDuplicates(significantItems, duplicateIdentifier).filter(
|
||||
(g) => g.group.length > 1
|
||||
);
|
||||
|
||||
|
@ -33,7 +33,7 @@ export function getSignificantTermGroups(
|
|||
// and then summarize them in larger groups where possible.
|
||||
|
||||
// Get a tree structure based on `frequent_item_sets`.
|
||||
const { root } = getSimpleHierarchicalTree(itemsets, false, false, significantTerms, fields);
|
||||
const { root } = getSimpleHierarchicalTree(itemsets, false, false, significantItems, fields);
|
||||
|
||||
// Each leave of the tree will be a summarized group of co-occuring field/value pairs.
|
||||
const treeLeaves = getSimpleHierarchicalTreeLeaves(root, []);
|
||||
|
@ -42,21 +42,21 @@ export function getSignificantTermGroups(
|
|||
// that occur in multiple groups. This will allow us to highlight field/value pairs that are
|
||||
// unique to a group in a better way.
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(treeLeaves);
|
||||
const significantTermGroups = getMarkedDuplicates(treeLeaves, fieldValuePairCounts);
|
||||
const significantItemGroups = getMarkedDuplicates(treeLeaves, fieldValuePairCounts);
|
||||
|
||||
// Some field/value pairs might not be part of the `frequent_item_sets` result set, for example
|
||||
// because they don't co-occur with other field/value pairs or because of the limits we set on the query.
|
||||
// In this next part we identify those missing pairs and add them as individual groups.
|
||||
const missingSignificantTerms = getMissingSignificantTerms(
|
||||
significantTerms,
|
||||
significantTermGroups
|
||||
const missingSignificantItems = getMissingSignificantItems(
|
||||
significantItems,
|
||||
significantItemGroups
|
||||
);
|
||||
|
||||
significantTermGroups.push(
|
||||
...missingSignificantTerms.map((significantTerm) =>
|
||||
transformSignificantTermToGroup(significantTerm, groupedSignificantTerms)
|
||||
significantItemGroups.push(
|
||||
...missingSignificantItems.map((significantItem) =>
|
||||
transformSignificantItemToGroup(significantItem, groupedSignificantItems)
|
||||
)
|
||||
);
|
||||
|
||||
return significantTermGroups;
|
||||
return significantItemGroups;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { ItemSet, SimpleHierarchicalTreeNode } from '../../../../common/types';
|
||||
|
||||
|
@ -34,7 +34,7 @@ function NewNodeFactory(name: string): SimpleHierarchicalTreeNode {
|
|||
* The resulting tree components are non-overlapping subsets of the data.
|
||||
* In summary, we start with the most inclusive itemset (highest count), and perform a depth first search in field order.
|
||||
*
|
||||
* @param significantTerms
|
||||
* @param significantItems
|
||||
* @param fields
|
||||
* @param displayParent
|
||||
* @param parentDocCount
|
||||
|
@ -47,7 +47,7 @@ function NewNodeFactory(name: string): SimpleHierarchicalTreeNode {
|
|||
* @returns
|
||||
*/
|
||||
function dfDepthFirstSearch(
|
||||
significantTerms: SignificantTerm[],
|
||||
significantItems: SignificantItem[],
|
||||
fields: string[],
|
||||
displayParent: SimpleHierarchicalTreeNode,
|
||||
parentDocCount: number,
|
||||
|
@ -79,10 +79,10 @@ function dfDepthFirstSearch(
|
|||
|
||||
let displayNode: SimpleHierarchicalTreeNode;
|
||||
|
||||
const significantTerm = significantTerms.find(
|
||||
const significantItem = significantItems.find(
|
||||
(d) => d.fieldName === field && d.fieldValue === value
|
||||
);
|
||||
if (!significantTerm) {
|
||||
if (!significantItem) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,8 @@ function dfDepthFirstSearch(
|
|||
displayParent.name += ` ${value}`;
|
||||
|
||||
displayParent.set.push({
|
||||
key: significantTerm.key,
|
||||
type: significantTerm.type,
|
||||
key: significantItem.key,
|
||||
type: significantItem.type,
|
||||
fieldName: field,
|
||||
fieldValue: value,
|
||||
docCount,
|
||||
|
@ -105,8 +105,8 @@ function dfDepthFirstSearch(
|
|||
displayNode = NewNodeFactory(`${docCount}/${totalDocCount}${label}`);
|
||||
displayNode.set = [...displayParent.set];
|
||||
displayNode.set.push({
|
||||
key: significantTerm.key,
|
||||
type: significantTerm.type,
|
||||
key: significantItem.key,
|
||||
type: significantItem.type,
|
||||
fieldName: field,
|
||||
fieldValue: value,
|
||||
docCount,
|
||||
|
@ -148,7 +148,7 @@ function dfDepthFirstSearch(
|
|||
let subCount = 0;
|
||||
for (const nextValue of getValuesDescending(filteredItemSets, nextField)) {
|
||||
subCount += dfDepthFirstSearch(
|
||||
significantTerms,
|
||||
significantItems,
|
||||
fields,
|
||||
displayNode,
|
||||
docCount,
|
||||
|
@ -181,7 +181,7 @@ export function getSimpleHierarchicalTree(
|
|||
itemSets: ItemSet[],
|
||||
collapseRedundant: boolean,
|
||||
displayOther: boolean,
|
||||
significantTerms: SignificantTerm[],
|
||||
significantItems: SignificantItem[],
|
||||
fields: string[] = []
|
||||
) {
|
||||
const totalDocCount = Math.max(...itemSets.map((d) => d.total_doc_count));
|
||||
|
@ -191,7 +191,7 @@ export function getSimpleHierarchicalTree(
|
|||
for (const field of fields) {
|
||||
for (const value of getValuesDescending(itemSets, field)) {
|
||||
dfDepthFirstSearch(
|
||||
significantTerms,
|
||||
significantItems,
|
||||
fields,
|
||||
newRoot,
|
||||
totalDocCount + 1,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { orderBy } from 'lodash';
|
||||
import type { SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
import { stringHash } from '@kbn/ml-string-hash';
|
||||
|
||||
import type { SimpleHierarchicalTreeNode } from '../../../../common/types';
|
||||
|
@ -16,7 +16,7 @@ import type { SimpleHierarchicalTreeNode } from '../../../../common/types';
|
|||
*/
|
||||
export function getSimpleHierarchicalTreeLeaves(
|
||||
tree: SimpleHierarchicalTreeNode,
|
||||
leaves: SignificantTermGroup[],
|
||||
leaves: SignificantItemGroup[],
|
||||
level = 1
|
||||
) {
|
||||
if (tree.children.length === 0) {
|
||||
|
@ -43,7 +43,7 @@ export function getSimpleHierarchicalTreeLeaves(
|
|||
const sortedLeaves = orderBy(leaves, [(d) => d.group.length], ['desc']);
|
||||
|
||||
// Checks if a group is a subset of items already present in a larger group.
|
||||
const filteredLeaves = sortedLeaves.reduce<SignificantTermGroup[]>((p, c) => {
|
||||
const filteredLeaves = sortedLeaves.reduce<SignificantItemGroup[]>((p, c) => {
|
||||
const isSubset = p.some((pG) =>
|
||||
c.group.every((cGI) =>
|
||||
pG.group.some((pGI) => pGI.fieldName === cGI.fieldName && pGI.fieldValue === cGI.fieldValue)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { significantTermGroups } from '../../../../common/__mocks__/artificial_logs/significant_term_groups';
|
||||
import { significantItemGroups } from '../../../../common/__mocks__/artificial_logs/significant_item_groups';
|
||||
import { significantTerms } from '../../../../common/__mocks__/artificial_logs/significant_terms';
|
||||
|
||||
import { duplicateIdentifier } from './duplicate_identifier';
|
||||
|
@ -13,30 +13,30 @@ import { getGroupsWithReaddedDuplicates } from './get_groups_with_readded_duplic
|
|||
import { groupDuplicates } from './fetch_frequent_item_sets';
|
||||
import { getFieldValuePairCounts } from './get_field_value_pair_counts';
|
||||
import { getMarkedDuplicates } from './get_marked_duplicates';
|
||||
import { getMissingSignificantTerms } from './get_missing_significant_terms';
|
||||
import { transformSignificantTermToGroup } from './transform_significant_term_to_group';
|
||||
import { getMissingSignificantItems } from './get_missing_significant_items';
|
||||
import { transformSignificantItemToGroup } from './transform_significant_item_to_group';
|
||||
|
||||
describe('getMissingSignificantTerms', () => {
|
||||
it('get missing significant terms', () => {
|
||||
const groupedSignificantTerms = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
describe('getMissingSignificantItems', () => {
|
||||
it('get missing significant items', () => {
|
||||
const groupedSignificantItems = groupDuplicates(significantTerms, duplicateIdentifier).filter(
|
||||
(g) => g.group.length > 1
|
||||
);
|
||||
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantTermGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantTermGroups, fieldValuePairCounts);
|
||||
const fieldValuePairCounts = getFieldValuePairCounts(significantItemGroups);
|
||||
const markedDuplicates = getMarkedDuplicates(significantItemGroups, fieldValuePairCounts);
|
||||
const groupsWithReaddedDuplicates = getGroupsWithReaddedDuplicates(
|
||||
markedDuplicates,
|
||||
groupedSignificantTerms
|
||||
groupedSignificantItems
|
||||
);
|
||||
|
||||
const missingSignificantTerms = getMissingSignificantTerms(
|
||||
const missingSignificantItems = getMissingSignificantItems(
|
||||
significantTerms,
|
||||
groupsWithReaddedDuplicates
|
||||
);
|
||||
|
||||
const transformed = transformSignificantTermToGroup(
|
||||
missingSignificantTerms[0],
|
||||
groupedSignificantTerms
|
||||
const transformed = transformSignificantItemToGroup(
|
||||
missingSignificantItems[0],
|
||||
groupedSignificantItems
|
||||
);
|
||||
|
||||
expect(transformed).toEqual({
|
|
@ -6,17 +6,17 @@
|
|||
*/
|
||||
|
||||
import { stringHash } from '@kbn/ml-string-hash';
|
||||
import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { SignificantTermDuplicateGroup } from '../../../../common/types';
|
||||
import type { SignificantItemDuplicateGroup } from '../../../../common/types';
|
||||
|
||||
export function transformSignificantTermToGroup(
|
||||
significantTerm: SignificantTerm,
|
||||
groupedSignificantTerms: SignificantTermDuplicateGroup[]
|
||||
): SignificantTermGroup {
|
||||
const { key, type, fieldName, fieldValue, doc_count: docCount, pValue } = significantTerm;
|
||||
export function transformSignificantItemToGroup(
|
||||
significantItem: SignificantItem,
|
||||
groupedSignificantItems: SignificantItemDuplicateGroup[]
|
||||
): SignificantItemGroup {
|
||||
const { key, type, fieldName, fieldValue, doc_count: docCount, pValue } = significantItem;
|
||||
|
||||
const duplicates = groupedSignificantTerms.find((d) =>
|
||||
const duplicates = groupedSignificantItems.find((d) =>
|
||||
d.group.some((dg) => dg.fieldName === fieldName && dg.fieldValue === fieldValue)
|
||||
);
|
||||
|
|
@ -21,23 +21,23 @@ import { i18n } from '@kbn/i18n';
|
|||
import { KBN_FIELD_TYPES } from '@kbn/field-types';
|
||||
import { streamFactory } from '@kbn/ml-response-stream/server';
|
||||
import type {
|
||||
SignificantTerm,
|
||||
SignificantTermGroup,
|
||||
SignificantTermHistogramItem,
|
||||
SignificantItem,
|
||||
SignificantItemGroup,
|
||||
SignificantItemHistogramItem,
|
||||
NumericChartData,
|
||||
NumericHistogramField,
|
||||
} from '@kbn/ml-agg-utils';
|
||||
import { SIGNIFICANT_TERM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
||||
import { fetchHistogramsForFields } from '@kbn/ml-agg-utils';
|
||||
import { createExecutionContext } from '@kbn/ml-route-utils';
|
||||
import type { UsageCounter } from '@kbn/usage-collection-plugin/server';
|
||||
|
||||
import { RANDOM_SAMPLER_SEED, AIOPS_TELEMETRY_ID } from '../../../common/constants';
|
||||
import {
|
||||
addSignificantTermsAction,
|
||||
addSignificantTermsGroupAction,
|
||||
addSignificantTermsGroupHistogramAction,
|
||||
addSignificantTermsHistogramAction,
|
||||
addSignificantItemsAction,
|
||||
addSignificantItemsGroupAction,
|
||||
addSignificantItemsGroupHistogramAction,
|
||||
addSignificantItemsHistogramAction,
|
||||
addErrorAction,
|
||||
pingAction,
|
||||
resetAllAction,
|
||||
|
@ -65,7 +65,7 @@ import { fetchFrequentItemSets } from './queries/fetch_frequent_item_sets';
|
|||
import { fetchTerms2CategoriesCounts } from './queries/fetch_terms_2_categories_counts';
|
||||
import { getHistogramQuery } from './queries/get_histogram_query';
|
||||
import { getGroupFilter } from './queries/get_group_filter';
|
||||
import { getSignificantTermGroups } from './queries/get_significant_term_groups';
|
||||
import { getSignificantItemGroups } from './queries/get_significant_item_groups';
|
||||
import { trackAIOpsRouteUsage } from '../../lib/track_route_usage';
|
||||
|
||||
// 10s ping frequency to keep the stream alive.
|
||||
|
@ -287,19 +287,19 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
}
|
||||
}
|
||||
|
||||
// Step 2: Significant Categories and Terms
|
||||
// Step 2: Significant Categories and Items
|
||||
|
||||
// This will store the combined count of detected significant log patterns and keywords
|
||||
let fieldValuePairsCount = 0;
|
||||
|
||||
const significantCategories: SignificantTerm[] = [];
|
||||
const significantCategories: SignificantItem[] = [];
|
||||
|
||||
if (version === '1') {
|
||||
significantCategories.push(
|
||||
...((
|
||||
request.body as AiopsLogRateAnalysisSchema<'1'>
|
||||
).overrides?.significantTerms?.filter(
|
||||
(d) => d.type === SIGNIFICANT_TERM_TYPE.LOG_PATTERN
|
||||
(d) => d.type === SIGNIFICANT_ITEM_TYPE.LOG_PATTERN
|
||||
) ?? [])
|
||||
);
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
...((
|
||||
request.body as AiopsLogRateAnalysisSchema<'2'>
|
||||
).overrides?.significantItems?.filter(
|
||||
(d) => d.type === SIGNIFICANT_TERM_TYPE.LOG_PATTERN
|
||||
(d) => d.type === SIGNIFICANT_ITEM_TYPE.LOG_PATTERN
|
||||
) ?? [])
|
||||
);
|
||||
}
|
||||
|
@ -329,18 +329,18 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
);
|
||||
|
||||
if (significantCategories.length > 0) {
|
||||
push(addSignificantTermsAction(significantCategories, version));
|
||||
push(addSignificantItemsAction(significantCategories, version));
|
||||
}
|
||||
}
|
||||
|
||||
const significantTerms: SignificantTerm[] = [];
|
||||
const significantTerms: SignificantItem[] = [];
|
||||
|
||||
if (version === '1') {
|
||||
significantTerms.push(
|
||||
...((
|
||||
request.body as AiopsLogRateAnalysisSchema<'1'>
|
||||
).overrides?.significantTerms?.filter(
|
||||
(d) => d.type === SIGNIFICANT_TERM_TYPE.KEYWORD
|
||||
(d) => d.type === SIGNIFICANT_ITEM_TYPE.KEYWORD
|
||||
) ?? [])
|
||||
);
|
||||
}
|
||||
|
@ -350,7 +350,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
...((
|
||||
request.body as AiopsLogRateAnalysisSchema<'2'>
|
||||
).overrides?.significantItems?.filter(
|
||||
(d) => d.type === SIGNIFICANT_TERM_TYPE.KEYWORD
|
||||
(d) => d.type === SIGNIFICANT_ITEM_TYPE.KEYWORD
|
||||
) ?? [])
|
||||
);
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
});
|
||||
significantTerms.push(...pValues);
|
||||
|
||||
push(addSignificantTermsAction(pValues, version));
|
||||
push(addSignificantItemsAction(pValues, version));
|
||||
}
|
||||
|
||||
push(
|
||||
|
@ -571,7 +571,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
}
|
||||
|
||||
if (fields.length > 0 && itemSets.length > 0) {
|
||||
const significantTermGroups = getSignificantTermGroups(
|
||||
const significantItemGroups = getSignificantItemGroups(
|
||||
itemSets,
|
||||
[...significantTerms, ...significantCategories],
|
||||
fields
|
||||
|
@ -579,10 +579,10 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
|
||||
// We'll find out if there's at least one group with at least two items,
|
||||
// only then will we return the groups to the clients and make the grouping option available.
|
||||
const maxItems = Math.max(...significantTermGroups.map((g) => g.group.length));
|
||||
const maxItems = Math.max(...significantItemGroups.map((g) => g.group.length));
|
||||
|
||||
if (maxItems > 1) {
|
||||
push(addSignificantTermsGroupAction(significantTermGroups, version));
|
||||
push(addSignificantItemsGroupAction(significantItemGroups, version));
|
||||
}
|
||||
|
||||
loaded += PROGRESS_STEP_GROUPING;
|
||||
|
@ -595,9 +595,9 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
return;
|
||||
}
|
||||
|
||||
logDebugMessage(`Fetch ${significantTermGroups.length} group histograms.`);
|
||||
logDebugMessage(`Fetch ${significantItemGroups.length} group histograms.`);
|
||||
|
||||
const groupHistogramQueue = queue(async function (cpg: SignificantTermGroup) {
|
||||
const groupHistogramQueue = queue(async function (cpg: SignificantItemGroup) {
|
||||
if (shouldStop) {
|
||||
logDebugMessage('shouldStop abort fetching group histograms.');
|
||||
groupHistogramQueue.kill();
|
||||
|
@ -644,7 +644,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
}
|
||||
return;
|
||||
}
|
||||
const histogram: SignificantTermHistogramItem[] =
|
||||
const histogram: SignificantItemHistogramItem[] =
|
||||
overallTimeSeries.data.map((o) => {
|
||||
const current = cpgTimeSeries.data.find(
|
||||
(d1) => d1.key_as_string === o.key_as_string
|
||||
|
@ -670,7 +670,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
}) ?? [];
|
||||
|
||||
push(
|
||||
addSignificantTermsGroupHistogramAction(
|
||||
addSignificantItemsGroupHistogramAction(
|
||||
[
|
||||
{
|
||||
id: cpg.id,
|
||||
|
@ -683,7 +683,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
}
|
||||
}, MAX_CONCURRENT_QUERIES);
|
||||
|
||||
groupHistogramQueue.push(significantTermGroups);
|
||||
groupHistogramQueue.push(significantItemGroups);
|
||||
await groupHistogramQueue.drain();
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -706,7 +706,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
overallTimeSeries !== undefined &&
|
||||
!request.body.overrides?.regroupOnly
|
||||
) {
|
||||
const fieldValueHistogramQueue = queue(async function (cp: SignificantTerm) {
|
||||
const fieldValueHistogramQueue = queue(async function (cp: SignificantItem) {
|
||||
if (shouldStop) {
|
||||
logDebugMessage('shouldStop abort fetching field/value histograms.');
|
||||
fieldValueHistogramQueue.kill();
|
||||
|
@ -759,7 +759,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
return;
|
||||
}
|
||||
|
||||
const histogram: SignificantTermHistogramItem[] =
|
||||
const histogram: SignificantItemHistogramItem[] =
|
||||
overallTimeSeries.data.map((o) => {
|
||||
const current = cpTimeSeries.data.find(
|
||||
(d1) => d1.key_as_string === o.key_as_string
|
||||
|
@ -788,7 +788,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
loaded += (1 / fieldValuePairsCount) * PROGRESS_STEP_HISTOGRAMS;
|
||||
pushHistogramDataLoadingState();
|
||||
push(
|
||||
addSignificantTermsHistogramAction(
|
||||
addSignificantItemsHistogramAction(
|
||||
[
|
||||
{
|
||||
fieldName,
|
||||
|
@ -863,7 +863,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
return;
|
||||
}
|
||||
|
||||
const histogram: SignificantTermHistogramItem[] =
|
||||
const histogram: SignificantItemHistogramItem[] =
|
||||
overallTimeSeries.data.map((o) => {
|
||||
const current = catTimeSeries.data.find(
|
||||
(d1) => d1.key_as_string === o.key_as_string
|
||||
|
@ -893,7 +893,7 @@ export function routeHandlerFactory<T extends ApiVersion>(
|
|||
loaded += (1 / fieldValuePairsCount) * PROGRESS_STEP_HISTOGRAMS;
|
||||
pushHistogramDataLoadingState();
|
||||
push(
|
||||
addSignificantTermsHistogramAction(
|
||||
addSignificantItemsHistogramAction(
|
||||
[
|
||||
{
|
||||
fieldName,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { stringHash } from '@kbn/ml-string-hash';
|
|||
import { extractErrorProperties } from '@kbn/ml-error-utils';
|
||||
import { Query } from '@kbn/es-query';
|
||||
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { SignificantTerm } from '@kbn/ml-agg-utils';
|
||||
import { SignificantItem } from '@kbn/ml-agg-utils';
|
||||
import {
|
||||
createRandomSamplerWrapper,
|
||||
RandomSampler,
|
||||
|
@ -50,8 +50,8 @@ export interface DocumentStatsSearchStrategyParams {
|
|||
timeFieldName?: string;
|
||||
runtimeFieldMap?: estypes.MappingRuntimeFields;
|
||||
fieldsToFetch?: string[];
|
||||
selectedSignificantTerm?: SignificantTerm;
|
||||
includeSelectedSignificantTerm?: boolean;
|
||||
selectedSignificantItem?: SignificantItem;
|
||||
includeSelectedSignificantItem?: boolean;
|
||||
trackTotalHits?: boolean;
|
||||
}
|
||||
|
||||
|
@ -167,8 +167,8 @@ export interface DocumentStatsSearchStrategyParams {
|
|||
timeFieldName?: string;
|
||||
runtimeFieldMap?: estypes.MappingRuntimeFields;
|
||||
fieldsToFetch?: string[];
|
||||
selectedSignificantTerm?: SignificantTerm;
|
||||
includeSelectedSignificantTerm?: boolean;
|
||||
selectedSignificantItem?: SignificantItem;
|
||||
includeSelectedSignificantItem?: boolean;
|
||||
trackTotalHits?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ export const LogRateAnalysis: FC<AlertDetailsLogRateAnalysisSectionProps> = ({ r
|
|||
|
||||
const onAnalysisCompleted = (analysisResults: LogRateAnalysisResultsData | undefined) => {
|
||||
const significantFieldValues = orderBy(
|
||||
analysisResults?.significantTerms?.map((item) => ({
|
||||
analysisResults?.significantItems?.map((item) => ({
|
||||
field: item.fieldName,
|
||||
value: item.fieldValue,
|
||||
docCount: item.doc_count,
|
||||
|
|
|
@ -7956,7 +7956,7 @@
|
|||
"xpack.aiops.logRateAnalysis.resultsTable.impactLabelColumnTooltip": "Le niveau d'impact du champ sur la différence de taux de messages.",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardButtonLabel": "Copier dans le presse-papiers",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardGroupMessage": "Copier les éléments de groupe en tant que syntaxe KQL dans le Presse-papiers",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantTermMessage": "Copier la paire clé-valeur en tant que syntaxe KQL dans le Presse-papiers",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantItemMessage": "Copier la paire clé-valeur en tant que syntaxe KQL dans le Presse-papiers",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInDiscover": "Afficher dans Discover",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInLogPatternAnalysis": "Voir dans l'analyse du modèle de log",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.logPatternLinkNotAvailableTooltipMessage": "Le lien n'est pas disponible si l'élément du tableau est lui-même un modèle de log.",
|
||||
|
|
|
@ -7971,7 +7971,7 @@
|
|||
"xpack.aiops.logRateAnalysis.resultsTable.impactLabelColumnTooltip": "メッセージレート差異に対するフィールドの影響のレベル。",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardButtonLabel": "クリップボードにコピー",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardGroupMessage": "グループアイテムをKQL構文としてクリップボードにコピー",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantTermMessage": "フィールド/値のペアをKQL構文としてクリップボードにコピー",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantItemMessage": "フィールド/値のペアをKQL構文としてクリップボードにコピー",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInDiscover": "Discoverに表示",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInLogPatternAnalysis": "ログパターン分析で表示",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.logPatternLinkNotAvailableTooltipMessage": "テーブル項目がログパターン自体の場合は、このリンクは使用できません。",
|
||||
|
|
|
@ -7970,7 +7970,7 @@
|
|||
"xpack.aiops.logRateAnalysis.resultsTable.impactLabelColumnTooltip": "字段对消息速率差异的影响水平。",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardButtonLabel": "复制到剪贴板",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardGroupMessage": "将组项目作为 KQL 语法复制到剪贴板",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantTermMessage": "将字段/值对作为 KQL 语法复制到剪贴板",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.copyToClipboardSignificantItemMessage": "将字段/值对作为 KQL 语法复制到剪贴板",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInDiscover": "在 Discover 中查看",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.linksMenu.viewInLogPatternAnalysis": "在日志模式分析中查看",
|
||||
"xpack.aiops.logRateAnalysis.resultsTable.logPatternLinkNotAvailableTooltipMessage": "如果表项目为日志模式本身,则此链接不可用。",
|
||||
|
|
|
@ -70,8 +70,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
);
|
||||
|
||||
expect(significantItems).to.eql(
|
||||
testData.expected.significantTerms,
|
||||
'Significant terms do not match expected values.'
|
||||
testData.expected.significantItems,
|
||||
'Significant items do not match expected values.'
|
||||
);
|
||||
|
||||
const histogramActions = getHistogramActions(data, apiVersion);
|
||||
|
|
|
@ -41,7 +41,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
overrides = {
|
||||
loaded: 0,
|
||||
remainingFieldCandidates: [],
|
||||
significantTerms: testData.expected.significantTerms,
|
||||
significantTerms: testData.expected.significantItems,
|
||||
regroupOnly: true,
|
||||
} as AiopsLogRateAnalysisSchema<typeof apiVersion>['overrides'];
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
loaded: 0,
|
||||
remainingFieldCandidates: [],
|
||||
significantItems: testData.expected
|
||||
.significantTerms as AiopsLogRateAnalysisSchemaSignificantItem[],
|
||||
.significantItems as AiopsLogRateAnalysisSchemaSignificantItem[],
|
||||
regroupOnly: true,
|
||||
} as AiopsLogRateAnalysisSchema<typeof apiVersion>['overrides'];
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
// that also the jest unit tests use mocks that are not outdated.
|
||||
import { significantTerms as artificialLogSignificantTerms } from '@kbn/aiops-plugin/common/__mocks__/artificial_logs/significant_terms';
|
||||
import { significantLogPatterns as artificialLogSignificantLogPatterns } from '@kbn/aiops-plugin/common/__mocks__/artificial_logs/significant_log_patterns';
|
||||
import { finalSignificantTermGroups as artificialLogsSignificantTermGroups } from '@kbn/aiops-plugin/common/__mocks__/artificial_logs/final_significant_term_groups';
|
||||
import { finalSignificantTermGroupsTextfield as artificialLogsSignificantTermGroupsTextfield } from '@kbn/aiops-plugin/common/__mocks__/artificial_logs/final_significant_term_groups_textfield';
|
||||
import { finalSignificantItemGroups as artificialLogsSignificantItemGroups } from '@kbn/aiops-plugin/common/__mocks__/artificial_logs/final_significant_item_groups';
|
||||
import { finalSignificantItemGroupsTextfield as artificialLogsSignificantItemGroupsTextfield } from '@kbn/aiops-plugin/common/__mocks__/artificial_logs/final_significant_item_groups_textfield';
|
||||
|
||||
import type {
|
||||
AiopsLogRateAnalysisSchema,
|
||||
|
@ -45,7 +45,7 @@ export const getLogRateAnalysisTestData = <T extends ApiVersion>(): Array<TestDa
|
|||
actionsLengthGroupOnly: 4,
|
||||
noIndexChunksLength: 4,
|
||||
noIndexActionsLength: 3,
|
||||
significantTerms: [
|
||||
significantItems: [
|
||||
{
|
||||
key: 'day_of_week:Thursday',
|
||||
type: 'keyword',
|
||||
|
@ -99,8 +99,8 @@ export const getLogRateAnalysisTestData = <T extends ApiVersion>(): Array<TestDa
|
|||
actionsLengthGroupOnly: 10,
|
||||
noIndexChunksLength: 4,
|
||||
noIndexActionsLength: 3,
|
||||
significantTerms: artificialLogSignificantTerms,
|
||||
groups: artificialLogsSignificantTermGroups,
|
||||
significantItems: artificialLogSignificantTerms,
|
||||
groups: artificialLogsSignificantItemGroups,
|
||||
histogramLength: 20,
|
||||
},
|
||||
},
|
||||
|
@ -126,8 +126,8 @@ export const getLogRateAnalysisTestData = <T extends ApiVersion>(): Array<TestDa
|
|||
actionsLengthGroupOnly: 10,
|
||||
noIndexChunksLength: 4,
|
||||
noIndexActionsLength: 3,
|
||||
significantTerms: [...artificialLogSignificantTerms, ...artificialLogSignificantLogPatterns],
|
||||
groups: artificialLogsSignificantTermGroupsTextfield,
|
||||
significantItems: [...artificialLogSignificantTerms, ...artificialLogSignificantLogPatterns],
|
||||
groups: artificialLogsSignificantItemGroupsTextfield,
|
||||
histogramLength: 20,
|
||||
},
|
||||
},
|
||||
|
@ -153,8 +153,8 @@ export const getLogRateAnalysisTestData = <T extends ApiVersion>(): Array<TestDa
|
|||
actionsLengthGroupOnly: 10,
|
||||
noIndexChunksLength: 4,
|
||||
noIndexActionsLength: 3,
|
||||
significantTerms: artificialLogSignificantTerms,
|
||||
groups: artificialLogsSignificantTermGroups,
|
||||
significantItems: artificialLogSignificantTerms,
|
||||
groups: artificialLogsSignificantItemGroups,
|
||||
histogramLength: 20,
|
||||
},
|
||||
},
|
||||
|
@ -180,8 +180,8 @@ export const getLogRateAnalysisTestData = <T extends ApiVersion>(): Array<TestDa
|
|||
actionsLengthGroupOnly: 10,
|
||||
noIndexChunksLength: 4,
|
||||
noIndexActionsLength: 3,
|
||||
significantTerms: [...artificialLogSignificantTerms, ...artificialLogSignificantLogPatterns],
|
||||
groups: artificialLogsSignificantTermGroupsTextfield,
|
||||
significantItems: [...artificialLogSignificantTerms, ...artificialLogSignificantLogPatterns],
|
||||
groups: artificialLogsSignificantItemGroupsTextfield,
|
||||
histogramLength: 20,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@ import type {
|
|||
AiopsLogRateAnalysisSchema,
|
||||
AiopsLogRateAnalysisApiVersion as ApiVersion,
|
||||
} from '@kbn/aiops-plugin/common/api/log_rate_analysis/schema';
|
||||
import type { SignificantTerm, SignificantTermGroup } from '@kbn/ml-agg-utils';
|
||||
import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { LogRateAnalysisDataGenerator } from '../../../functional/services/aiops/log_rate_analysis_data_generator';
|
||||
|
||||
|
@ -25,8 +25,8 @@ export interface TestData<T extends ApiVersion> {
|
|||
actionsLengthGroupOnly: number;
|
||||
noIndexChunksLength: number;
|
||||
noIndexActionsLength: number;
|
||||
significantTerms: SignificantTerm[];
|
||||
groups: SignificantTermGroup[];
|
||||
significantItems: SignificantItem[];
|
||||
groups: SignificantItemGroup[];
|
||||
histogramLength: number;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue