add traceid
This commit is contained in:
parent
f810a4e364
commit
453033ac43
1
main.go
1
main.go
|
@ -105,6 +105,7 @@ func main() {
|
|||
orm.RegisterSchemaWithIndexName(alerting.Alert{}, "alerting-alerts")
|
||||
orm.RegisterSchemaWithIndexName(alerting.AlertingHistory{}, "alerting-alert-history")
|
||||
orm.RegisterSchema(elastic.CommonCommand{})
|
||||
orm.RegisterSchemaWithIndexName(elastic.TraceMeta{}, "traces")
|
||||
alertSrv.GetScheduler().Start()
|
||||
},nil){
|
||||
app.Run()
|
||||
|
|
|
@ -128,63 +128,63 @@ export default [
|
|||
// },
|
||||
|
||||
// data
|
||||
{
|
||||
path: "/data",
|
||||
name: "data",
|
||||
icon: "database",
|
||||
routes: [
|
||||
// {
|
||||
// path: "/data",
|
||||
// name: "data",
|
||||
// icon: "database",
|
||||
// path: '/data/overview',
|
||||
// name: 'overview',
|
||||
// component: './DataManagement/IndexSummary',
|
||||
// routes:[
|
||||
// // {
|
||||
// // path: '/data/overview',
|
||||
// // name: 'overview',
|
||||
// // component: './DataManagement/IndexSummary',
|
||||
// // routes:[
|
||||
// // { path: '/', redirect: '/' },
|
||||
// // ],
|
||||
// // },
|
||||
// {
|
||||
// path: "/data/index",
|
||||
// name: "index",
|
||||
// component: "./DataManagement/Index",
|
||||
// routes: [{ path: "/", redirect: "/" }],
|
||||
// },
|
||||
// // {
|
||||
// // path: '/data/document',
|
||||
// // name: 'document',
|
||||
// // component: './DataManagement/Document',
|
||||
// // routes:[
|
||||
// // { path: '/', redirect: '/' },
|
||||
// // ],
|
||||
// // },
|
||||
// // {
|
||||
// // path: '/data/template',
|
||||
// // name: 'template',
|
||||
// // component: './DataManagement/IndexTemplate',
|
||||
// // routes:[
|
||||
// // { path: '/', redirect: '/' },
|
||||
// // ],
|
||||
// // },
|
||||
// // {
|
||||
// // path: '/data/lifecycle',
|
||||
// // name: 'lifecycle',
|
||||
// // component: './DataManagement/IndexLifeCycle',
|
||||
// // routes:[
|
||||
// // { path: '/', redirect: '/' },
|
||||
// // ],
|
||||
// // },
|
||||
// {
|
||||
// routes: [{ path: "/", redirect: "/" }],
|
||||
// path: "/data/discover",
|
||||
// name: "discover",
|
||||
// component: "./DataManagement/Discover",
|
||||
// },
|
||||
// {
|
||||
// routes: [{ path: "/", redirect: "/" }],
|
||||
// path: "/data/views/",
|
||||
// name: "indexPatterns",
|
||||
// component: "./DataManagement/IndexPatterns",
|
||||
// },
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
path: "/data/index",
|
||||
name: "index",
|
||||
component: "./DataManagement/Index",
|
||||
routes: [{ path: "/", redirect: "/" }],
|
||||
},
|
||||
// {
|
||||
// path: '/data/document',
|
||||
// name: 'document',
|
||||
// component: './DataManagement/Document',
|
||||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: '/data/template',
|
||||
// name: 'template',
|
||||
// component: './DataManagement/IndexTemplate',
|
||||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// path: '/data/lifecycle',
|
||||
// name: 'lifecycle',
|
||||
// component: './DataManagement/IndexLifeCycle',
|
||||
// routes:[
|
||||
// { path: '/', redirect: '/' },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
routes: [{ path: "/", redirect: "/" }],
|
||||
path: "/data/discover",
|
||||
name: "discover",
|
||||
component: "./DataManagement/Discover",
|
||||
},
|
||||
{
|
||||
routes: [{ path: "/", redirect: "/" }],
|
||||
path: "/data/views/",
|
||||
name: "indexPatterns",
|
||||
component: "./DataManagement/IndexPatterns",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
//search
|
||||
// {
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { EuiContextMenu, EuiPopover } from '@elastic/eui';
|
||||
import { InjectedIntl } from '@kbn/i18n/react';
|
||||
import classNames from 'classnames';
|
||||
import React, { MouseEvent, useState, useEffect } from 'react';
|
||||
import { IUiSettingsClient } from 'src/core/public';
|
||||
import { FilterEditor } from './filter_editor';
|
||||
import { FilterView } from './filter_view';
|
||||
import { IIndexPattern } from '../..';
|
||||
import { EuiContextMenu, EuiPopover } from "@elastic/eui";
|
||||
import { InjectedIntl } from "@kbn/i18n/react";
|
||||
import classNames from "classnames";
|
||||
import React, { MouseEvent, useState, useEffect } from "react";
|
||||
import { IUiSettingsClient } from "src/core/public";
|
||||
import { FilterEditor } from "./filter_editor";
|
||||
import { FilterView } from "./filter_view";
|
||||
import { IIndexPattern } from "../..";
|
||||
import {
|
||||
Filter,
|
||||
isFilterPinned,
|
||||
|
@ -33,8 +33,8 @@ import {
|
|||
toggleFilterPinned,
|
||||
toggleFilterDisabled,
|
||||
getIndexPatternFromFilter,
|
||||
} from '../../../common';
|
||||
import { getIndexPatterns } from '../../services';
|
||||
} from "../../../common";
|
||||
import { getIndexPatterns } from "../../services";
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
|
@ -53,9 +53,9 @@ interface LabelOptions {
|
|||
message?: string;
|
||||
}
|
||||
|
||||
const FILTER_ITEM_OK = '';
|
||||
const FILTER_ITEM_WARNING = 'warn';
|
||||
const FILTER_ITEM_ERROR = 'error';
|
||||
const FILTER_ITEM_OK = "";
|
||||
const FILTER_ITEM_WARNING = "warn";
|
||||
const FILTER_ITEM_ERROR = "error";
|
||||
|
||||
export type FilterLabelStatus =
|
||||
| typeof FILTER_ITEM_OK
|
||||
|
@ -64,7 +64,9 @@ export type FilterLabelStatus =
|
|||
|
||||
export function FilterItem(props: Props) {
|
||||
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false);
|
||||
const [indexPatternExists, setIndexPatternExists] = useState<boolean | undefined>(undefined);
|
||||
const [indexPatternExists, setIndexPatternExists] = useState<
|
||||
boolean | undefined
|
||||
>(undefined);
|
||||
const { id, filter, indexPatterns } = props;
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -123,26 +125,35 @@ export function FilterItem(props: Props) {
|
|||
|
||||
function getClasses(negate: boolean, labelConfig: LabelOptions) {
|
||||
return classNames(
|
||||
'globalFilterItem',
|
||||
"globalFilterItem",
|
||||
{
|
||||
'globalFilterItem-isDisabled': isDisabled(labelConfig),
|
||||
'globalFilterItem-isError': labelConfig.status === FILTER_ITEM_ERROR,
|
||||
'globalFilterItem-isWarning': labelConfig.status === FILTER_ITEM_WARNING,
|
||||
'globalFilterItem-isPinned': isFilterPinned(filter),
|
||||
'globalFilterItem-isExcluded': negate,
|
||||
"globalFilterItem-isDisabled": isDisabled(labelConfig),
|
||||
"globalFilterItem-isError": labelConfig.status === FILTER_ITEM_ERROR,
|
||||
"globalFilterItem-isWarning":
|
||||
labelConfig.status === FILTER_ITEM_WARNING,
|
||||
"globalFilterItem-isPinned": isFilterPinned(filter),
|
||||
"globalFilterItem-isExcluded": negate,
|
||||
},
|
||||
props.className
|
||||
);
|
||||
}
|
||||
|
||||
function getDataTestSubj(labelConfig: LabelOptions) {
|
||||
const dataTestSubjKey = filter.meta.key ? `filter-key-${filter.meta.key}` : '';
|
||||
const dataTestSubjKey = filter.meta.key
|
||||
? `filter-key-${filter.meta.key}`
|
||||
: "";
|
||||
const dataTestSubjValue = filter.meta.value
|
||||
? `filter-value-${isValidLabel(labelConfig) ? labelConfig.title : labelConfig.status}`
|
||||
: '';
|
||||
const dataTestSubjNegated = filter.meta.negate ? 'filter-negated' : '';
|
||||
const dataTestSubjDisabled = `filter-${isDisabled(labelConfig) ? 'disabled' : 'enabled'}`;
|
||||
const dataTestSubjPinned = `filter-${isFilterPinned(filter) ? 'pinned' : 'unpinned'}`;
|
||||
? `filter-value-${
|
||||
isValidLabel(labelConfig) ? labelConfig.title : labelConfig.status
|
||||
}`
|
||||
: "";
|
||||
const dataTestSubjNegated = filter.meta.negate ? "filter-negated" : "";
|
||||
const dataTestSubjDisabled = `filter-${
|
||||
isDisabled(labelConfig) ? "disabled" : "enabled"
|
||||
}`;
|
||||
const dataTestSubjPinned = `filter-${
|
||||
isFilterPinned(filter) ? "pinned" : "unpinned"
|
||||
}`;
|
||||
return `filter ${dataTestSubjDisabled} ${dataTestSubjKey} ${dataTestSubjValue} ${dataTestSubjPinned} ${dataTestSubjNegated}`;
|
||||
}
|
||||
|
||||
|
@ -153,52 +164,46 @@ export function FilterItem(props: Props) {
|
|||
id: 0,
|
||||
items: [
|
||||
{
|
||||
name: isFilterPinned(filter)
|
||||
? 'Unpin'
|
||||
: 'Pin across all apps',
|
||||
icon: 'pin',
|
||||
name: isFilterPinned(filter) ? "Unpin" : "Pin across all apps",
|
||||
icon: "pin",
|
||||
onClick: () => {
|
||||
setIsPopoverOpen(false);
|
||||
onTogglePinned();
|
||||
},
|
||||
'data-test-subj': 'pinFilter',
|
||||
"data-test-subj": "pinFilter",
|
||||
},
|
||||
{
|
||||
name: 'Edit filter',
|
||||
icon: 'pencil',
|
||||
name: "Edit filter",
|
||||
icon: "pencil",
|
||||
panel: 1,
|
||||
'data-test-subj': 'editFilter',
|
||||
"data-test-subj": "editFilter",
|
||||
},
|
||||
{
|
||||
name: negate
|
||||
? 'Include results'
|
||||
: 'Exclude results',
|
||||
icon: negate ? 'plusInCircle' : 'minusInCircle',
|
||||
name: negate ? "Include results" : "Exclude results",
|
||||
icon: negate ? "plusInCircle" : "minusInCircle",
|
||||
onClick: () => {
|
||||
setIsPopoverOpen(false);
|
||||
onToggleNegated();
|
||||
},
|
||||
'data-test-subj': 'negateFilter',
|
||||
"data-test-subj": "negateFilter",
|
||||
},
|
||||
{
|
||||
name: disabled
|
||||
? 'Re-enable'
|
||||
: 'Temporarily disable',
|
||||
icon: `${disabled ? 'eye' : 'eyeClosed'}`,
|
||||
name: disabled ? "Re-enable" : "Temporarily disable",
|
||||
icon: `${disabled ? "eye" : "eyeClosed"}`,
|
||||
onClick: () => {
|
||||
setIsPopoverOpen(false);
|
||||
onToggleDisabled();
|
||||
},
|
||||
'data-test-subj': 'disableFilter',
|
||||
"data-test-subj": "disableFilter",
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
icon: 'trash',
|
||||
name: "Delete",
|
||||
icon: "trash",
|
||||
onClick: () => {
|
||||
setIsPopoverOpen(false);
|
||||
props.onRemove();
|
||||
},
|
||||
'data-test-subj': 'deleteFilter',
|
||||
"data-test-subj": "deleteFilter",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -236,31 +241,23 @@ export function FilterItem(props: Props) {
|
|||
const allFields = indexPatterns.map((indexPattern) => {
|
||||
return indexPattern.fields.map((field) => field.name);
|
||||
});
|
||||
const flatFields = allFields.reduce((acc: string[], it: string[]) => [...acc, ...it], []);
|
||||
return flatFields.includes(filter.meta?.key || '');
|
||||
const flatFields = allFields.reduce(
|
||||
(acc: string[], it: string[]) => [...acc, ...it],
|
||||
[]
|
||||
);
|
||||
return flatFields.includes(filter.meta?.key || "");
|
||||
}
|
||||
|
||||
function getValueLabel(): LabelOptions {
|
||||
const label: LabelOptions = {
|
||||
title: '',
|
||||
message: '',
|
||||
title: "",
|
||||
message: "",
|
||||
status: FILTER_ITEM_OK,
|
||||
};
|
||||
if (indexPatternExists === false) {
|
||||
label.status = FILTER_ITEM_ERROR;
|
||||
label.title = props.intl.formatMessage({
|
||||
id: 'data.filter.filterBar.labelErrorText',
|
||||
defaultMessage: `Error`,
|
||||
});
|
||||
label.message = props.intl.formatMessage(
|
||||
{
|
||||
id: 'data.filter.filterBar.labelErrorInfo',
|
||||
defaultMessage: 'Index pattern {indexPattern} not found',
|
||||
},
|
||||
{
|
||||
indexPattern: filter.meta.index,
|
||||
}
|
||||
);
|
||||
label.title = "Error";
|
||||
label.message = "Index pattern not found";
|
||||
} else if (isFilterApplicable()) {
|
||||
try {
|
||||
label.title = getDisplayValueFromFilter(filter, indexPatterns);
|
||||
|
|
|
@ -17,29 +17,28 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { QueryStart, SavedQuery } from '../../query';
|
||||
import { SearchBar } from './';
|
||||
import { useFilterManager } from './lib/use_filter_manager';
|
||||
import { useTimefilter } from './lib/use_timefilter';
|
||||
import _ from "lodash";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { QueryStart, SavedQuery } from "../../query";
|
||||
import { SearchBar } from "./";
|
||||
import { useFilterManager } from "./lib/use_filter_manager";
|
||||
import { useTimefilter } from "./lib/use_timefilter";
|
||||
// import { useSavedQuery } from './lib/use_saved_query';
|
||||
import { Filter, Query, TimeRange } from '../../../common';
|
||||
import { useQueryStringManager } from './lib/use_query_string_manager';
|
||||
import { Filter, Query, TimeRange } from "../../../common";
|
||||
import { useQueryStringManager } from "./lib/use_query_string_manager";
|
||||
|
||||
// Respond to user changing the filters
|
||||
const defaultFiltersUpdated = (props) => {
|
||||
return (filters: Filter[]) => {
|
||||
props.filterManager.setFilters(filters);
|
||||
if (props.onQuerySubmit)
|
||||
props.onQuerySubmit();
|
||||
if (props.onQuerySubmit) props.onQuerySubmit();
|
||||
};
|
||||
};
|
||||
|
||||
// Respond to user changing the refresh settings
|
||||
const defaultOnRefreshChange = (props) => {
|
||||
// const { timefilter } = props.timefilter;
|
||||
const timefilter = props.timefilter
|
||||
const timefilter = props.timefilter;
|
||||
return (options: { isPaused: boolean; refreshInterval: number }) => {
|
||||
timefilter.setRefreshInterval({
|
||||
value: options.refreshInterval,
|
||||
|
@ -49,10 +48,7 @@ const defaultOnRefreshChange = (props) => {
|
|||
};
|
||||
|
||||
// Respond to user changing the query string or time settings
|
||||
const defaultOnQuerySubmit = (
|
||||
props,
|
||||
currentQuery
|
||||
) => {
|
||||
const defaultOnQuerySubmit = (props, currentQuery) => {
|
||||
if (!props.useDefaultBehaviors) return props.onQuerySubmit;
|
||||
|
||||
//const { timefilter } = props.timefilter;
|
||||
|
@ -69,8 +65,7 @@ const defaultOnQuerySubmit = (
|
|||
} else {
|
||||
props.queryString.clearQuery();
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Refresh button triggered for an update
|
||||
if (props.onQuerySubmit)
|
||||
props.onQuerySubmit(
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
EuiButtonEmpty,
|
||||
EuiPopover,
|
||||
|
@ -28,10 +28,9 @@ import {
|
|||
EuiTabbedContent,
|
||||
EuiTab,
|
||||
EuiSwitch,
|
||||
} from '@elastic/eui';
|
||||
import { EuiSelectableProps } from '@elastic/eui/src/components/selectable/selectable';
|
||||
import { IndexPatternRef } from './types';
|
||||
|
||||
} from "@elastic/eui";
|
||||
import { EuiSelectableProps } from "@elastic/eui/src/components/selectable/selectable";
|
||||
import { IndexPatternRef } from "./types";
|
||||
|
||||
export type ChangeIndexPatternTriggerProps = EuiButtonEmptyProps & {
|
||||
label: string;
|
||||
|
@ -72,21 +71,29 @@ export function ChangeIndexPattern({
|
|||
</EuiButtonEmpty>
|
||||
);
|
||||
};
|
||||
|
||||
const [selectedTabId, setSelectedTabId] = useState(indices.includes(indexPatternId) ? 1 :0);
|
||||
const indexNames = (indexPatternId || "").split(",");
|
||||
const [selectedTabId, setSelectedTabId] = useState(
|
||||
indexNames.every((index) => indices.includes(index)) ? 1 : 0
|
||||
);
|
||||
const singleSelection = React.useMemo(() => {
|
||||
return indexNames.length > 1 ? true : "always";
|
||||
}, [indexNames]);
|
||||
const onSelectedTabChanged = (id: number) => {
|
||||
setSelectedTabId(id);
|
||||
};
|
||||
const [includeSystemIndex, setIncludeSystemIndex] = useState(false);
|
||||
|
||||
const tabs = React.useMemo(() => {
|
||||
const showIndices = includeSystemIndex ? indices: indices.filter(key=>!key.startsWith("."));
|
||||
const showIndices = includeSystemIndex
|
||||
? indices
|
||||
: indices.filter((key) => !key.startsWith("."));
|
||||
const tabs = [
|
||||
{
|
||||
id: 'view',
|
||||
name: 'View',
|
||||
id: "view",
|
||||
name: "View",
|
||||
disabled: false,
|
||||
content: ( <EuiSelectable
|
||||
content: (
|
||||
<EuiSelectable
|
||||
style={{ marginTop: 10 }}
|
||||
data-test-subj="indexPattern-switcher"
|
||||
{...selectableProps}
|
||||
|
@ -96,13 +103,15 @@ export function ChangeIndexPattern({
|
|||
label: viewName,
|
||||
key: id,
|
||||
value: id,
|
||||
checked: id === indexPatternId ? 'on' : undefined,
|
||||
checked: id === indexPatternId ? "on" : undefined,
|
||||
}))}
|
||||
onChange={(choices) => {
|
||||
const choice = (choices.find(({ checked }) => checked) as unknown) as {
|
||||
const choice = (choices.find(
|
||||
({ checked }) => checked
|
||||
) as unknown) as {
|
||||
value: string;
|
||||
};
|
||||
onChangeIndexPattern(choice.value, 'view');
|
||||
onChangeIndexPattern(choice.value, "view");
|
||||
setPopoverIsOpen(false);
|
||||
}}
|
||||
searchProps={{
|
||||
|
@ -116,15 +125,22 @@ export function ChangeIndexPattern({
|
|||
{list}
|
||||
</>
|
||||
)}
|
||||
</EuiSelectable>),
|
||||
</EuiSelectable>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'index',
|
||||
name: 'Index',
|
||||
id: "index",
|
||||
name: "Index",
|
||||
disabled: false,
|
||||
content: (
|
||||
<div>
|
||||
<div style={{display:'flex', margin:'10px auto', flexDirection: 'row-reverse',}}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
margin: "10px auto",
|
||||
flexDirection: "row-reverse",
|
||||
}}
|
||||
>
|
||||
<EuiSwitch
|
||||
label="Include system index"
|
||||
checked={includeSystemIndex}
|
||||
|
@ -136,18 +152,25 @@ export function ChangeIndexPattern({
|
|||
style={{ marginTop: 5 }}
|
||||
{...selectableProps}
|
||||
searchable
|
||||
singleSelection="always"
|
||||
singleSelection={singleSelection}
|
||||
options={showIndices.map((indexName) => ({
|
||||
label: indexName,
|
||||
key: indexName,
|
||||
value: indexName,
|
||||
checked: indexName === indexPatternId ? 'on' : undefined,
|
||||
checked: indexNames.includes(indexName) ? "on" : undefined,
|
||||
}))}
|
||||
onChange={(choices) => {
|
||||
const choice = (choices.find(({ checked }) => checked) as unknown) as {
|
||||
value: string;
|
||||
};
|
||||
onChangeIndexPattern(choice.value, 'index');
|
||||
// const choice = (choices.find(
|
||||
// ({ checked }) => checked
|
||||
// ) as unknown) as {
|
||||
// value: string;
|
||||
// };
|
||||
const values = choices
|
||||
.filter(({ checked }) => checked)
|
||||
.map((choice) => {
|
||||
return choice.value;
|
||||
});
|
||||
onChangeIndexPattern(values.join(","), "index");
|
||||
setPopoverIsOpen(false);
|
||||
}}
|
||||
searchProps={{
|
||||
|
@ -161,11 +184,20 @@ export function ChangeIndexPattern({
|
|||
{list}
|
||||
</>
|
||||
)}
|
||||
</EuiSelectable></div>),
|
||||
</EuiSelectable>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
return tabs;
|
||||
},[selectableProps, indexPatternId, indexPatternRefs, indices, includeSystemIndex])
|
||||
}, [
|
||||
selectableProps,
|
||||
indexPatternId,
|
||||
indexPatternRefs,
|
||||
indices,
|
||||
includeSystemIndex,
|
||||
singleSelection,
|
||||
]);
|
||||
|
||||
const selectedTabContent = React.useMemo(() => {
|
||||
return tabs.find((obj) => obj.id === selectedTabId)?.content;
|
||||
|
@ -207,7 +239,7 @@ export function ChangeIndexPattern({
|
|||
initialSelectedTab={tabs[selectedTabId]}
|
||||
autoFocus="selected"
|
||||
onTabClick={(tab) => {
|
||||
const idx = tabs.findIndex(item=>item.id == tab.id);
|
||||
const idx = tabs.findIndex((item) => item.id == tab.id);
|
||||
setSelectedTabId(idx);
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { SavedObject } from 'kibana/public';
|
||||
import { IIndexPattern, IndexPatternAttributes } from 'src/plugins/data/public';
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { SavedObject } from "kibana/public";
|
||||
import { IIndexPattern, IndexPatternAttributes } from "src/plugins/data/public";
|
||||
|
||||
import { IndexPatternRef } from './types';
|
||||
import { ChangeIndexPattern } from './change_indexpattern';
|
||||
import { IndexPatternRef } from "./types";
|
||||
import { ChangeIndexPattern } from "./change_indexpattern";
|
||||
export interface DiscoverIndexPatternProps {
|
||||
/**
|
||||
* list of available index patterns, if length > 1, component offers a "change" link
|
||||
|
@ -56,7 +56,7 @@ export function DiscoverIndexPattern({
|
|||
|
||||
const [selected, setSelected] = useState({
|
||||
id: selectedId,
|
||||
title: selectedTitle || '',
|
||||
title: selectedTitle || "",
|
||||
});
|
||||
useEffect(() => {
|
||||
const { id, title, viewName } = selectedIndexPattern;
|
||||
|
@ -72,23 +72,23 @@ export function DiscoverIndexPattern({
|
|||
trigger={{
|
||||
label: selected.viewName,
|
||||
title: selected.title,
|
||||
'data-test-subj': 'indexPattern-switch-link',
|
||||
className: 'dscIndexPattern__triggerButton',
|
||||
"data-test-subj": "indexPattern-switch-link",
|
||||
className: "dscIndexPattern__triggerButton",
|
||||
}}
|
||||
indexPatternId={selected.id}
|
||||
indexPatternRefs={options}
|
||||
onChangeIndexPattern={(id, typ) => {
|
||||
let indexPattern = null;
|
||||
if(typ == 'index'){
|
||||
indices.forEach((indexName)=>{
|
||||
if(indexName == id){
|
||||
if (typ == "index") {
|
||||
// indices.forEach((indexName)=>{
|
||||
// if(indexName == id){
|
||||
indexPattern = {
|
||||
id: indexName,
|
||||
title: indexName,
|
||||
viewName: indexName,
|
||||
}
|
||||
}
|
||||
})
|
||||
id: id,
|
||||
title: id,
|
||||
viewName: id,
|
||||
};
|
||||
// }
|
||||
// })
|
||||
} else {
|
||||
indexPattern = options.find((pattern) => pattern.id === id);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,17 @@ import * as styles from "./discover.scss";
|
|||
import { Subscription } from "rxjs";
|
||||
import { connect } from "dva";
|
||||
|
||||
import { Card, Spin, message, Select, Icon, Popover } from "antd";
|
||||
import {
|
||||
Card,
|
||||
Spin,
|
||||
message,
|
||||
Select,
|
||||
Icon,
|
||||
Popover,
|
||||
Tabs,
|
||||
Input,
|
||||
Button,
|
||||
} from "antd";
|
||||
// import DiscoverGrid from './Components/discover_grid';
|
||||
import { flattenHitWrapper } from "../../components/kibana/data/common/index_patterns/index_patterns";
|
||||
import { getStateColumnActions } from "../../components/kibana/discover/public/application/angular/doc_table/actions/columns";
|
||||
|
@ -85,7 +95,9 @@ const Discover = (props) => {
|
|||
const [state, setState] = useState({
|
||||
columns: columnsParam || ["_source"], //['name', 'address'],
|
||||
interval: "auto",
|
||||
activeTabKey: "normal",
|
||||
});
|
||||
const [searchType, setSearchType] = React.useState("normal");
|
||||
|
||||
// const [sort, setSort] = useState(null);
|
||||
|
||||
|
@ -100,7 +112,7 @@ const Discover = (props) => {
|
|||
);
|
||||
return subscriptions;
|
||||
}, [props.indexPattern]);
|
||||
const setIndexPattern = async (id, typ) => {
|
||||
const setIndexPattern = async (id, typ, filters, isReset = false) => {
|
||||
const IP = await services.indexPatternService.get(
|
||||
id,
|
||||
typ,
|
||||
|
@ -113,6 +125,14 @@ const Discover = (props) => {
|
|||
columns: ["_source"],
|
||||
sort: [],
|
||||
});
|
||||
if (filters && filters.length > 0) {
|
||||
if (isReset) {
|
||||
filterManager.setFilters(filters);
|
||||
} else {
|
||||
filterManager.addFilters(filters);
|
||||
}
|
||||
}
|
||||
updateQuery();
|
||||
};
|
||||
const onTimeFieldChange = async (id, timeField) => {
|
||||
const IP = await services.indexPatternService.get(
|
||||
|
@ -130,6 +150,8 @@ const Discover = (props) => {
|
|||
const indexPatterns = [indexPattern];
|
||||
const indexPatternList = props.indexPatternList;
|
||||
const contentCentered = false; //resultState != 'ready';
|
||||
const indexPatternRef = React.useRef();
|
||||
indexPatternRef.current = indexPattern;
|
||||
|
||||
indexPatterns.get = (id) => {
|
||||
return Promise.resolve(indexPatterns.find((ip) => ip.id == id));
|
||||
|
@ -143,12 +165,12 @@ const Discover = (props) => {
|
|||
|
||||
const updateQuery = useCallback(
|
||||
async (_payload) => {
|
||||
if (!indexPattern) {
|
||||
if (!indexPatternRef.current) {
|
||||
return;
|
||||
}
|
||||
setResultState("loading");
|
||||
const params = getSearchParams(
|
||||
_payload?.indexPattern || indexPattern,
|
||||
_payload?.indexPattern || indexPatternRef.current,
|
||||
_payload?.interval || state.interval,
|
||||
_payload?.sort
|
||||
);
|
||||
|
@ -171,7 +193,7 @@ const Discover = (props) => {
|
|||
// console.log(getEsQuery(indexPattern));
|
||||
// console.log(timefilter.createFilter(indexPattern));
|
||||
},
|
||||
[indexPattern, state.interval]
|
||||
[state.interval]
|
||||
);
|
||||
|
||||
const onChangeInterval = useCallback(
|
||||
|
@ -406,9 +428,43 @@ const Discover = (props) => {
|
|||
}, [saveDocument, deleteDocument]);
|
||||
|
||||
const [settingsVisible, setSettingsVisible] = React.useState(false);
|
||||
const onTraceIDSearch = React.useCallback(
|
||||
async (value) => {
|
||||
const { http } = getContext();
|
||||
const indexNames = await http
|
||||
.fetch(http.getServerBasePath() + "/search/trace_id", {
|
||||
query: {
|
||||
traceID: value,
|
||||
},
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
if (indexNames && indexNames.length > 0) {
|
||||
const newFilters = generateFilters(
|
||||
filterManager,
|
||||
"trace_id",
|
||||
value,
|
||||
"+",
|
||||
indexNames.join(",")
|
||||
);
|
||||
setIndexPattern(indexNames.join(","), "index", newFilters, true);
|
||||
setSearchType("normal");
|
||||
}
|
||||
},
|
||||
[setIndexPattern]
|
||||
);
|
||||
|
||||
return (
|
||||
<Card bordered={false} bodyStyle={{ paddingTop: 10 }}>
|
||||
<Tabs
|
||||
animated={false}
|
||||
tabPosition="right"
|
||||
activeKey={searchType}
|
||||
onChange={setSearchType}
|
||||
type="card"
|
||||
>
|
||||
<Tabs.TabPane key="normal" tab="Normal">
|
||||
<SearchBar
|
||||
{...{
|
||||
showSearchBar: false,
|
||||
|
@ -434,6 +490,20 @@ const Discover = (props) => {
|
|||
services,
|
||||
}}
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane key="traceid" tab="TraceID">
|
||||
<Input.Search
|
||||
placeholder="Input trace ID"
|
||||
enterButton={
|
||||
<Button icon="search" type="primary">
|
||||
搜索
|
||||
</Button>
|
||||
}
|
||||
size="large"
|
||||
onSearch={onTraceIDSearch}
|
||||
/>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
|
||||
<EuiPageBody className="dscPageBody" aria-describedby="savedSearchTitle">
|
||||
<EuiFlexGroup className="dscPageBody__contents" gutterSize="none">
|
||||
|
@ -658,6 +728,9 @@ const Discover = (props) => {
|
|||
};
|
||||
|
||||
const DiscoverUI = (props) => {
|
||||
if (!props.selectedCluster.id) {
|
||||
return null;
|
||||
}
|
||||
const [viewID, setViewID] = useQueryParam("viewID", StringParam);
|
||||
const [index, setIndex] = useQueryParam("index", StringParam);
|
||||
// const [type, setType] = useQueryParam('type', StringParam);
|
||||
|
|
|
@ -1,47 +1,53 @@
|
|||
import {AutocompleteService} from '../../components/kibana/data/public/autocomplete';
|
||||
import {FilterManager} from '../../components/kibana/data/public/query/filter_manager/filter_manager';
|
||||
import {QueryStringManager} from '../../components/kibana/data/public/query/query_string/query_string_manager';
|
||||
import {Timefilter, TimeHistory} from '../../components/kibana/data/public/query/timefilter';
|
||||
import { useState, useEffect, createContext } from 'react';
|
||||
import { Subscription } from 'rxjs';
|
||||
import {buildEsQuery} from '../../components/kibana/data/common/es_query/es_query/build_es_query';
|
||||
import {getCalculateAutoTimeExpression} from '../../components/kibana/data/common/search/aggs/utils/calculate_auto_time_expression';
|
||||
import {intervalOptions} from '../../components/kibana/data/common/search/aggs/buckets/_interval_options';
|
||||
import {TimeBuckets} from '../../components/kibana/data/common/search/aggs/buckets/lib/time_buckets/time_buckets';
|
||||
import moment from 'moment';
|
||||
import { AutocompleteService } from "../../components/kibana/data/public/autocomplete";
|
||||
import { FilterManager } from "../../components/kibana/data/public/query/filter_manager/filter_manager";
|
||||
import { QueryStringManager } from "../../components/kibana/data/public/query/query_string/query_string_manager";
|
||||
import {
|
||||
Timefilter,
|
||||
TimeHistory,
|
||||
} from "../../components/kibana/data/public/query/timefilter";
|
||||
import { useState, useEffect, createContext } from "react";
|
||||
import { Subscription } from "rxjs";
|
||||
import { buildEsQuery } from "../../components/kibana/data/common/es_query/es_query/build_es_query";
|
||||
import { getCalculateAutoTimeExpression } from "../../components/kibana/data/common/search/aggs/utils/calculate_auto_time_expression";
|
||||
import { intervalOptions } from "../../components/kibana/data/common/search/aggs/buckets/_interval_options";
|
||||
import { TimeBuckets } from "../../components/kibana/data/common/search/aggs/buckets/lib/time_buckets/time_buckets";
|
||||
import moment from "moment";
|
||||
// import { fetch } from 'umi-request';
|
||||
import {Fetch} from '../../components/kibana/core/public/http/fetch';
|
||||
import {SavedObjectsClient} from '../../components/kibana/core/public/saved_objects/saved_objects_client';
|
||||
import {getIndexPatterns, setIndexPatterns} from '../../components/kibana/data/public/services';
|
||||
import { Fetch } from "../../components/kibana/core/public/http/fetch";
|
||||
import { SavedObjectsClient } from "../../components/kibana/core/public/saved_objects/saved_objects_client";
|
||||
import {
|
||||
getIndexPatterns,
|
||||
setIndexPatterns,
|
||||
} from "../../components/kibana/data/public/services";
|
||||
import {
|
||||
IndexPatternsService,
|
||||
onRedirectNoIndexPattern,
|
||||
onUnsupportedTimePattern,
|
||||
IndexPatternsApiClient,
|
||||
SavedObjectsClientPublicToCommon
|
||||
} from '../../components/kibana/data/public/index_patterns';
|
||||
import {FieldFormatsRegistry,} from '../../components/kibana/data/common/field_formats';
|
||||
import {baseFormattersPublic} from '../../components/kibana/data/public/field_formats';
|
||||
import { deserializeFieldFormat } from '../../components/kibana/data/public/field_formats/utils/deserialize';
|
||||
import {ESPrefix} from '@/services/common'
|
||||
SavedObjectsClientPublicToCommon,
|
||||
} from "../../components/kibana/data/public/index_patterns";
|
||||
import { FieldFormatsRegistry } from "../../components/kibana/data/common/field_formats";
|
||||
import { baseFormattersPublic } from "../../components/kibana/data/public/field_formats";
|
||||
import { deserializeFieldFormat } from "../../components/kibana/data/public/field_formats/utils/deserialize";
|
||||
import { ESPrefix } from "@/services/common";
|
||||
|
||||
const timeBucketConfig = {
|
||||
'histogram:maxBars': 100,
|
||||
'histogram:barTarget': 50,
|
||||
dateFormat: 'YYYY-MM-DD',
|
||||
'dateFormat:scaled': [
|
||||
['', 'HH:mm:ss.SSS'],
|
||||
['PT1S', 'HH:mm:ss'],
|
||||
['PT1M', 'HH:mm'],
|
||||
['PT1H', 'YYYY-MM-DD HH:mm'],
|
||||
['P1DT', 'YYYY-MM-DD'],
|
||||
['P1YT', 'YYYY'],
|
||||
"histogram:maxBars": 100,
|
||||
"histogram:barTarget": 50,
|
||||
dateFormat: "YYYY-MM-DD",
|
||||
"dateFormat:scaled": [
|
||||
["", "HH:mm:ss.SSS"],
|
||||
["PT1S", "HH:mm:ss"],
|
||||
["PT1M", "HH:mm"],
|
||||
["PT1H", "YYYY-MM-DD HH:mm"],
|
||||
["P1DT", "YYYY-MM-DD"],
|
||||
["P1YT", "YYYY"],
|
||||
],
|
||||
};
|
||||
|
||||
const basePath = {
|
||||
get: () => {
|
||||
return '';
|
||||
return "";
|
||||
},
|
||||
prepend: (path) => {
|
||||
return path;
|
||||
|
@ -49,8 +55,8 @@ const basePath = {
|
|||
remove: (url) => {
|
||||
return url;
|
||||
},
|
||||
serverBasePath: '/api/',
|
||||
}
|
||||
serverBasePath: "/api/",
|
||||
};
|
||||
const http = new Fetch({
|
||||
basePath,
|
||||
});
|
||||
|
@ -58,22 +64,22 @@ const savedObjects = new SavedObjectsClient(http);
|
|||
const savedObjectsClient = new SavedObjectsClientPublicToCommon(savedObjects);
|
||||
const getFieldFormatsConfig = (key) => {
|
||||
return {
|
||||
['format:defaultTypeMap']: {
|
||||
"ip": { "id": "ip", "params": {} },
|
||||
"date": { "id": "date", "params": {} },
|
||||
"date_nanos": { "id": "date_nanos", "params": {}, "es": true },
|
||||
"number": { "id": "number", "params": {} },
|
||||
"boolean": { "id": "boolean", "params": {} },
|
||||
"histogram": { "id": "histogram", "params": {} },
|
||||
"_source": { "id": "_source", "params": {} },
|
||||
"_default_": { "id": "string", "params": {} }
|
||||
["format:defaultTypeMap"]: {
|
||||
ip: { id: "ip", params: {} },
|
||||
date: { id: "date", params: {} },
|
||||
date_nanos: { id: "date_nanos", params: {}, es: true },
|
||||
number: { id: "number", params: {} },
|
||||
boolean: { id: "boolean", params: {} },
|
||||
histogram: { id: "histogram", params: {} },
|
||||
_source: { id: "_source", params: {} },
|
||||
_default_: { id: "string", params: {} },
|
||||
},
|
||||
'format:number:defaultPattern': '0,0.[000]',
|
||||
'format:percent:defaultPattern': '0,0.[000]%',
|
||||
'format:bytes:defaultPattern': '0,0.[0]b',
|
||||
'format:currency:defaultPattern': '($0,0.[00])',
|
||||
"format:number:defaultPattern": "0,0.[000]",
|
||||
"format:percent:defaultPattern": "0,0.[000]%",
|
||||
"format:bytes:defaultPattern": "0,0.[0]b",
|
||||
"format:currency:defaultPattern": "($0,0.[00])",
|
||||
}[key];
|
||||
}
|
||||
};
|
||||
|
||||
const fieldFormats = new FieldFormatsRegistry();
|
||||
fieldFormats.init(
|
||||
|
@ -87,25 +93,23 @@ fieldFormats.init(
|
|||
},
|
||||
baseFormattersPublic
|
||||
);
|
||||
fieldFormats.deserialize = deserializeFieldFormat.bind(
|
||||
fieldFormats
|
||||
);
|
||||
fieldFormats.deserialize = deserializeFieldFormat.bind(fieldFormats);
|
||||
|
||||
const indexPatternsApiClient = new IndexPatternsApiClient(http);
|
||||
const uiconfigs = {
|
||||
['metaFields']: ['_source', '_id', '_type', '_index'],//'_score'
|
||||
defaultIndex: '',
|
||||
["metaFields"]: ["_source", "_id", "_type", "_index"], //'_score'
|
||||
defaultIndex: "",
|
||||
};
|
||||
const uiSettings = {
|
||||
get: (key) => {
|
||||
return uiconfigs[key]
|
||||
return uiconfigs[key];
|
||||
},
|
||||
set: (key, val) => {
|
||||
return uiconfigs[key] = val;
|
||||
return (uiconfigs[key] = val);
|
||||
},
|
||||
getAll: () => {
|
||||
return uiconfigs;
|
||||
}
|
||||
},
|
||||
};
|
||||
const indexPatternService = new IndexPatternsService({
|
||||
uiSettings,
|
||||
|
@ -118,7 +122,6 @@ const indexPatternService = new IndexPatternsService({
|
|||
onRedirectNoIndexPattern,
|
||||
});
|
||||
|
||||
|
||||
export class Storage {
|
||||
store;
|
||||
|
||||
|
@ -160,33 +163,35 @@ export class Storage {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
const filterManager = new FilterManager();
|
||||
const storage = new Storage(localStorage);
|
||||
const queryStringManager = new QueryStringManager(storage);
|
||||
const timefilterConfig = {
|
||||
timeDefaults: { from: 'now-15m', to: 'now' },
|
||||
timeDefaults: { from: "now-15m", to: "now" },
|
||||
refreshIntervalDefaults: { pause: true, value: 10000 },
|
||||
};
|
||||
const timeHistory = new TimeHistory(storage);
|
||||
const timefilter = new Timefilter(timefilterConfig, timeHistory);
|
||||
|
||||
const autocomplete = new AutocompleteService();
|
||||
autocomplete.setup({autocomplete: autocomplete, http:http}, {
|
||||
autocomplete.setup(
|
||||
{ autocomplete: autocomplete, http: http },
|
||||
{
|
||||
timefilter,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const getConfig = (key) => {
|
||||
const kvals = {
|
||||
"histogram:maxBars": 100,
|
||||
"histogram:barTarget": 50,
|
||||
dateFormat: 'strict_date_optional_time',//'YYYY-MM-DD HH:mm:ss',
|
||||
'dateFormat:scaled': true,
|
||||
dateFormat: "strict_date_optional_time", //'YYYY-MM-DD HH:mm:ss',
|
||||
"dateFormat:scaled": true,
|
||||
};
|
||||
return kvals[key] || '';
|
||||
return kvals[key] || "";
|
||||
};
|
||||
|
||||
const calculateAutoTimeExpression = getCalculateAutoTimeExpression(getConfig)
|
||||
const calculateAutoTimeExpression = getCalculateAutoTimeExpression(getConfig);
|
||||
// console.log(calculateAutoTimeExpression({
|
||||
// from: timefilter.getTime().from,
|
||||
// to: timefilter.getTime().to,
|
||||
|
@ -203,8 +208,7 @@ const getTimeBuckets = (interval) => {
|
|||
timeBuckets.setBounds(bounds);
|
||||
timeBuckets.setInterval(interval);
|
||||
return timeBuckets; //.getInterval(true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const defaultFiltersUpdated = () => {
|
||||
return (filters) => {
|
||||
|
@ -244,46 +248,51 @@ export const getContext = ()=>{
|
|||
indexPatternService,
|
||||
},
|
||||
http,
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
const getEsQuery = (indexPattern) => {
|
||||
const timeFilter = timefilter.createFilter(indexPattern);
|
||||
return buildEsQuery(
|
||||
indexPattern,
|
||||
queryStringManager.getQuery(),
|
||||
[...filterManager.getFilters(), ...(timeFilter ? [timeFilter] : [])],
|
||||
[...filterManager.getFilters(), ...(timeFilter ? [timeFilter] : [])]
|
||||
// getEsQueryConfig(getUiSettings())
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getSearchParams = (indexPattern, internal, sort) => {
|
||||
// const timeExp = calculateAutoTimeExpression(timefilter.getTime());
|
||||
const timeExp = getTimeBuckets(internal).getInterval(true).expression;
|
||||
// console.log(timeExp, internal)
|
||||
let esSort = indexPattern.timeFieldName ? [{[indexPattern.timeFieldName]: {order: "desc"}}]: [];
|
||||
let esSort = indexPattern.timeFieldName
|
||||
? [{ [indexPattern.timeFieldName]: { order: "desc" } }]
|
||||
: [];
|
||||
if (sort) {
|
||||
esSort = sort.reduce((sorts, s) => {
|
||||
const [sortField, sortDeriction] = s;
|
||||
sorts.push({
|
||||
[sortField]: {order: sortDeriction}
|
||||
})
|
||||
[sortField]: { order: sortDeriction },
|
||||
});
|
||||
return sorts;
|
||||
}, [])
|
||||
}, []);
|
||||
}
|
||||
const isCalendarInterval = timeExp.includes('w') || timeExp.includes('d') || timeExp.includes('y') || timeExp.includes('M');
|
||||
const isCalendarInterval =
|
||||
timeExp.includes("w") ||
|
||||
timeExp.includes("d") ||
|
||||
timeExp.includes("y") ||
|
||||
timeExp.includes("M");
|
||||
|
||||
let aggs = {
|
||||
2: {
|
||||
date_histogram: {
|
||||
//calendar_interval:
|
||||
[isCalendarInterval? 'calendar_interval' : 'fixed_interval']: timeExp,
|
||||
[isCalendarInterval ? "calendar_interval" : "fixed_interval"]: timeExp,
|
||||
field: indexPattern.timeFieldName,
|
||||
min_doc_count: 1,
|
||||
time_zone: "Asia/Shanghai"
|
||||
}
|
||||
}
|
||||
time_zone: "Asia/Shanghai",
|
||||
},
|
||||
},
|
||||
};
|
||||
let esRequest = {
|
||||
index: indexPattern.index || indexPattern.title,
|
||||
|
@ -293,27 +302,29 @@ const getSearchParams = (indexPattern, internal, sort) =>{
|
|||
|
||||
highlight: {
|
||||
pre_tags: ["@highlighted-field@"],
|
||||
post_tags:["@highlighted-field@"]
|
||||
post_tags: ["@highlighted-field@"],
|
||||
},
|
||||
sort: esSort, //
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
if (indexPattern.timeFieldName) {
|
||||
esRequest.body['aggs']=aggs;
|
||||
esRequest.body["aggs"] = aggs;
|
||||
}
|
||||
return esRequest;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchESRequest = (params, clusterID) => {
|
||||
return fetch(`${ESPrefix}/${clusterID}/search/ese`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
body: JSON.stringify(params),
|
||||
}).then( res => {
|
||||
return res.json()
|
||||
}).then(resJson=>{
|
||||
return resJson;
|
||||
})
|
||||
}
|
||||
.then((res) => {
|
||||
return res.json();
|
||||
})
|
||||
.then((resJson) => {
|
||||
return resJson;
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue