Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/p1 release #133

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
39 changes: 37 additions & 2 deletions common/constants/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,51 @@
*/

export const RAW_QUERY = 'rawQuery';
export const INDEX = 'index';
export const FINAL_QUERY = 'finalQuery';
export const SELECTED_DATE_RANGE = 'selectedDateRange';
export const INDEX = 'indexPattern';
export const SELECTED_FIELDS = 'selectedFields';
export const UNSELECTED_FIELDS = 'unselectedFields';
export const AVAILABLE_FIELDS = 'availableFields';
export const QUERIED_FIELDS = 'queriedFields';
export const TAB_ID_TXT_PFX = 'query-panel-';
export const TAB_TITLE = 'New query';
export const TAB_CHART_TITLE = 'Visualizations';
export const TAB_EVENT_TITLE = 'Events';
export const TAB_EVENT_ID_TXT_PFX = 'main-content-events-';
export const TAB_CHART_ID_TXT_PFX = 'main-content-charts-';
export const TAB_CHART_ID_TXT_PFX = 'main-content-vis-';

export const DATE_PICKER_FORMAT = 'YYYY-MM-DD HH:mm:ss';
export const TIME_INTERVAL_OPTIONS = [
{
display: 'Auto',
val: 'h' // same as value of Hour for now
},
{
display: 'Minute',
val: 'm'
},
{
display: 'Hour',
val: 'h'
},
{
display: 'Day',
val: 'd'
},
{
display: 'Week',
val: 'w'
},
{
display: 'Month',
val: 'M'
},
{
display: 'Year',
val: 'y'
},
]

// redux
export const SELECTED_QUERY_TAB = 'selectedQueryTab';
Expand Down
13 changes: 11 additions & 2 deletions common/constants/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export const DSL_BASE = '/api/dsl';
export const DSL_SEARCH = '/search';
export const DSL_CAT = '/cat.indices';
export const DSL_MAPPING = '/indices.getFieldMapping';
export const OBSERVABILITY_BASE = '/api/observability';
export const EVENT_ANALYTICS = '/event_analytics';
export const SAVED_OBJECTS = '/saved_objects';
export const SAVED_QUERY = '/query';
export const SAVED_VISUALIZATION = '/vis';

// Server route
export const PPL_ENDPOINT = '/_plugins/_ppl';
Expand All @@ -29,11 +34,15 @@ export const observabilityPluginOrder = 6000;
// Shared Constants
export const UI_DATE_FORMAT = 'MM/DD/YYYY hh:mm A';
export const PPL_DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss';
export const PPL_STATS_REGEX = /\|\s*stats/i;
export const PPL_INDEX_INSERT_POINT_REGEX = /search (source|index)\s*=\s*([^\s]+)(.*)/i;
export const PPL_INDEX_REGEX = /(search source|source|index)\s*=\s*([^|\s]+)/i;
export const PPL_CONTAINS_TIMESTAMP_REGEX = /\|\s*.*\s*[<|<=|=|>=|>]\s*timestamp\([^\)]+\)/i;

// Observability plugin URI
const BASE_OBSERVABILITY_URI = '/_plugins/_observability';
export const OPENSEARCH_PANELS_API = {
OBJECT: `${BASE_OBSERVABILITY_URI}/object`,
};
};

// Saved Objects
export const SAVED_OBJECT = '/object';
8 changes: 7 additions & 1 deletion common/types/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
import {
RAW_QUERY,
SELECTED_FIELDS,
UNSELECTED_FIELDS
UNSELECTED_FIELDS,
AVAILABLE_FIELDS,
QUERIED_FIELDS
} from '../constants/explorer';
import SavedObjects from '../../public/services/saved_objects/event_analytics/saved_objects';

export interface IQueryTab {
id: string;
Expand Down Expand Up @@ -45,9 +48,12 @@ export interface IExplorerTabFields {
export interface IExplorerFields {
[SELECTED_FIELDS]: Array<IField>;
[UNSELECTED_FIELDS]: Array<IField>;
[AVAILABLE_FIELDS]: Array<IField>;
[QUERIED_FIELDS]: Array<IField>;
}

export interface ILogExplorerProps {
pplService: any;
dslService: any;
savedObjects: SavedObjects;
}
2 changes: 1 addition & 1 deletion common/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
* GitHub history for details.
*/

export { getIndexPatternFromRawQuery } from './query_utils';
export { getIndexPatternFromRawQuery, insertDateRangeToQuery } from './query_utils';
35 changes: 34 additions & 1 deletion common/utils/query_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,45 @@
* GitHub history for details.
*/

import { PPL_INDEX_REGEX } from "../constants/shared";
import { isEmpty } from 'lodash';
import datemath from '@elastic/datemath';
import { DATE_PICKER_FORMAT } from '../../common/constants/explorer';
import {
PPL_INDEX_REGEX,
PPL_INDEX_INSERT_POINT_REGEX
} from '../../common/constants/shared';

export const getIndexPatternFromRawQuery = (query: string) : string => {
const matches = query.match(PPL_INDEX_REGEX);
if (matches) {
return matches[2];
}
return '';
};

export const insertDateRangeToQuery = ({
rawQuery,
startTime,
endTime,
timeField = 'utc_time',
}: {
rawQuery: string;
startTime: string;
endTime: string;
timeField?: string;
}) => {

let finalQuery = '';

if (isEmpty(rawQuery)) return finalQuery;

// convert to moment
const start = datemath.parse(startTime)?.format(DATE_PICKER_FORMAT);
const end = datemath.parse(endTime)?.format(DATE_PICKER_FORMAT);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you select something like Today or This week from date picker's "commonly used", i remember startTime and endTime will be the same string. could you check if you need to do some handling for that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, on handler side, I added the code to check and change the end to be 'now' if start and end are the same.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mengweieric i think instead of changing it to now, you can use datemath.parse(endTime, {roundUp: true}) so something like "Today" will also include now to end of day. Ref: https://github.com/elastic/kibana/blob/master/packages/elastic-datemath/src/index.ts#L157

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, this makes sense, I'll change it.

const tokens = rawQuery.match(PPL_INDEX_INSERT_POINT_REGEX);

if (isEmpty(tokens)) return finalQuery;
finalQuery = `search ${tokens![1]}=${tokens![2]} | where ${timeField} >= timestamp('${start}') and ${timeField} <= timestamp('${end}')${tokens![3]}`;

return finalQuery;
};
37 changes: 16 additions & 21 deletions public/components/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import { AppPluginStartDependencies } from '../types';
import { Home as ApplicationAnalyticsHome } from './application_analytics/home';
import { renderPageWithSidebar } from './common/side_nav';
import { Home as CustomPanelsHome } from './custom_panels/home';
import { Home as EventExplorerHome } from './explorer/home';
import { LogExplorer } from './explorer/log_explorer';
import { EventAnalytics } from './explorer/event_analytics';
import { Main as NotebooksHome } from './notebooks/components/main';
import { Home as TraceAnalyticsHome } from './trace_analytics/home';

Expand All @@ -30,13 +29,15 @@ interface ObservabilityAppDeps {
DepsStart: AppPluginStartDependencies;
pplService: any;
dslService: any;
savedObjects: any;
}

export const App = ({
CoreStart,
DepsStart,
pplService,
dslService
dslService,
savedObjects
}: ObservabilityAppDeps) => {

const { chrome, http, notifications } = CoreStart;
Expand Down Expand Up @@ -97,17 +98,19 @@ export const App = ({
)}
/>
<Route
exact
path={['/explorer', '/explorer/home']}
path="/event_analytics"
render={(props) => {
chrome.setBreadcrumbs([
parentBreadcrumb,
{
text: 'Event analytics',
href: '/explorer/events',
},
]);
return renderPageWithSidebar(<EventExplorerHome />);
return (
<EventAnalytics
chrome={ chrome }
parentBreadcrumb={ parentBreadcrumb }
pplService={ pplService }
dslService={ dslService }
savedObjects={ savedObjects }
http={ http }
{ ...props }
/>
);
}}
/>
<Route
Expand All @@ -125,14 +128,6 @@ export const App = ({
);
}}
/>
<Route
exact
path='/explorer/events'
render={(props) => <LogExplorer
pplService={ pplService }
dslService={ dslService }
/> }
/>
</Switch>
</>
</I18nProvider>
Expand Down
25 changes: 21 additions & 4 deletions public/components/common/search/autocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,42 @@
*/

import './search.scss';
import React, { useEffect } from 'react';
import React, {
createElement,
Fragment,
useEffect,
useRef
} from 'react';
import { render } from 'react-dom';
import { autocomplete } from '@algolia/autocomplete-js';
import { IQueryBarProps } from './search';
import { RAW_QUERY } from '../../../../common/constants/explorer';
import { createPPLSuggestionsPlugin } from './autocomplete_plugin';

export function Autocomplete(props: IQueryBarProps) {
const containerRef = useRef(null);
const { query, handleQueryChange, handleQuerySearch, dslService } = props;

const PPLSuggestionPlugin = createPPLSuggestionsPlugin({
query,
handleQueryChange: props.handleQueryChange,
handleQuerySearch: props.handleQuerySearch,
dslService: props.dslService,
});

useEffect(() => {

if (!containerRef.current) {
return undefined;
}

const search = autocomplete({
container: '#autocomplete',
initialState: { query: props.query[RAW_QUERY] },
container: containerRef.current,
renderer: { createElement, Fragment },
render({ children }, root) {
render(children, root);
},
initialState: { query: query[RAW_QUERY] },
openOnFocus: true,
placeholder: 'Enter PPL query to retrieve log, traces, and metrics',
plugins: [PPLSuggestionPlugin],
Expand All @@ -40,5 +57,5 @@ export function Autocomplete(props: IQueryBarProps) {
};
}, []);

return <div id="autocomplete" />;
return <div ref={containerRef} />;
}
6 changes: 3 additions & 3 deletions public/components/common/search/autocomplete_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface PPLSuggestion {
}

interface CreatePPLSuggestionsPluginProps {
query: any;
handleQueryChange: (query: string, index: string) => void;
handleQuerySearch: () => void;
dslService: DSLService;
Expand Down Expand Up @@ -173,7 +174,7 @@ const getSuggestions = async (str: string, dslService: DSLService) => {
item: '=',
});
currField = splittedModel[splittedModel.length - 2];
currFieldType = fieldsFromBackend.find((field) => field.label === currField).type;
currFieldType = fieldsFromBackend.find((field) => field.label === currField)?.type;
return fullSuggestions.filter(({ label }) => label.startsWith(prefix) && prefix !== label);
} else if (nextWhere === splittedModel.length - 2) {
return fillSuggestions(
Expand Down Expand Up @@ -267,9 +268,8 @@ export function createPPLSuggestionsPlugin(
): AutocompletePlugin<PPLSuggestion, undefined> {
return {
onStateChange: ({ state }) => {
if (state.query.length > queryLength) {
if (options.query.rawQuery !== state.query) {
options.handleQueryChange(state.query, currIndex);
queryLength++;
}
},
onSubmit: () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,20 @@
import React from 'react';
import {
EuiFlexItem,
EuiSwitch,
EuiSuperDatePicker,
EuiSuperDatePicker
} from '@elastic/eui';
import {
IFilterProps
IDatePickerProps
} from './search';

export function Filter(props: IFilterProps) {
export function DatePicker(props: IDatePickerProps) {

const {
startTime,
endTime,
setStartTime,
setEndTime,
setIsOutputStale
handleTimePickerChange
} = props;

function handleTimeChange({
Expand Down Expand Up @@ -69,8 +68,9 @@ export function Filter(props: IFilterProps) {
showUpdateButton={ false }
dateFormat="MM/DD/YYYY hh:mm:ss A"
onTimeChange={(e) => {
setStartTime(e.start);
setEndTime(e.end);
const start = e.start;
const end = e.start === e.end ? 'now' : e.end;
handleTimePickerChange([start, end]);
}}
onRefresh={ handleRefresh }
className="osdQueryBar__datePicker"
Expand Down
Loading