Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions dashboards-observability/common/constants/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,10 @@ export const PLOTLY_GAUGE_COLUMN_NUMBER = 4;
export const APP_ANALYTICS_TAB_ID_REGEX = /application-analytics-tab.+/;
export const DEFAULT_AVAILABILITY_QUERY = 'stats count() by span( timestamp, 1h )';
export const PPL_DEFAULT_PATTERN_REGEX_FILETER = '[a-zA-Z\\d]';
export const PPL_PATTERNS_REGEX = /\|\s*patterns.+?\|\s*where\s+patterns_field\s*\=\s*'[^a-zA-Z0-9]+'/;
// Greedily matches the longest substring for example (patterns referer | patterns pattern='[0-9]' message | where ...) used to modify the query for patterns table
export const PATTERNS_REGEX = /\|\s*patterns.+?\|.*\s*where\s+patterns_field\s*\=\s*'[^a-zA-Z0-9]+'/;
// Used to extract the initial pattern applied
export const PATTERNS_EXTRACTOR_REGEX = /patterns\s+(?<pattern>\S+)/;
// Used to extract the pattern that is being searched for (for highlighting pattern in pattern table)
export const SELECTED_PATTERN_REGEX = /\|\s*patterns.+?\|\s*where\s+patterns_field\s*\=\s*'(?<pattern>[^a-zA-Z0-9]+)'/
export const ADD_BUTTON_TEXT = '+ Add color theme';
export const NUMBER_INPUT_MIN_LIMIT = 1;

Expand Down
2 changes: 1 addition & 1 deletion dashboards-observability/common/types/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ export interface PatternTableData {
count: number;
pattern: string;
sampleLog: string;
anomalyCount: number;
anomalyCount?: number;
};

export interface ConfigListEntry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,16 @@ import { cloneDeep, has, isEmpty, isEqual, reduce } from 'lodash';
import React, { ReactElement, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { batch, useDispatch, useSelector } from 'react-redux';
import {
AGGREGATIONS,
AVAILABLE_FIELDS,
CUSTOM_LABEL,
DATE_PICKER_FORMAT,
DEFAULT_AVAILABILITY_QUERY,
EVENT_ANALYTICS_DOCUMENTATION_URL,
FILTERED_PATTERN,
GROUPBY,
NEW_TAB,
PATTERNS_EXTRACTOR_REGEX,
PATTERNS_REGEX,
PATTERN_REGEX,
PPL_DEFAULT_PATTERN_REGEX_FILETER,
PPL_PATTERNS_REGEX,
RAW_QUERY,
SAVED_OBJECT_ID,
SAVED_OBJECT_TYPE,
Expand All @@ -66,28 +62,20 @@ import {
PPL_NEWLINE_REGEX,
PPL_PATTERNS_DOCUMENTATION_URL,
PPL_STATS_REGEX,
VIS_CHART_TYPES,
} from '../../../../common/constants/shared';
import {
getIndexPatternFromRawQuery,
preprocessQuery,
buildQuery,
composeFinalQuery,
} from '../../../../common/utils';
import { formatError, getDefaultVisConfig } from '../utils';
import {
statsChunk,
GroupByChunk,
GroupField,
StatsAggregationChunk,
} from '../../../../common/query_manager/ast/types';
import { GroupByChunk } from '../../../../common/query_manager/ast/types';
import {
IDefaultTimestampState,
IExplorerProps,
IField,
IQueryTab,
IVisualizationContainerProps,
} from '../../../../common/types/explorer';
import {
buildQuery,
composeFinalQuery,
getIndexPatternFromRawQuery,
} from '../../../../common/utils';
import { sleep } from '../../common/live_tail/live_tail_button';
import { onItemSelect, parseGetSuggestions } from '../../common/search/autocomplete_logic';
import { Search } from '../../common/search/search';
Expand All @@ -106,6 +94,7 @@ import {
change as updateVizConfig,
selectVisualizationConfig,
} from '../redux/slices/viualization_config_slice';
import { formatError, getDefaultVisConfig } from '../utils';
import { DataGrid } from './events_views/data_grid';
import './explorer.scss';
import { HitsCounter } from './hits_counter/hits_counter';
Expand Down Expand Up @@ -193,9 +182,8 @@ export const Explorer = ({
const [liveTimestamp, setLiveTimestamp] = useState(DATE_PICKER_FORMAT);
const [triggerAvailability, setTriggerAvailability] = useState(false);
const [viewLogPatterns, setViewLogPatterns] = useState(false);
const [isValidDataConfigOptionSelected, setIsValidDataConfigOptionSelected] = useState<boolean>(
false
);
const [isValidDataConfigOptionSelected, setIsValidDataConfigOptionSelected] =
useState<boolean>(false);
const [spanValue, setSpanValue] = useState(false);
const [subType, setSubType] = useState('visualization');
const [metricMeasure, setMetricMeasure] = useState('');
Expand Down Expand Up @@ -448,8 +436,8 @@ export const Explorer = ({
getCountVisualizations(minInterval);

// to fetch patterns data on current query
if (!finalQuery.match(PPL_PATTERNS_REGEX)) {
getPatterns(minInterval, getErrorHandler('Error fetching patterns'));
if (!finalQuery.match(PATTERNS_REGEX)) {
getPatterns(minInterval);
}
}

Expand Down Expand Up @@ -891,6 +879,11 @@ export const Explorer = ({
tabId={tabId}
query={query}
isPatternLoading={isPatternLoading}
totalHits={reduce(
countDistribution.data['count()'],
(sum, n) => sum + n,
0
)}
/>
<EuiHorizontalRule margin="xs" />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
SortDirection,
} from '@elastic/eui';
import { PatternTableData } from 'common/types/explorer';
import { reduce, round } from 'lodash';
import { round } from 'lodash';
import React from 'react';
import { useSelector } from 'react-redux';
import { FILTERED_PATTERN } from '../../../../../common/constants/explorer';
Expand All @@ -25,11 +25,13 @@ interface PatternsTableProps {
tabId: string;
query: any;
isPatternLoading: boolean;
totalHits?: number;
}

export function PatternsTable(props: PatternsTableProps) {
const { tableData, tabId, onPatternSelection, query } = props;
const patternsData = useSelector(selectPatterns)[tabId];
const totalHits = props.totalHits || tableData.reduce((p, v) => p + v.count, 0);

const tableColumns = [
{
Expand All @@ -47,16 +49,7 @@ export function PatternsTable(props: PatternsTableProps) {
width: '6%',
sortable: (row: PatternTableData) => row.count,
render: (item: number) => {
const ratio =
(item /
reduce(
patternsData.total,
(sum, n) => {
return sum + n;
},
0
)) *
100;
const ratio = (item / totalHits) * 100;
return <EuiText size="s">{`${round(ratio, 2)}%`}</EuiText>;
},
},
Expand All @@ -66,7 +59,7 @@ export function PatternsTable(props: PatternsTableProps) {
width: '6%',
sortable: (row: PatternTableData) => row.anomalyCount,
render: (item: number) => {
return <EuiText size="s">{item}</EuiText>;
return <EuiText size="s">{item ?? 'N/A'}</EuiText>;
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ export const useFetchEvents = ({ pplService, requestParams }: IFetchEventsParams
return pplService
.fetch({ query, format }, errorHandler)
.then((res: any) => handler(res))
.catch((err: any) => console.error(err))
.catch((err: any) => {
console.error(err);
throw err;
})
.finally(() => setIsEventsLoading(false));
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const useFetchPatterns = ({ pplService, requestParams }: IFetchPatternsPa
const queriesRef = useRef();
queriesRef.current = queries;

const dispatchOnPatterns = (res: { patternTableData: PatternTableData[]; total: number[] }) => {
const dispatchOnPatterns = (res: { patternTableData: PatternTableData[] }) => {
batch(() => {
dispatch(
resetPatterns({
Expand Down Expand Up @@ -76,7 +76,7 @@ export const useFetchPatterns = ({ pplService, requestParams }: IFetchPatternsPa

const clearPatternCommands = (query: string) => query.replace(PATTERNS_REGEX, '');

const getPatterns = (interval: string, errorHandler: (error: any) => void, query?: string) => {
const getPatterns = (interval: string, errorHandler?: (error: any) => void, query?: string) => {
const cur = queriesRef.current;
const rawQuery = cur![requestParams.tabId][FINAL_QUERY];
const searchQuery = isUndefined(query) ? clearPatternCommands(rawQuery) : query;
Expand All @@ -92,31 +92,40 @@ export const useFetchPatterns = ({ pplService, requestParams }: IFetchPatternsPa
interval
);
// Fetch patterns data for the current query results
Promise.all([
fetchEvents({ query: statsQuery }, 'jdbc', (res) => res, errorHandler),
fetchEvents({ query: anomaliesQuery }, 'jdbc', (res) => res, errorHandler),
fetchEvents({ query: `${searchQuery} | stats count()` }, 'jdbc', (res) => res, errorHandler),
]).then((res) => {
const [statsRes, anomaliesRes, countRes] = res as IPPLEventsDataSource[];
const anomaliesMap: { [x: string]: number } = {};
anomaliesRes.datarows.forEach((row) => {
const pattern = row[2];
const score = row[3];
if (score > 0) {
anomaliesMap[pattern] = (anomaliesMap[pattern] || 0) + 1;
Promise.allSettled([
fetchEvents({ query: statsQuery }, 'jdbc', (res) => res),
fetchEvents({ query: anomaliesQuery }, 'jdbc', (res) => res),
])
.then((res) => {
const [statsResp, anomaliesResp] = res as PromiseSettledResult<IPPLEventsDataSource>[];
if (statsResp.status === 'rejected') {
throw statsResp.reason;
}
});
const formatToTableData: PatternTableData[] = statsRes.datarows.map((row) => ({
count: row[0],
pattern: row[2],
sampleLog: row[1][0],
anomalyCount: anomaliesMap[row[2]] || 0,
}));
dispatchOnPatterns({
patternTableData: formatToTableData,
total: countRes.datarows[0],
});
});

let anomaliesResultsAvailable = true;
const anomaliesMap: { [x: string]: number } = {};
if (anomaliesResp.status === 'fulfilled') {
anomaliesResp.value.datarows.forEach((row) => {
const pattern = row[2];
const score = row[3];
if (score > 0) {
anomaliesMap[pattern] = (anomaliesMap[pattern] || 0) + 1;
}
});
} else {
console.error('Error fetching anomalies in patterns');
anomaliesResultsAvailable = false;
}

const formatToTableData: PatternTableData[] = statsResp.value.datarows.map((row) => ({
count: row[0],
pattern: row[2],
sampleLog: row[1][0],
anomalyCount: anomaliesResultsAvailable ? anomaliesMap[row[2]] || 0 : undefined,
}));
dispatchOnPatterns({ patternTableData: formatToTableData });
})
.catch(errorHandler);
};

const setDefaultPatternsField = async (
Expand Down
1 change: 1 addition & 0 deletions dashboards-observability/public/services/requests/ppl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default class PPLService {
.catch((error) => {
console.error('fetch error: ', error.body);
if (errorHandler) errorHandler(error);
throw error;
});
};
}