[Logs / Metrics UI] Separate logs / metrics source configuration awareness (#95334)
* Remove metrics awareness of logs fields
This commit is contained in:
parent
43e3d558fd
commit
6b6404954e
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { LogSourceConfigurationProperties } from '../http_api/log_sources';
|
||||
|
||||
// NOTE: Type will change, see below.
|
||||
type ResolvedLogsSourceConfiguration = LogSourceConfigurationProperties;
|
||||
|
||||
// NOTE: This will handle real resolution for https://github.com/elastic/kibana/issues/92650, via the index patterns service, but for now just
|
||||
// hands back properties from the saved object (and therefore looks pointless...).
|
||||
export const resolveLogSourceConfiguration = (
|
||||
sourceConfiguration: LogSourceConfigurationProperties
|
||||
): ResolvedLogsSourceConfiguration => {
|
||||
return sourceConfiguration;
|
||||
};
|
81
x-pack/plugins/infra/common/metrics_sources/index.ts
Normal file
81
x-pack/plugins/infra/common/metrics_sources/index.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import * as rt from 'io-ts';
|
||||
import { omit } from 'lodash';
|
||||
import {
|
||||
SourceConfigurationRT,
|
||||
SourceStatusRuntimeType,
|
||||
} from '../source_configuration/source_configuration';
|
||||
import { DeepPartial } from '../utility_types';
|
||||
|
||||
/**
|
||||
* Properties specific to the Metrics Source Configuration.
|
||||
*/
|
||||
export const metricsSourceConfigurationPropertiesRT = rt.strict({
|
||||
name: SourceConfigurationRT.props.name,
|
||||
description: SourceConfigurationRT.props.description,
|
||||
metricAlias: SourceConfigurationRT.props.metricAlias,
|
||||
inventoryDefaultView: SourceConfigurationRT.props.inventoryDefaultView,
|
||||
metricsExplorerDefaultView: SourceConfigurationRT.props.metricsExplorerDefaultView,
|
||||
fields: rt.strict(omit(SourceConfigurationRT.props.fields.props, 'message')),
|
||||
anomalyThreshold: rt.number,
|
||||
});
|
||||
|
||||
export type MetricsSourceConfigurationProperties = rt.TypeOf<
|
||||
typeof metricsSourceConfigurationPropertiesRT
|
||||
>;
|
||||
|
||||
export const partialMetricsSourceConfigurationPropertiesRT = rt.partial({
|
||||
...metricsSourceConfigurationPropertiesRT.type.props,
|
||||
fields: rt.partial({
|
||||
...metricsSourceConfigurationPropertiesRT.type.props.fields.type.props,
|
||||
}),
|
||||
});
|
||||
|
||||
export type PartialMetricsSourceConfigurationProperties = rt.TypeOf<
|
||||
typeof partialMetricsSourceConfigurationPropertiesRT
|
||||
>;
|
||||
|
||||
const metricsSourceConfigurationOriginRT = rt.keyof({
|
||||
fallback: null,
|
||||
internal: null,
|
||||
stored: null,
|
||||
});
|
||||
|
||||
export const metricsSourceStatusRT = rt.strict({
|
||||
metricIndicesExist: SourceStatusRuntimeType.props.metricIndicesExist,
|
||||
indexFields: SourceStatusRuntimeType.props.indexFields,
|
||||
});
|
||||
|
||||
export type MetricsSourceStatus = rt.TypeOf<typeof metricsSourceStatusRT>;
|
||||
|
||||
export const metricsSourceConfigurationRT = rt.exact(
|
||||
rt.intersection([
|
||||
rt.type({
|
||||
id: rt.string,
|
||||
origin: metricsSourceConfigurationOriginRT,
|
||||
configuration: metricsSourceConfigurationPropertiesRT,
|
||||
}),
|
||||
rt.partial({
|
||||
updatedAt: rt.number,
|
||||
version: rt.string,
|
||||
status: metricsSourceStatusRT,
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
export type MetricsSourceConfiguration = rt.TypeOf<typeof metricsSourceConfigurationRT>;
|
||||
export type PartialMetricsSourceConfiguration = DeepPartial<MetricsSourceConfiguration>;
|
||||
|
||||
export const metricsSourceConfigurationResponseRT = rt.type({
|
||||
source: metricsSourceConfigurationRT,
|
||||
});
|
||||
|
||||
export type MetricsSourceConfigurationResponse = rt.TypeOf<
|
||||
typeof metricsSourceConfigurationResponseRT
|
||||
>;
|
|
@ -5,8 +5,19 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
/**
|
||||
* These are the core source configuration types that represent a Source Configuration in
|
||||
* it's entirety. There are then subsets of this configuration that form the Logs Source Configuration
|
||||
* and Metrics Source Configuration. The Logs Source Configuration is further expanded to it's resolved form.
|
||||
* -> Source Configuration
|
||||
* -> Logs source configuration
|
||||
* -> Resolved Logs Source Configuration
|
||||
* -> Metrics Source Configuration
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-empty-interface */
|
||||
|
||||
import { omit } from 'lodash';
|
||||
import * as rt from 'io-ts';
|
||||
import moment from 'moment';
|
||||
import { pipe } from 'fp-ts/lib/pipeable';
|
||||
|
@ -29,121 +40,113 @@ export const TimestampFromString = new rt.Type<number, string>(
|
|||
);
|
||||
|
||||
/**
|
||||
* Stored source configuration as read from and written to saved objects
|
||||
* Log columns
|
||||
*/
|
||||
|
||||
const SavedSourceConfigurationFieldsRuntimeType = rt.partial({
|
||||
container: rt.string,
|
||||
host: rt.string,
|
||||
pod: rt.string,
|
||||
tiebreaker: rt.string,
|
||||
timestamp: rt.string,
|
||||
});
|
||||
|
||||
export type InfraSavedSourceConfigurationFields = rt.TypeOf<
|
||||
typeof SavedSourceConfigurationFieldColumnRuntimeType
|
||||
>;
|
||||
|
||||
export const SavedSourceConfigurationTimestampColumnRuntimeType = rt.type({
|
||||
export const SourceConfigurationTimestampColumnRuntimeType = rt.type({
|
||||
timestampColumn: rt.type({
|
||||
id: rt.string,
|
||||
}),
|
||||
});
|
||||
|
||||
export type InfraSourceConfigurationTimestampColumn = rt.TypeOf<
|
||||
typeof SavedSourceConfigurationTimestampColumnRuntimeType
|
||||
typeof SourceConfigurationTimestampColumnRuntimeType
|
||||
>;
|
||||
|
||||
export const SavedSourceConfigurationMessageColumnRuntimeType = rt.type({
|
||||
export const SourceConfigurationMessageColumnRuntimeType = rt.type({
|
||||
messageColumn: rt.type({
|
||||
id: rt.string,
|
||||
}),
|
||||
});
|
||||
|
||||
export type InfraSourceConfigurationMessageColumn = rt.TypeOf<
|
||||
typeof SavedSourceConfigurationMessageColumnRuntimeType
|
||||
typeof SourceConfigurationMessageColumnRuntimeType
|
||||
>;
|
||||
|
||||
export const SavedSourceConfigurationFieldColumnRuntimeType = rt.type({
|
||||
export const SourceConfigurationFieldColumnRuntimeType = rt.type({
|
||||
fieldColumn: rt.type({
|
||||
id: rt.string,
|
||||
field: rt.string,
|
||||
}),
|
||||
});
|
||||
|
||||
export const SavedSourceConfigurationColumnRuntimeType = rt.union([
|
||||
SavedSourceConfigurationTimestampColumnRuntimeType,
|
||||
SavedSourceConfigurationMessageColumnRuntimeType,
|
||||
SavedSourceConfigurationFieldColumnRuntimeType,
|
||||
]);
|
||||
|
||||
export type InfraSavedSourceConfigurationColumn = rt.TypeOf<
|
||||
typeof SavedSourceConfigurationColumnRuntimeType
|
||||
export type InfraSourceConfigurationFieldColumn = rt.TypeOf<
|
||||
typeof SourceConfigurationFieldColumnRuntimeType
|
||||
>;
|
||||
|
||||
export const SavedSourceConfigurationRuntimeType = rt.partial({
|
||||
export const SourceConfigurationColumnRuntimeType = rt.union([
|
||||
SourceConfigurationTimestampColumnRuntimeType,
|
||||
SourceConfigurationMessageColumnRuntimeType,
|
||||
SourceConfigurationFieldColumnRuntimeType,
|
||||
]);
|
||||
|
||||
export type InfraSourceConfigurationColumn = rt.TypeOf<typeof SourceConfigurationColumnRuntimeType>;
|
||||
|
||||
/**
|
||||
* Fields
|
||||
*/
|
||||
|
||||
const SourceConfigurationFieldsRT = rt.type({
|
||||
container: rt.string,
|
||||
host: rt.string,
|
||||
pod: rt.string,
|
||||
tiebreaker: rt.string,
|
||||
timestamp: rt.string,
|
||||
message: rt.array(rt.string),
|
||||
});
|
||||
|
||||
/**
|
||||
* Properties that represent a full source configuration, which is the result of merging static values with
|
||||
* saved values.
|
||||
*/
|
||||
export const SourceConfigurationRT = rt.type({
|
||||
name: rt.string,
|
||||
description: rt.string,
|
||||
metricAlias: rt.string,
|
||||
logAlias: rt.string,
|
||||
inventoryDefaultView: rt.string,
|
||||
metricsExplorerDefaultView: rt.string,
|
||||
fields: SavedSourceConfigurationFieldsRuntimeType,
|
||||
logColumns: rt.array(SavedSourceConfigurationColumnRuntimeType),
|
||||
fields: SourceConfigurationFieldsRT,
|
||||
logColumns: rt.array(SourceConfigurationColumnRuntimeType),
|
||||
anomalyThreshold: rt.number,
|
||||
});
|
||||
|
||||
/**
|
||||
* Stored source configuration as read from and written to saved objects
|
||||
*/
|
||||
const SavedSourceConfigurationFieldsRuntimeType = rt.partial(
|
||||
omit(SourceConfigurationFieldsRT.props, ['message'])
|
||||
);
|
||||
|
||||
export type InfraSavedSourceConfigurationFields = rt.TypeOf<
|
||||
typeof SavedSourceConfigurationFieldsRuntimeType
|
||||
>;
|
||||
|
||||
export const SavedSourceConfigurationRuntimeType = rt.intersection([
|
||||
rt.partial(omit(SourceConfigurationRT.props, ['fields'])),
|
||||
rt.partial({
|
||||
fields: SavedSourceConfigurationFieldsRuntimeType,
|
||||
}),
|
||||
]);
|
||||
|
||||
export interface InfraSavedSourceConfiguration
|
||||
extends rt.TypeOf<typeof SavedSourceConfigurationRuntimeType> {}
|
||||
|
||||
export const pickSavedSourceConfiguration = (
|
||||
value: InfraSourceConfiguration
|
||||
): InfraSavedSourceConfiguration => {
|
||||
const {
|
||||
name,
|
||||
description,
|
||||
metricAlias,
|
||||
logAlias,
|
||||
fields,
|
||||
inventoryDefaultView,
|
||||
metricsExplorerDefaultView,
|
||||
logColumns,
|
||||
anomalyThreshold,
|
||||
} = value;
|
||||
const { container, host, pod, tiebreaker, timestamp } = fields;
|
||||
|
||||
return {
|
||||
name,
|
||||
description,
|
||||
metricAlias,
|
||||
logAlias,
|
||||
inventoryDefaultView,
|
||||
metricsExplorerDefaultView,
|
||||
fields: { container, host, pod, tiebreaker, timestamp },
|
||||
logColumns,
|
||||
anomalyThreshold,
|
||||
};
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Static source configuration as read from the configuration file
|
||||
* Static source configuration, the result of merging values from the config file and
|
||||
* hardcoded defaults.
|
||||
*/
|
||||
|
||||
const StaticSourceConfigurationFieldsRuntimeType = rt.partial({
|
||||
...SavedSourceConfigurationFieldsRuntimeType.props,
|
||||
message: rt.array(rt.string),
|
||||
});
|
||||
|
||||
const StaticSourceConfigurationFieldsRuntimeType = rt.partial(SourceConfigurationFieldsRT.props);
|
||||
export const StaticSourceConfigurationRuntimeType = rt.partial({
|
||||
name: rt.string,
|
||||
description: rt.string,
|
||||
metricAlias: rt.string,
|
||||
logAlias: rt.string,
|
||||
inventoryDefaultView: rt.string,
|
||||
metricsExplorerDefaultView: rt.string,
|
||||
...SourceConfigurationRT.props,
|
||||
fields: StaticSourceConfigurationFieldsRuntimeType,
|
||||
logColumns: rt.array(SavedSourceConfigurationColumnRuntimeType),
|
||||
anomalyThreshold: rt.number,
|
||||
});
|
||||
|
||||
export interface InfraStaticSourceConfiguration
|
||||
|
@ -153,18 +156,20 @@ export interface InfraStaticSourceConfiguration
|
|||
* Full source configuration type after all cleanup has been done at the edges
|
||||
*/
|
||||
|
||||
const SourceConfigurationFieldsRuntimeType = rt.type({
|
||||
...StaticSourceConfigurationFieldsRuntimeType.props,
|
||||
});
|
||||
|
||||
export type InfraSourceConfigurationFields = rt.TypeOf<typeof SourceConfigurationFieldsRuntimeType>;
|
||||
export type InfraSourceConfigurationFields = rt.TypeOf<typeof SourceConfigurationFieldsRT>;
|
||||
|
||||
export const SourceConfigurationRuntimeType = rt.type({
|
||||
...SavedSourceConfigurationRuntimeType.props,
|
||||
fields: SourceConfigurationFieldsRuntimeType,
|
||||
logColumns: rt.array(SavedSourceConfigurationColumnRuntimeType),
|
||||
...SourceConfigurationRT.props,
|
||||
fields: SourceConfigurationFieldsRT,
|
||||
logColumns: rt.array(SourceConfigurationColumnRuntimeType),
|
||||
});
|
||||
|
||||
export interface InfraSourceConfiguration
|
||||
extends rt.TypeOf<typeof SourceConfigurationRuntimeType> {}
|
||||
|
||||
/**
|
||||
* Source status
|
||||
*/
|
||||
const SourceStatusFieldRuntimeType = rt.type({
|
||||
name: rt.string,
|
||||
type: rt.string,
|
||||
|
@ -175,12 +180,17 @@ const SourceStatusFieldRuntimeType = rt.type({
|
|||
|
||||
export type InfraSourceIndexField = rt.TypeOf<typeof SourceStatusFieldRuntimeType>;
|
||||
|
||||
const SourceStatusRuntimeType = rt.type({
|
||||
export const SourceStatusRuntimeType = rt.type({
|
||||
logIndicesExist: rt.boolean,
|
||||
metricIndicesExist: rt.boolean,
|
||||
indexFields: rt.array(SourceStatusFieldRuntimeType),
|
||||
});
|
||||
|
||||
export interface InfraSourceStatus extends rt.TypeOf<typeof SourceStatusRuntimeType> {}
|
||||
|
||||
/**
|
||||
* Source configuration along with source status and metadata
|
||||
*/
|
||||
export const SourceRuntimeType = rt.intersection([
|
||||
rt.type({
|
||||
id: rt.string,
|
||||
|
@ -198,11 +208,6 @@ export const SourceRuntimeType = rt.intersection([
|
|||
}),
|
||||
]);
|
||||
|
||||
export interface InfraSourceStatus extends rt.TypeOf<typeof SourceStatusRuntimeType> {}
|
||||
|
||||
export interface InfraSourceConfiguration
|
||||
extends rt.TypeOf<typeof SourceConfigurationRuntimeType> {}
|
||||
|
||||
export interface InfraSource extends rt.TypeOf<typeof SourceRuntimeType> {}
|
||||
|
||||
export const SourceResponseRuntimeType = rt.type({
|
|
@ -17,7 +17,7 @@ import { act } from 'react-dom/test-utils';
|
|||
import { Comparator } from '../../../../server/lib/alerting/metric_threshold/types';
|
||||
import { SnapshotCustomMetricInput } from '../../../../common/http_api/snapshot_api';
|
||||
|
||||
jest.mock('../../../containers/source/use_source_via_http', () => ({
|
||||
jest.mock('../../../containers/metrics_source/use_source_via_http', () => ({
|
||||
useSourceViaHttp: () => ({
|
||||
source: { id: 'default' },
|
||||
createDerivedIndexPattern: () => ({ fields: [], title: 'metricbeat-*' }),
|
||||
|
|
|
@ -43,7 +43,7 @@ import {
|
|||
AlertTypeParamsExpressionProps,
|
||||
} from '../../../../../triggers_actions_ui/public';
|
||||
import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar';
|
||||
import { useSourceViaHttp } from '../../../containers/source/use_source_via_http';
|
||||
import { useSourceViaHttp } from '../../../containers/metrics_source/use_source_via_http';
|
||||
import { sqsMetricTypes } from '../../../../common/inventory_models/aws_sqs/toolbar_items';
|
||||
import { ec2MetricTypes } from '../../../../common/inventory_models/aws_ec2/toolbar_items';
|
||||
import { s3MetricTypes } from '../../../../common/inventory_models/aws_s3/toolbar_items';
|
||||
|
@ -124,14 +124,13 @@ export const Expressions: React.FC<Props> = (props) => {
|
|||
} = props;
|
||||
const { source, createDerivedIndexPattern } = useSourceViaHttp({
|
||||
sourceId: 'default',
|
||||
type: 'metrics',
|
||||
fetch: http.fetch,
|
||||
toastWarning: notifications.toasts.addWarning,
|
||||
});
|
||||
const [timeSize, setTimeSize] = useState<number | undefined>(1);
|
||||
const [timeUnit, setTimeUnit] = useState<Unit>('m');
|
||||
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern('metrics'), [
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern(), [
|
||||
createDerivedIndexPattern,
|
||||
]);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import React from 'react';
|
|||
import { Expression, AlertContextMeta } from './expression';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
jest.mock('../../../containers/source/use_source_via_http', () => ({
|
||||
jest.mock('../../../containers/metrics_source/use_source_via_http', () => ({
|
||||
useSourceViaHttp: () => ({
|
||||
source: { id: 'default' },
|
||||
createDerivedIndexPattern: () => ({ fields: [], title: 'metricbeat-*' }),
|
||||
|
|
|
@ -27,7 +27,7 @@ import {
|
|||
AlertTypeParamsExpressionProps,
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
} from '../../../../../triggers_actions_ui/public/types';
|
||||
import { useSourceViaHttp } from '../../../containers/source/use_source_via_http';
|
||||
import { useSourceViaHttp } from '../../../containers/metrics_source/use_source_via_http';
|
||||
import { findInventoryModel } from '../../../../common/inventory_models';
|
||||
import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types';
|
||||
import { NodeTypeExpression } from './node_type';
|
||||
|
@ -75,12 +75,11 @@ export const Expression: React.FC<Props> = (props) => {
|
|||
} = props;
|
||||
const { source, createDerivedIndexPattern } = useSourceViaHttp({
|
||||
sourceId: 'default',
|
||||
type: 'metrics',
|
||||
fetch: http.fetch,
|
||||
toastWarning: notifications.toasts.addWarning,
|
||||
});
|
||||
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern('metrics'), [
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern(), [
|
||||
createDerivedIndexPattern,
|
||||
]);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import { act } from 'react-dom/test-utils';
|
|||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { Comparator } from '../../../../server/lib/alerting/metric_threshold/types';
|
||||
|
||||
jest.mock('../../../containers/source/use_source_via_http', () => ({
|
||||
jest.mock('../../../containers/metrics_source/use_source_via_http', () => ({
|
||||
useSourceViaHttp: () => ({
|
||||
source: { id: 'default' },
|
||||
createDerivedIndexPattern: () => ({ fields: [], title: 'metricbeat-*' }),
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar';
|
||||
import { MetricsExplorerOptions } from '../../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options';
|
||||
import { MetricsExplorerGroupBy } from '../../../pages/metrics/metrics_explorer/components/group_by';
|
||||
import { useSourceViaHttp } from '../../../containers/source/use_source_via_http';
|
||||
import { useSourceViaHttp } from '../../../containers/metrics_source/use_source_via_http';
|
||||
import { convertKueryToElasticSearchQuery } from '../../../utils/kuery';
|
||||
|
||||
import { ExpressionRow } from './expression_row';
|
||||
|
@ -73,14 +73,13 @@ export const Expressions: React.FC<Props> = (props) => {
|
|||
const { http, notifications } = useKibanaContextForPlugin().services;
|
||||
const { source, createDerivedIndexPattern } = useSourceViaHttp({
|
||||
sourceId: 'default',
|
||||
type: 'metrics',
|
||||
fetch: http.fetch,
|
||||
toastWarning: notifications.toasts.addWarning,
|
||||
});
|
||||
|
||||
const [timeSize, setTimeSize] = useState<number | undefined>(1);
|
||||
const [timeUnit, setTimeUnit] = useState<Unit | undefined>('m');
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern('metrics'), [
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern(), [
|
||||
createDerivedIndexPattern,
|
||||
]);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { mountWithIntl, nextTick } from '@kbn/test/jest';
|
|||
import { coreMock as mockCoreMock } from 'src/core/public/mocks';
|
||||
import { MetricExpression } from '../types';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfiguration } from '../../../../common/metrics_sources';
|
||||
import React from 'react';
|
||||
import { ExpressionChart } from './expression_chart';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
@ -45,20 +45,17 @@ describe('ExpressionChart', () => {
|
|||
fields: [],
|
||||
};
|
||||
|
||||
const source: InfraSource = {
|
||||
const source: MetricsSourceConfiguration = {
|
||||
id: 'default',
|
||||
origin: 'fallback',
|
||||
configuration: {
|
||||
name: 'default',
|
||||
description: 'The default configuration',
|
||||
logColumns: [],
|
||||
metricAlias: 'metricbeat-*',
|
||||
logAlias: 'filebeat-*',
|
||||
inventoryDefaultView: 'host',
|
||||
metricsExplorerDefaultView: 'host',
|
||||
fields: {
|
||||
timestamp: '@timestamp',
|
||||
message: ['message'],
|
||||
container: 'container.id',
|
||||
host: 'host.name',
|
||||
pod: 'kubernetes.pod.uid',
|
||||
|
|
|
@ -11,7 +11,7 @@ import { first, last } from 'lodash';
|
|||
import { EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfiguration } from '../../../../common/metrics_sources';
|
||||
import { Color } from '../../../../common/color_palette';
|
||||
import { MetricsExplorerRow, MetricsExplorerAggregation } from '../../../../common/http_api';
|
||||
import { MetricExplorerSeriesChart } from '../../../pages/metrics/metrics_explorer/components/series_chart';
|
||||
|
@ -35,7 +35,7 @@ import { ThresholdAnnotations } from '../../common/criterion_preview_chart/thres
|
|||
interface Props {
|
||||
expression: MetricExpression;
|
||||
derivedIndexPattern: IIndexPattern;
|
||||
source: InfraSource | null;
|
||||
source: MetricsSourceConfiguration | null;
|
||||
filterQuery?: string;
|
||||
groupBy?: string | string[];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import { act } from 'react-dom/test-utils';
|
|||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { Comparator } from '../../../../server/lib/alerting/metric_threshold/types';
|
||||
|
||||
jest.mock('../../../containers/source/use_source_via_http', () => ({
|
||||
jest.mock('../../../containers/metrics_source/use_source_via_http', () => ({
|
||||
useSourceViaHttp: () => ({
|
||||
source: { id: 'default' },
|
||||
createDerivedIndexPattern: () => ({ fields: [], title: 'metricbeat-*' }),
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import { useMemo } from 'react';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfiguration } from '../../../../common/metrics_sources';
|
||||
import { MetricExpression } from '../types';
|
||||
import { MetricsExplorerOptions } from '../../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_options';
|
||||
import { useMetricsExplorerData } from '../../../pages/metrics/metrics_explorer/hooks/use_metrics_explorer_data';
|
||||
|
@ -15,7 +15,7 @@ import { useMetricsExplorerData } from '../../../pages/metrics/metrics_explorer/
|
|||
export const useMetricsExplorerChartData = (
|
||||
expression: MetricExpression,
|
||||
derivedIndexPattern: IIndexPattern,
|
||||
source: InfraSource | null,
|
||||
source: MetricsSourceConfiguration | null,
|
||||
filterQuery?: string,
|
||||
groupBy?: string | string[]
|
||||
) => {
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './input_fields';
|
||||
export { SourceConfigurationSettings } from './source_configuration_settings';
|
||||
export { ViewSourceConfigurationButton } from './view_source_configuration_button';
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
LogColumnConfiguration,
|
||||
isTimestampLogColumnConfiguration,
|
||||
isMessageLogColumnConfiguration,
|
||||
TimestampLogColumnConfiguration,
|
||||
MessageLogColumnConfiguration,
|
||||
FieldLogColumnConfiguration,
|
||||
} from '../../utils/source_configuration';
|
||||
|
||||
export interface TimestampLogColumnConfigurationProps {
|
||||
logColumnConfiguration: TimestampLogColumnConfiguration['timestampColumn'];
|
||||
remove: () => void;
|
||||
type: 'timestamp';
|
||||
}
|
||||
|
||||
export interface MessageLogColumnConfigurationProps {
|
||||
logColumnConfiguration: MessageLogColumnConfiguration['messageColumn'];
|
||||
remove: () => void;
|
||||
type: 'message';
|
||||
}
|
||||
|
||||
export interface FieldLogColumnConfigurationProps {
|
||||
logColumnConfiguration: FieldLogColumnConfiguration['fieldColumn'];
|
||||
remove: () => void;
|
||||
type: 'field';
|
||||
}
|
||||
|
||||
export type LogColumnConfigurationProps =
|
||||
| TimestampLogColumnConfigurationProps
|
||||
| MessageLogColumnConfigurationProps
|
||||
| FieldLogColumnConfigurationProps;
|
||||
|
||||
interface FormState {
|
||||
logColumns: LogColumnConfiguration[];
|
||||
}
|
||||
|
||||
type FormStateChanges = Partial<FormState>;
|
||||
|
||||
export const useLogColumnsConfigurationFormState = ({
|
||||
initialFormState = defaultFormState,
|
||||
}: {
|
||||
initialFormState?: FormState;
|
||||
}) => {
|
||||
const [formStateChanges, setFormStateChanges] = useState<FormStateChanges>({});
|
||||
|
||||
const resetForm = useCallback(() => setFormStateChanges({}), []);
|
||||
|
||||
const formState = useMemo(
|
||||
() => ({
|
||||
...initialFormState,
|
||||
...formStateChanges,
|
||||
}),
|
||||
[initialFormState, formStateChanges]
|
||||
);
|
||||
|
||||
const logColumnConfigurationProps = useMemo<LogColumnConfigurationProps[]>(
|
||||
() =>
|
||||
formState.logColumns.map(
|
||||
(logColumn): LogColumnConfigurationProps => {
|
||||
const remove = () =>
|
||||
setFormStateChanges((changes) => ({
|
||||
...changes,
|
||||
logColumns: formState.logColumns.filter((item) => item !== logColumn),
|
||||
}));
|
||||
|
||||
if (isTimestampLogColumnConfiguration(logColumn)) {
|
||||
return {
|
||||
logColumnConfiguration: logColumn.timestampColumn,
|
||||
remove,
|
||||
type: 'timestamp',
|
||||
};
|
||||
} else if (isMessageLogColumnConfiguration(logColumn)) {
|
||||
return {
|
||||
logColumnConfiguration: logColumn.messageColumn,
|
||||
remove,
|
||||
type: 'message',
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
logColumnConfiguration: logColumn.fieldColumn,
|
||||
remove,
|
||||
type: 'field',
|
||||
};
|
||||
}
|
||||
}
|
||||
),
|
||||
[formState.logColumns]
|
||||
);
|
||||
|
||||
const addLogColumn = useCallback(
|
||||
(logColumnConfiguration: LogColumnConfiguration) =>
|
||||
setFormStateChanges((changes) => ({
|
||||
...changes,
|
||||
logColumns: [...formState.logColumns, logColumnConfiguration],
|
||||
})),
|
||||
[formState.logColumns]
|
||||
);
|
||||
|
||||
const moveLogColumn = useCallback(
|
||||
(sourceIndex, destinationIndex) => {
|
||||
if (destinationIndex >= 0 && sourceIndex <= formState.logColumns.length - 1) {
|
||||
const newLogColumns = [...formState.logColumns];
|
||||
newLogColumns.splice(destinationIndex, 0, newLogColumns.splice(sourceIndex, 1)[0]);
|
||||
setFormStateChanges((changes) => ({
|
||||
...changes,
|
||||
logColumns: newLogColumns,
|
||||
}));
|
||||
}
|
||||
},
|
||||
[formState.logColumns]
|
||||
);
|
||||
|
||||
const errors = useMemo(
|
||||
() =>
|
||||
logColumnConfigurationProps.length <= 0
|
||||
? [
|
||||
<FormattedMessage
|
||||
id="xpack.infra.sourceConfiguration.logColumnListEmptyErrorMessage"
|
||||
defaultMessage="The log column list must not be empty."
|
||||
/>,
|
||||
]
|
||||
: [],
|
||||
[logColumnConfigurationProps]
|
||||
);
|
||||
|
||||
const isFormValid = useMemo(() => (errors.length <= 0 ? true : false), [errors]);
|
||||
|
||||
const isFormDirty = useMemo(() => Object.keys(formStateChanges).length > 0, [formStateChanges]);
|
||||
|
||||
return {
|
||||
addLogColumn,
|
||||
moveLogColumn,
|
||||
errors,
|
||||
logColumnConfigurationProps,
|
||||
formState,
|
||||
formStateChanges,
|
||||
isFormDirty,
|
||||
isFormValid,
|
||||
resetForm,
|
||||
};
|
||||
};
|
||||
|
||||
const defaultFormState: FormState = {
|
||||
logColumns: [],
|
||||
};
|
|
@ -9,27 +9,25 @@ import createContainer from 'constate';
|
|||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import {
|
||||
InfraSavedSourceConfiguration,
|
||||
InfraSource,
|
||||
SourceResponse,
|
||||
} from '../../../common/http_api/source_api';
|
||||
MetricsSourceConfigurationResponse,
|
||||
MetricsSourceConfiguration,
|
||||
PartialMetricsSourceConfigurationProperties,
|
||||
} from '../../../common/metrics_sources';
|
||||
|
||||
import { useTrackedPromise } from '../../utils/use_tracked_promise';
|
||||
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
|
||||
|
||||
export const pickIndexPattern = (
|
||||
source: InfraSource | undefined,
|
||||
type: 'logs' | 'metrics' | 'both'
|
||||
source: MetricsSourceConfiguration | undefined,
|
||||
type: 'metrics'
|
||||
) => {
|
||||
if (!source) {
|
||||
return 'unknown-index';
|
||||
}
|
||||
if (type === 'logs') {
|
||||
return source.configuration.logAlias;
|
||||
}
|
||||
if (type === 'metrics') {
|
||||
return source.configuration.metricAlias;
|
||||
}
|
||||
return `${source.configuration.logAlias},${source.configuration.metricAlias}`;
|
||||
return `${source.configuration.metricAlias}`;
|
||||
};
|
||||
|
||||
const DEPENDENCY_ERROR_MESSAGE = 'Failed to load source: No fetch client available.';
|
||||
|
@ -39,7 +37,7 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
const fetchService = kibana.services.http?.fetch;
|
||||
const API_URL = `/api/metrics/source/${sourceId}`;
|
||||
|
||||
const [source, setSource] = useState<InfraSource | undefined>(undefined);
|
||||
const [source, setSource] = useState<MetricsSourceConfiguration | undefined>(undefined);
|
||||
|
||||
const [loadSourceRequest, loadSource] = useTrackedPromise(
|
||||
{
|
||||
|
@ -49,7 +47,7 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
throw new Error(DEPENDENCY_ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
return await fetchService<SourceResponse>(`${API_URL}/metrics`, {
|
||||
return await fetchService<MetricsSourceConfigurationResponse>(`${API_URL}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
},
|
||||
|
@ -62,12 +60,12 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
|
||||
const [createSourceConfigurationRequest, createSourceConfiguration] = useTrackedPromise(
|
||||
{
|
||||
createPromise: async (sourceProperties: InfraSavedSourceConfiguration) => {
|
||||
createPromise: async (sourceProperties: PartialMetricsSourceConfigurationProperties) => {
|
||||
if (!fetchService) {
|
||||
throw new Error(DEPENDENCY_ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
return await fetchService<SourceResponse>(API_URL, {
|
||||
return await fetchService<MetricsSourceConfigurationResponse>(API_URL, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(sourceProperties),
|
||||
});
|
||||
|
@ -83,12 +81,12 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
|
||||
const [updateSourceConfigurationRequest, updateSourceConfiguration] = useTrackedPromise(
|
||||
{
|
||||
createPromise: async (sourceProperties: InfraSavedSourceConfiguration) => {
|
||||
createPromise: async (sourceProperties: PartialMetricsSourceConfigurationProperties) => {
|
||||
if (!fetchService) {
|
||||
throw new Error(DEPENDENCY_ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
return await fetchService<SourceResponse>(API_URL, {
|
||||
return await fetchService<MetricsSourceConfigurationResponse>(API_URL, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(sourceProperties),
|
||||
});
|
||||
|
@ -102,7 +100,7 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
[fetchService, sourceId]
|
||||
);
|
||||
|
||||
const createDerivedIndexPattern = (type: 'logs' | 'metrics' | 'both') => {
|
||||
const createDerivedIndexPattern = (type: 'metrics') => {
|
||||
return {
|
||||
fields: source?.status ? source.status.indexFields : [],
|
||||
title: pickIndexPattern(source, type),
|
||||
|
@ -129,9 +127,6 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
|
||||
const sourceExists = useMemo(() => (source ? !!source.version : undefined), [source]);
|
||||
|
||||
const logIndicesExist = useMemo(() => source && source.status && source.status.logIndicesExist, [
|
||||
source,
|
||||
]);
|
||||
const metricIndicesExist = useMemo(
|
||||
() => source && source.status && source.status.metricIndicesExist,
|
||||
[source]
|
||||
|
@ -144,7 +139,6 @@ export const useSource = ({ sourceId }: { sourceId: string }) => {
|
|||
return {
|
||||
createSourceConfiguration,
|
||||
createDerivedIndexPattern,
|
||||
logIndicesExist,
|
||||
isLoading,
|
||||
isLoadingSource: loadSourceRequest.state === 'pending',
|
||||
isUninitialized,
|
|
@ -13,51 +13,47 @@ import createContainer from 'constate';
|
|||
import { HttpHandler } from 'src/core/public';
|
||||
import { ToastInput } from 'src/core/public';
|
||||
import {
|
||||
SourceResponseRuntimeType,
|
||||
SourceResponse,
|
||||
InfraSource,
|
||||
} from '../../../common/http_api/source_api';
|
||||
metricsSourceConfigurationResponseRT,
|
||||
MetricsSourceConfigurationResponse,
|
||||
MetricsSourceConfiguration,
|
||||
} from '../../../common/metrics_sources';
|
||||
import { useHTTPRequest } from '../../hooks/use_http_request';
|
||||
import { throwErrors, createPlainError } from '../../../common/runtime_types';
|
||||
|
||||
export const pickIndexPattern = (
|
||||
source: InfraSource | undefined,
|
||||
type: 'logs' | 'metrics' | 'both'
|
||||
source: MetricsSourceConfiguration | undefined,
|
||||
type: 'metrics'
|
||||
) => {
|
||||
if (!source) {
|
||||
return 'unknown-index';
|
||||
}
|
||||
if (type === 'logs') {
|
||||
return source.configuration.logAlias;
|
||||
}
|
||||
if (type === 'metrics') {
|
||||
return source.configuration.metricAlias;
|
||||
}
|
||||
return `${source.configuration.logAlias},${source.configuration.metricAlias}`;
|
||||
return `${source.configuration.metricAlias}`;
|
||||
};
|
||||
|
||||
interface Props {
|
||||
sourceId: string;
|
||||
type: 'logs' | 'metrics' | 'both';
|
||||
fetch?: HttpHandler;
|
||||
toastWarning?: (input: ToastInput) => void;
|
||||
}
|
||||
|
||||
export const useSourceViaHttp = ({
|
||||
sourceId = 'default',
|
||||
type = 'both',
|
||||
fetch,
|
||||
toastWarning,
|
||||
}: Props) => {
|
||||
export const useSourceViaHttp = ({ sourceId = 'default', fetch, toastWarning }: Props) => {
|
||||
const decodeResponse = (response: any) => {
|
||||
return pipe(
|
||||
SourceResponseRuntimeType.decode(response),
|
||||
metricsSourceConfigurationResponseRT.decode(response),
|
||||
fold(throwErrors(createPlainError), identity)
|
||||
);
|
||||
};
|
||||
|
||||
const { error, loading, response, makeRequest } = useHTTPRequest<SourceResponse>(
|
||||
`/api/metrics/source/${sourceId}/${type}`,
|
||||
const {
|
||||
error,
|
||||
loading,
|
||||
response,
|
||||
makeRequest,
|
||||
} = useHTTPRequest<MetricsSourceConfigurationResponse>(
|
||||
`/api/metrics/source/${sourceId}`,
|
||||
'GET',
|
||||
null,
|
||||
decodeResponse,
|
||||
|
@ -71,15 +67,12 @@ export const useSourceViaHttp = ({
|
|||
})();
|
||||
}, [makeRequest]);
|
||||
|
||||
const createDerivedIndexPattern = useCallback(
|
||||
(indexType: 'logs' | 'metrics' | 'both' = type) => {
|
||||
return {
|
||||
fields: response?.source.status ? response.source.status.indexFields : [],
|
||||
title: pickIndexPattern(response?.source, indexType),
|
||||
};
|
||||
},
|
||||
[response, type]
|
||||
);
|
||||
const createDerivedIndexPattern = useCallback(() => {
|
||||
return {
|
||||
fields: response?.source.status ? response.source.status.indexFields : [],
|
||||
title: pickIndexPattern(response?.source, 'metrics'),
|
||||
};
|
||||
}, [response]);
|
||||
|
||||
const source = useMemo(() => {
|
||||
return response ? response.source : null;
|
|
@ -17,10 +17,10 @@ import { useUrlState } from '../../utils/use_url_state';
|
|||
import { useFindSavedObject } from '../../hooks/use_find_saved_object';
|
||||
import { useCreateSavedObject } from '../../hooks/use_create_saved_object';
|
||||
import { useDeleteSavedObject } from '../../hooks/use_delete_saved_object';
|
||||
import { Source } from '../source';
|
||||
import { Source } from '../metrics_source';
|
||||
import { metricsExplorerViewSavedObjectName } from '../../../common/saved_objects/metrics_explorer_view';
|
||||
import { inventoryViewSavedObjectName } from '../../../common/saved_objects/inventory_view';
|
||||
import { useSourceConfigurationFormState } from '../../components/source_configuration/source_configuration_form_state';
|
||||
import { useSourceConfigurationFormState } from '../../pages/metrics/settings/source_configuration_form_state';
|
||||
import { useGetSavedObject } from '../../hooks/use_get_saved_object';
|
||||
import { useUpdateSavedObject } from '../../hooks/use_update_saved_object';
|
||||
|
||||
|
|
|
@ -9,17 +9,19 @@ import React, { useContext } from 'react';
|
|||
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import {
|
||||
InfraSavedSourceConfiguration,
|
||||
InfraSourceConfiguration,
|
||||
} from '../../../common/http_api/source_api';
|
||||
MetricsSourceConfigurationProperties,
|
||||
PartialMetricsSourceConfigurationProperties,
|
||||
} from '../../../common/metrics_sources';
|
||||
import { RendererFunction } from '../../utils/typed_react';
|
||||
import { Source } from '../source';
|
||||
import { Source } from '../metrics_source';
|
||||
|
||||
interface WithSourceProps {
|
||||
children: RendererFunction<{
|
||||
configuration?: InfraSourceConfiguration;
|
||||
create: (sourceProperties: InfraSavedSourceConfiguration) => Promise<any> | undefined;
|
||||
createDerivedIndexPattern: (type: 'logs' | 'metrics' | 'both') => IIndexPattern;
|
||||
configuration?: MetricsSourceConfigurationProperties;
|
||||
create: (
|
||||
sourceProperties: PartialMetricsSourceConfigurationProperties
|
||||
) => Promise<any> | undefined;
|
||||
createDerivedIndexPattern: (type: 'metrics') => IIndexPattern;
|
||||
exists?: boolean;
|
||||
hasFailed: boolean;
|
||||
isLoading: boolean;
|
||||
|
@ -29,7 +31,9 @@ interface WithSourceProps {
|
|||
metricAlias?: string;
|
||||
metricIndicesExist?: boolean;
|
||||
sourceId: string;
|
||||
update: (sourceProperties: InfraSavedSourceConfiguration) => Promise<any> | undefined;
|
||||
update: (
|
||||
sourceProperties: PartialMetricsSourceConfigurationProperties
|
||||
) => Promise<any> | undefined;
|
||||
version?: string;
|
||||
}>;
|
||||
}
|
||||
|
@ -42,7 +46,6 @@ export const WithSource: React.FunctionComponent<WithSourceProps> = ({ children
|
|||
sourceExists,
|
||||
sourceId,
|
||||
metricIndicesExist,
|
||||
logIndicesExist,
|
||||
isLoading,
|
||||
loadSource,
|
||||
hasFailedLoadingSource,
|
||||
|
@ -60,7 +63,6 @@ export const WithSource: React.FunctionComponent<WithSourceProps> = ({ children
|
|||
isLoading,
|
||||
lastFailureMessage: loadSourceFailureMessage,
|
||||
load: loadSource,
|
||||
logIndicesExist,
|
||||
metricIndicesExist,
|
||||
sourceId,
|
||||
update: updateSourceConfiguration,
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
SnapshotNodeMetric,
|
||||
SnapshotNodePath,
|
||||
} from '../../common/http_api/snapshot_api';
|
||||
import { InfraSourceConfigurationFields } from '../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../common/metrics_sources';
|
||||
import { WaffleSortOption } from '../pages/metrics/inventory_view/hooks/use_waffle_options';
|
||||
|
||||
export interface InfraWaffleMapNode {
|
||||
|
@ -124,7 +124,7 @@ export enum InfraWaffleMapRuleOperator {
|
|||
}
|
||||
|
||||
export interface InfraWaffleMapOptions {
|
||||
fields?: InfraSourceConfigurationFields | null;
|
||||
fields?: MetricsSourceConfigurationProperties['fields'] | null;
|
||||
formatter: InfraFormatterType;
|
||||
formatTemplate: string;
|
||||
metric: SnapshotMetricInput;
|
||||
|
|
|
@ -14,9 +14,7 @@ export const createMetricsHasData = (
|
|||
) => async () => {
|
||||
const [coreServices] = await getStartServices();
|
||||
const { http } = coreServices;
|
||||
const results = await http.get<{ hasData: boolean }>(
|
||||
'/api/metrics/source/default/metrics/hasData'
|
||||
);
|
||||
const results = await http.get<{ hasData: boolean }>('/api/metrics/source/default/hasData');
|
||||
return results.hasData;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { useHostIpToName } from './use_host_ip_to_name';
|
|||
import { getFromFromLocation, getToFromLocation } from './query_params';
|
||||
import { LoadingPage } from '../../components/loading_page';
|
||||
import { Error } from '../error';
|
||||
import { useSource } from '../../containers/source/source';
|
||||
import { useSourceViaHttp } from '../../containers/metrics_source/use_source_via_http';
|
||||
|
||||
type RedirectToHostDetailType = RouteComponentProps<{
|
||||
hostIp: string;
|
||||
|
@ -26,7 +26,7 @@ export const RedirectToHostDetailViaIP = ({
|
|||
},
|
||||
location,
|
||||
}: RedirectToHostDetailType) => {
|
||||
const { source } = useSource({ sourceId: 'default' });
|
||||
const { source } = useSourceViaHttp({ sourceId: 'default' });
|
||||
|
||||
const { error, name } = useHostIpToName(
|
||||
hostIp,
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { InputFieldProps } from '../../../components/source_configuration';
|
||||
import { InputFieldProps } from '../../../components/source_configuration/input_fields';
|
||||
|
||||
interface FieldsConfigurationPanelProps {
|
||||
isLoading: boolean;
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { InputFieldProps } from '../../../components/source_configuration';
|
||||
import { InputFieldProps } from '../../../components/source_configuration/input_fields';
|
||||
|
||||
interface IndicesConfigurationPanelProps {
|
||||
isLoading: boolean;
|
||||
|
|
|
@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import React from 'react';
|
||||
|
||||
import { NoIndices } from '../../../components/empty_states/no_indices';
|
||||
import { ViewSourceConfigurationButton } from '../../../components/source_configuration';
|
||||
import { ViewSourceConfigurationButton } from '../../../components/source_configuration/view_source_configuration_button';
|
||||
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { useLinkProps } from '../../../hooks/use_link_props';
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Route, RouteComponentProps, Switch } from 'react-router-dom';
|
|||
|
||||
import { EuiErrorBoundary, EuiFlexItem, EuiFlexGroup, EuiButtonEmpty } from '@elastic/eui';
|
||||
import { IIndexPattern } from 'src/plugins/data/common';
|
||||
import { InfraSourceConfiguration } from '../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../common/metrics_sources';
|
||||
import { DocumentTitle } from '../../components/document_title';
|
||||
import { HelpCenterContent } from '../../components/help_center_content';
|
||||
import { RoutedTabs } from '../../components/navigation/routed_tabs';
|
||||
|
@ -24,7 +24,7 @@ import {
|
|||
} from './metrics_explorer/hooks/use_metrics_explorer_options';
|
||||
import { WithMetricsExplorerOptionsUrlState } from '../../containers/metrics_explorer/with_metrics_explorer_options_url_state';
|
||||
import { WithSource } from '../../containers/with_source';
|
||||
import { Source } from '../../containers/source';
|
||||
import { Source } from '../../containers/metrics_source';
|
||||
import { MetricsExplorerPage } from './metrics_explorer';
|
||||
import { SnapshotPage } from './inventory_view';
|
||||
import { MetricsSettingsPage } from './settings';
|
||||
|
@ -188,8 +188,8 @@ export const InfrastructurePage = ({ match }: RouteComponentProps) => {
|
|||
};
|
||||
|
||||
const PageContent = (props: {
|
||||
configuration: InfraSourceConfiguration;
|
||||
createDerivedIndexPattern: (type: 'logs' | 'metrics' | 'both') => IIndexPattern;
|
||||
configuration: MetricsSourceConfigurationProperties;
|
||||
createDerivedIndexPattern: (type: 'metrics') => IIndexPattern;
|
||||
}) => {
|
||||
const { createDerivedIndexPattern, configuration } = props;
|
||||
const { options } = useContext(MetricsExplorerOptionsContainer.Context);
|
||||
|
|
|
@ -18,7 +18,7 @@ import { useSnapshot } from '../hooks/use_snaphot';
|
|||
import { useWaffleTimeContext } from '../hooks/use_waffle_time';
|
||||
import { useWaffleFiltersContext } from '../hooks/use_waffle_filters';
|
||||
import { DEFAULT_LEGEND, useWaffleOptionsContext } from '../hooks/use_waffle_options';
|
||||
import { useSourceContext } from '../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../containers/metrics_source';
|
||||
import { InfraFormatterType } from '../../../../lib/lib';
|
||||
import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common';
|
||||
import { Toolbar } from './toolbars/toolbar';
|
||||
|
|
|
@ -43,7 +43,7 @@ import {
|
|||
import { PaginationControls } from './pagination';
|
||||
import { AnomalySummary } from './annomaly_summary';
|
||||
import { AnomalySeverityIndicator } from '../../../../../../../components/logging/log_analysis_results/anomaly_severity_indicator';
|
||||
import { useSourceContext } from '../../../../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../../../../containers/metrics_source';
|
||||
import { createResultsUrl } from '../flyout_home';
|
||||
import { useWaffleViewState, WaffleViewState } from '../../../../hooks/use_waffle_view_state';
|
||||
type JobType = 'k8s' | 'hosts';
|
||||
|
|
|
@ -13,7 +13,7 @@ import { JobSetupScreen } from './job_setup_screen';
|
|||
import { useInfraMLCapabilities } from '../../../../../../containers/ml/infra_ml_capabilities';
|
||||
import { MetricHostsModuleProvider } from '../../../../../../containers/ml/modules/metrics_hosts/module';
|
||||
import { MetricK8sModuleProvider } from '../../../../../../containers/ml/modules/metrics_k8s/module';
|
||||
import { useSourceViaHttp } from '../../../../../../containers/source/use_source_via_http';
|
||||
import { useSourceViaHttp } from '../../../../../../containers/metrics_source/use_source_via_http';
|
||||
import { useActiveKibanaSpace } from '../../../../../../hooks/use_kibana_space';
|
||||
|
||||
export const AnomalyDetectionFlyout = () => {
|
||||
|
@ -23,7 +23,6 @@ export const AnomalyDetectionFlyout = () => {
|
|||
const [screenParams, setScreenParams] = useState<any | null>(null);
|
||||
const { source } = useSourceViaHttp({
|
||||
sourceId: 'default',
|
||||
type: 'metrics',
|
||||
});
|
||||
|
||||
const { space } = useActiveKibanaSpace();
|
||||
|
|
|
@ -17,7 +17,7 @@ import moment, { Moment } from 'moment';
|
|||
import { EuiComboBox } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiLoadingSpinner } from '@elastic/eui';
|
||||
import { useSourceViaHttp } from '../../../../../../containers/source/use_source_via_http';
|
||||
import { useSourceViaHttp } from '../../../../../../containers/metrics_source/use_source_via_http';
|
||||
import { useMetricK8sModuleContext } from '../../../../../../containers/ml/modules/metrics_k8s/module';
|
||||
import { useMetricHostsModuleContext } from '../../../../../../containers/ml/modules/metrics_hosts/module';
|
||||
import { FixedDatePicker } from '../../../../../../components/fixed_datepicker';
|
||||
|
@ -42,7 +42,6 @@ export const JobSetupScreen = (props: Props) => {
|
|||
const [filterQuery, setFilterQuery] = useState<string>('');
|
||||
const { createDerivedIndexPattern } = useSourceViaHttp({
|
||||
sourceId: 'default',
|
||||
type: 'metrics',
|
||||
});
|
||||
|
||||
const indicies = h.sourceConfiguration.indices;
|
||||
|
@ -79,7 +78,7 @@ export const JobSetupScreen = (props: Props) => {
|
|||
}
|
||||
}, [props.jobType, k.jobSummaries, h.jobSummaries]);
|
||||
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern('metrics'), [
|
||||
const derivedIndexPattern = useMemo(() => createDerivedIndexPattern(), [
|
||||
createDerivedIndexPattern,
|
||||
]);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import { EuiLoadingChart, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/e
|
|||
import { TabContent, TabProps } from '../shared';
|
||||
import { useSnapshot } from '../../../../hooks/use_snaphot';
|
||||
import { useWaffleOptionsContext } from '../../../../hooks/use_waffle_options';
|
||||
import { useSourceContext } from '../../../../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../../../../containers/metrics_source';
|
||||
import { findInventoryFields } from '../../../../../../../../common/inventory_models';
|
||||
import { convertKueryToElasticSearchQuery } from '../../../../../../../utils/kuery';
|
||||
import { SnapshotMetricType } from '../../../../../../../../common/inventory_models/types';
|
||||
|
|
|
@ -9,7 +9,7 @@ import React, { useCallback, useContext, useMemo } from 'react';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiLoadingChart } from '@elastic/eui';
|
||||
import { TabContent, TabProps } from '../shared';
|
||||
import { Source } from '../../../../../../../containers/source';
|
||||
import { Source } from '../../../../../../../containers/metrics_source';
|
||||
import { findInventoryModel } from '../../../../../../../../common/inventory_models';
|
||||
import { InventoryItemType } from '../../../../../../../../common/inventory_models/types';
|
||||
import { useMetadata } from '../../../../../metric_detail/hooks/use_metadata';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { useContext } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Source } from '../../../../containers/source';
|
||||
import { Source } from '../../../../containers/metrics_source';
|
||||
import { AutocompleteField } from '../../../../components/autocomplete_field';
|
||||
import { WithKueryAutocompletion } from '../../../../containers/with_kuery_autocompletion';
|
||||
import { useWaffleFiltersContext } from '../hooks/use_waffle_filters';
|
||||
|
|
|
@ -29,7 +29,7 @@ import { useUiSetting } from '../../../../../../../../../src/plugins/kibana_reac
|
|||
import { toMetricOpt } from '../../../../../../common/snapshot_metric_i18n';
|
||||
import { MetricsExplorerAggregation } from '../../../../../../common/http_api';
|
||||
import { colorTransformer, Color } from '../../../../../../common/color_palette';
|
||||
import { useSourceContext } from '../../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../../containers/metrics_source';
|
||||
import { useTimeline } from '../../hooks/use_timeline';
|
||||
import { useWaffleOptionsContext } from '../../hooks/use_waffle_options';
|
||||
import { useWaffleTimeContext } from '../../hooks/use_waffle_time';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { FunctionComponent } from 'react';
|
||||
import { EuiFlexItem } from '@elastic/eui';
|
||||
import { useSourceContext } from '../../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../../containers/metrics_source';
|
||||
import {
|
||||
SnapshotMetricInput,
|
||||
SnapshotGroupBy,
|
||||
|
@ -24,7 +24,7 @@ import { WaffleOptionsState, WaffleSortOption } from '../../hooks/use_waffle_opt
|
|||
import { useInventoryMeta } from '../../hooks/use_inventory_meta';
|
||||
|
||||
export interface ToolbarProps extends Omit<WaffleOptionsState, 'boundsOverride' | 'autoBounds'> {
|
||||
createDerivedIndexPattern: (type: 'logs' | 'metrics' | 'both') => IIndexPattern;
|
||||
createDerivedIndexPattern: (type: 'metrics') => IIndexPattern;
|
||||
changeMetric: (payload: SnapshotMetricInput) => void;
|
||||
changeGroupBy: (payload: SnapshotGroupBy) => void;
|
||||
changeCustomOptions: (payload: InfraGroupByOptions[]) => void;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React from 'react';
|
||||
import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
|
||||
import { fieldToName } from '../../lib/field_to_display_name';
|
||||
import { useSourceContext } from '../../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../../containers/metrics_source';
|
||||
import { useWaffleOptionsContext } from '../../hooks/use_waffle_options';
|
||||
import { WaffleInventorySwitcher } from '../waffle/waffle_inventory_switcher';
|
||||
import { ToolbarProps } from './toolbar';
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
InfraFormatterType,
|
||||
} from '../../../../../lib/lib';
|
||||
|
||||
jest.mock('../../../../../containers/source', () => ({
|
||||
jest.mock('../../../../../containers/metrics_source', () => ({
|
||||
useSourceContext: () => ({ sourceId: 'default' }),
|
||||
}));
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { first } from 'lodash';
|
|||
import { getCustomMetricLabel } from '../../../../../../common/formatters/get_custom_metric_label';
|
||||
import { SnapshotCustomMetricInput } from '../../../../../../common/http_api';
|
||||
import { withTheme, EuiTheme } from '../../../../../../../../../src/plugins/kibana_react/common';
|
||||
import { useSourceContext } from '../../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../../containers/metrics_source';
|
||||
import { findInventoryModel } from '../../../../../../common/inventory_models';
|
||||
import {
|
||||
InventoryItemType,
|
||||
|
|
|
@ -13,7 +13,7 @@ import { useEffect, useState } from 'react';
|
|||
import { ProcessListAPIResponse, ProcessListAPIResponseRT } from '../../../../../common/http_api';
|
||||
import { throwErrors, createPlainError } from '../../../../../common/runtime_types';
|
||||
import { useHTTPRequest } from '../../../../hooks/use_http_request';
|
||||
import { useSourceContext } from '../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../containers/metrics_source';
|
||||
|
||||
export interface SortBy {
|
||||
name: string;
|
||||
|
|
|
@ -17,7 +17,7 @@ jest.mock('react-router-dom', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
jest.mock('../../../../containers/source', () => ({
|
||||
jest.mock('../../../../containers/metrics_source', () => ({
|
||||
useSourceContext: () => ({
|
||||
createDerivedIndexPattern: () => 'jestbeat-*',
|
||||
}),
|
||||
|
|
|
@ -13,7 +13,7 @@ import { constant, identity } from 'fp-ts/lib/function';
|
|||
import createContainter from 'constate';
|
||||
import { useAlertPrefillContext } from '../../../../alerting/use_alert_prefill';
|
||||
import { useUrlState } from '../../../../utils/use_url_state';
|
||||
import { useSourceContext } from '../../../../containers/source';
|
||||
import { useSourceContext } from '../../../../containers/metrics_source';
|
||||
import { convertKueryToElasticSearchQuery } from '../../../../utils/kuery';
|
||||
import { esKuery } from '../../../../../../../../src/plugins/data/public';
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ import { ColumnarPage } from '../../../components/page';
|
|||
|
||||
import { SourceErrorPage } from '../../../components/source_error_page';
|
||||
import { SourceLoadingPage } from '../../../components/source_loading_page';
|
||||
import { ViewSourceConfigurationButton } from '../../../components/source_configuration';
|
||||
import { Source } from '../../../containers/source';
|
||||
import { ViewSourceConfigurationButton } from '../../../components/source_configuration/view_source_configuration_button';
|
||||
import { Source } from '../../../containers/metrics_source';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { Layout } from './components/layout';
|
||||
|
|
|
@ -14,7 +14,6 @@ const options: InfraWaffleMapOptions = {
|
|||
container: 'container.id',
|
||||
pod: 'kubernetes.pod.uid',
|
||||
host: 'host.name',
|
||||
message: ['@message'],
|
||||
timestamp: '@timestanp',
|
||||
tiebreaker: '@timestamp',
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@ import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/e
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common';
|
||||
import { ViewSourceConfigurationButton } from '../../../../components/source_configuration';
|
||||
import { ViewSourceConfigurationButton } from '../../../../components/source_configuration/view_source_configuration_button';
|
||||
import { useLinkProps } from '../../../../hooks/use_link_props';
|
||||
|
||||
interface InvalidNodeErrorProps {
|
||||
|
|
|
@ -17,7 +17,7 @@ import { Header } from '../../../components/header';
|
|||
import { ColumnarPage, PageContent } from '../../../components/page';
|
||||
import { withMetricPageProviders } from './page_providers';
|
||||
import { useMetadata } from './hooks/use_metadata';
|
||||
import { Source } from '../../../containers/source';
|
||||
import { Source } from '../../../containers/metrics_source';
|
||||
import { InfraLoadingPanel } from '../../../components/loading';
|
||||
import { findInventoryModel } from '../../../../common/inventory_models';
|
||||
import { NavItem } from './lib/side_nav_context';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { EuiErrorBoundary } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { Source } from '../../../containers/source';
|
||||
import { Source } from '../../../containers/metrics_source';
|
||||
import { MetricsTimeProvider } from './hooks/use_metrics_time';
|
||||
|
||||
export const withMetricPageProviders = <T extends object>(Component: React.ComponentType<T>) => (
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
} from '@elastic/charts';
|
||||
import { first, last } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { InfraSourceConfiguration } from '../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources';
|
||||
import { MetricsExplorerSeries } from '../../../../../common/http_api/metrics_explorer';
|
||||
import {
|
||||
MetricsExplorerOptions,
|
||||
|
@ -47,7 +47,7 @@ interface Props {
|
|||
options: MetricsExplorerOptions;
|
||||
chartOptions: MetricsExplorerChartOptions;
|
||||
series: MetricsExplorerSeries;
|
||||
source: InfraSourceConfiguration | undefined;
|
||||
source: MetricsSourceConfigurationProperties | undefined;
|
||||
timeRange: MetricsExplorerTimeOptions;
|
||||
onTimeChange: (start: string, end: string) => void;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import DateMath from '@elastic/datemath';
|
||||
import { Capabilities } from 'src/core/public';
|
||||
import { InfraSourceConfiguration } from '../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources';
|
||||
import { AlertFlyout } from '../../../../alerting/metric_threshold/components/alert_flyout';
|
||||
import { MetricsExplorerSeries } from '../../../../../common/http_api/metrics_explorer';
|
||||
import {
|
||||
|
@ -33,14 +33,14 @@ export interface Props {
|
|||
options: MetricsExplorerOptions;
|
||||
onFilter?: (query: string) => void;
|
||||
series: MetricsExplorerSeries;
|
||||
source?: InfraSourceConfiguration;
|
||||
source?: MetricsSourceConfigurationProperties;
|
||||
timeRange: MetricsExplorerTimeOptions;
|
||||
uiCapabilities?: Capabilities;
|
||||
chartOptions: MetricsExplorerChartOptions;
|
||||
}
|
||||
|
||||
const fieldToNodeType = (
|
||||
source: InfraSourceConfiguration,
|
||||
source: MetricsSourceConfigurationProperties,
|
||||
groupBy: string | string[]
|
||||
): InventoryItemType | undefined => {
|
||||
const fields = Array.isArray(groupBy) ? groupBy : [groupBy];
|
||||
|
|
|
@ -9,7 +9,7 @@ import { EuiButton, EuiFlexGrid, EuiFlexItem, EuiText, EuiHorizontalRule } from
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
import { InfraSourceConfiguration } from '../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources';
|
||||
import { MetricsExplorerResponse } from '../../../../../common/http_api/metrics_explorer';
|
||||
import {
|
||||
MetricsExplorerOptions,
|
||||
|
@ -31,7 +31,7 @@ interface Props {
|
|||
onFilter: (filter: string) => void;
|
||||
onTimeChange: (start: string, end: string) => void;
|
||||
data: MetricsExplorerResponse | null;
|
||||
source: InfraSourceConfiguration | undefined;
|
||||
source: MetricsSourceConfigurationProperties | undefined;
|
||||
timeRange: MetricsExplorerTimeOptions;
|
||||
}
|
||||
export const MetricsExplorerCharts = ({
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { encode } from 'rison-node';
|
||||
import uuid from 'uuid';
|
||||
import { set } from '@elastic/safer-lodash-set';
|
||||
import { InfraSourceConfiguration } from '../../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../../common/metrics_sources';
|
||||
import { colorTransformer, Color } from '../../../../../../common/color_palette';
|
||||
import { MetricsExplorerSeries } from '../../../../../../common/http_api/metrics_explorer';
|
||||
import {
|
||||
|
@ -143,7 +143,7 @@ const createTSVBIndexPattern = (alias: string) => {
|
|||
};
|
||||
|
||||
export const createTSVBLink = (
|
||||
source: InfraSourceConfiguration | undefined,
|
||||
source: MetricsSourceConfigurationProperties | undefined,
|
||||
options: MetricsExplorerOptions,
|
||||
series: MetricsExplorerSeries,
|
||||
timeRange: MetricsExplorerTimeOptions,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { useState, useCallback, useContext } from 'react';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import { InfraSourceConfiguration } from '../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources';
|
||||
import {
|
||||
MetricsExplorerMetric,
|
||||
MetricsExplorerAggregation,
|
||||
|
@ -28,7 +28,7 @@ export interface MetricExplorerViewState {
|
|||
}
|
||||
|
||||
export const useMetricsExplorerState = (
|
||||
source: InfraSourceConfiguration,
|
||||
source: MetricsSourceConfigurationProperties,
|
||||
derivedIndexPattern: IIndexPattern,
|
||||
shouldLoadImmediately = true
|
||||
) => {
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
import { MetricsExplorerOptions, MetricsExplorerTimeOptions } from './use_metrics_explorer_options';
|
||||
import { IIndexPattern } from '../../../../../../../../src/plugins/data/public';
|
||||
import { HttpHandler } from 'kibana/public';
|
||||
import { InfraSourceConfiguration } from '../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources';
|
||||
|
||||
const mockedFetch = jest.fn();
|
||||
|
||||
|
@ -38,7 +38,7 @@ const renderUseMetricsExplorerDataHook = () => {
|
|||
return renderHook(
|
||||
(props: {
|
||||
options: MetricsExplorerOptions;
|
||||
source: InfraSourceConfiguration | undefined;
|
||||
source: MetricsSourceConfigurationProperties | undefined;
|
||||
derivedIndexPattern: IIndexPattern;
|
||||
timeRange: MetricsExplorerTimeOptions;
|
||||
afterKey: string | null | Record<string, string | null>;
|
||||
|
|
|
@ -9,7 +9,7 @@ import DateMath from '@elastic/datemath';
|
|||
import { isEqual } from 'lodash';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import { InfraSourceConfiguration } from '../../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../../common/metrics_sources';
|
||||
import {
|
||||
MetricsExplorerResponse,
|
||||
metricsExplorerResponseRT,
|
||||
|
@ -25,7 +25,7 @@ function isSameOptions(current: MetricsExplorerOptions, next: MetricsExplorerOpt
|
|||
|
||||
export function useMetricsExplorerData(
|
||||
options: MetricsExplorerOptions,
|
||||
source: InfraSourceConfiguration | undefined,
|
||||
source: MetricsSourceConfigurationProperties | undefined,
|
||||
derivedIndexPattern: IIndexPattern,
|
||||
timerange: MetricsExplorerTimeOptions,
|
||||
afterKey: string | null | Record<string, string | null>,
|
||||
|
|
|
@ -9,7 +9,7 @@ import { EuiErrorBoundary } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import React, { useEffect } from 'react';
|
||||
import { IIndexPattern } from 'src/plugins/data/public';
|
||||
import { InfraSourceConfiguration } from '../../../../common/http_api/source_api';
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../common/metrics_sources';
|
||||
import { useTrackPageview } from '../../../../../observability/public';
|
||||
import { DocumentTitle } from '../../../components/document_title';
|
||||
import { NoData } from '../../../components/empty_states';
|
||||
|
@ -19,7 +19,7 @@ import { useMetricsExplorerState } from './hooks/use_metric_explorer_state';
|
|||
import { useSavedViewContext } from '../../../containers/saved_view/saved_view';
|
||||
|
||||
interface MetricsExplorerPageProps {
|
||||
source: InfraSourceConfiguration;
|
||||
source: MetricsSourceConfigurationProperties;
|
||||
derivedIndexPattern: IIndexPattern;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import { EuiErrorBoundary } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { SourceConfigurationSettings } from '../../components/source_configuration/source_configuration_settings';
|
||||
import { SourceConfigurationSettings } from './settings/source_configuration_settings';
|
||||
|
||||
export const MetricsSettingsPage = () => {
|
||||
const uiCapabilities = useKibana().services.application?.capabilities;
|
||||
|
|
|
@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
|
||||
import { InputFieldProps } from './input_fields';
|
||||
import { InputFieldProps } from '../../../components/source_configuration/input_fields';
|
||||
|
||||
interface FieldsConfigurationPanelProps {
|
||||
containerFieldProps: InputFieldProps;
|
|
@ -11,16 +11,14 @@ import {
|
|||
createInputFieldProps,
|
||||
createInputRangeFieldProps,
|
||||
validateInputFieldNotEmpty,
|
||||
} from './input_fields';
|
||||
} from '../../../components/source_configuration/input_fields';
|
||||
|
||||
interface FormState {
|
||||
name: string;
|
||||
description: string;
|
||||
metricAlias: string;
|
||||
logAlias: string;
|
||||
containerField: string;
|
||||
hostField: string;
|
||||
messageField: string[];
|
||||
podField: string;
|
||||
tiebreakerField: string;
|
||||
timestampField: string;
|
||||
|
@ -56,16 +54,6 @@ export const useIndicesConfigurationFormState = ({
|
|||
}),
|
||||
[formState.name]
|
||||
);
|
||||
const logAliasFieldProps = useMemo(
|
||||
() =>
|
||||
createInputFieldProps({
|
||||
errors: validateInputFieldNotEmpty(formState.logAlias),
|
||||
name: 'logAlias',
|
||||
onChange: (logAlias) => setFormStateChanges((changes) => ({ ...changes, logAlias })),
|
||||
value: formState.logAlias,
|
||||
}),
|
||||
[formState.logAlias]
|
||||
);
|
||||
const metricAliasFieldProps = useMemo(
|
||||
() =>
|
||||
createInputFieldProps({
|
||||
|
@ -144,7 +132,6 @@ export const useIndicesConfigurationFormState = ({
|
|||
const fieldProps = useMemo(
|
||||
() => ({
|
||||
name: nameFieldProps,
|
||||
logAlias: logAliasFieldProps,
|
||||
metricAlias: metricAliasFieldProps,
|
||||
containerField: containerFieldFieldProps,
|
||||
hostField: hostFieldFieldProps,
|
||||
|
@ -155,7 +142,6 @@ export const useIndicesConfigurationFormState = ({
|
|||
}),
|
||||
[
|
||||
nameFieldProps,
|
||||
logAliasFieldProps,
|
||||
metricAliasFieldProps,
|
||||
containerFieldFieldProps,
|
||||
hostFieldFieldProps,
|
||||
|
@ -193,11 +179,9 @@ export const useIndicesConfigurationFormState = ({
|
|||
const defaultFormState: FormState = {
|
||||
name: '',
|
||||
description: '',
|
||||
logAlias: '',
|
||||
metricAlias: '',
|
||||
containerField: '',
|
||||
hostField: '',
|
||||
messageField: [],
|
||||
podField: '',
|
||||
tiebreakerField: '',
|
||||
timestampField: '',
|
|
@ -17,8 +17,8 @@ import {
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React from 'react';
|
||||
|
||||
import { METRICS_INDEX_PATTERN } from '../../../common/constants';
|
||||
import { InputFieldProps } from './input_fields';
|
||||
import { METRICS_INDEX_PATTERN } from '../../../../common/constants';
|
||||
import { InputFieldProps } from '../../../components/source_configuration/input_fields';
|
||||
|
||||
interface IndicesConfigurationPanelProps {
|
||||
isLoading: boolean;
|
|
@ -13,7 +13,7 @@ import { EuiDescribedFormGroup } from '@elastic/eui';
|
|||
import { EuiForm } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { InputRangeFieldProps } from './input_fields';
|
||||
import { InputRangeFieldProps } from '../../../components/source_configuration/input_fields';
|
||||
|
||||
interface MLConfigurationPanelProps {
|
||||
isLoading: boolean;
|
|
@ -6,12 +6,12 @@
|
|||
*/
|
||||
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { InfraSourceConfiguration } from '../../../common/http_api/source_api';
|
||||
|
||||
import { MetricsSourceConfigurationProperties } from '../../../../common/metrics_sources';
|
||||
import { useIndicesConfigurationFormState } from './indices_configuration_form_state';
|
||||
import { useLogColumnsConfigurationFormState } from './log_columns_configuration_form_state';
|
||||
|
||||
export const useSourceConfigurationFormState = (configuration?: InfraSourceConfiguration) => {
|
||||
export const useSourceConfigurationFormState = (
|
||||
configuration?: MetricsSourceConfigurationProperties
|
||||
) => {
|
||||
const indicesConfigurationFormState = useIndicesConfigurationFormState({
|
||||
initialFormState: useMemo(
|
||||
() =>
|
||||
|
@ -19,11 +19,9 @@ export const useSourceConfigurationFormState = (configuration?: InfraSourceConfi
|
|||
? {
|
||||
name: configuration.name,
|
||||
description: configuration.description,
|
||||
logAlias: configuration.logAlias,
|
||||
metricAlias: configuration.metricAlias,
|
||||
containerField: configuration.fields.container,
|
||||
hostField: configuration.fields.host,
|
||||
messageField: configuration.fields.message,
|
||||
podField: configuration.fields.pod,
|
||||
tiebreakerField: configuration.fields.tiebreaker,
|
||||
timestampField: configuration.fields.timestamp,
|
||||
|
@ -34,43 +32,26 @@ export const useSourceConfigurationFormState = (configuration?: InfraSourceConfi
|
|||
),
|
||||
});
|
||||
|
||||
const logColumnsConfigurationFormState = useLogColumnsConfigurationFormState({
|
||||
initialFormState: useMemo(
|
||||
() =>
|
||||
configuration
|
||||
? {
|
||||
logColumns: configuration.logColumns,
|
||||
}
|
||||
: undefined,
|
||||
[configuration]
|
||||
),
|
||||
});
|
||||
|
||||
const errors = useMemo(
|
||||
() => [...indicesConfigurationFormState.errors, ...logColumnsConfigurationFormState.errors],
|
||||
[indicesConfigurationFormState.errors, logColumnsConfigurationFormState.errors]
|
||||
);
|
||||
const errors = useMemo(() => [...indicesConfigurationFormState.errors], [
|
||||
indicesConfigurationFormState.errors,
|
||||
]);
|
||||
|
||||
const resetForm = useCallback(() => {
|
||||
indicesConfigurationFormState.resetForm();
|
||||
logColumnsConfigurationFormState.resetForm();
|
||||
}, [indicesConfigurationFormState, logColumnsConfigurationFormState]);
|
||||
}, [indicesConfigurationFormState]);
|
||||
|
||||
const isFormDirty = useMemo(
|
||||
() => indicesConfigurationFormState.isFormDirty || logColumnsConfigurationFormState.isFormDirty,
|
||||
[indicesConfigurationFormState.isFormDirty, logColumnsConfigurationFormState.isFormDirty]
|
||||
);
|
||||
const isFormDirty = useMemo(() => indicesConfigurationFormState.isFormDirty, [
|
||||
indicesConfigurationFormState.isFormDirty,
|
||||
]);
|
||||
|
||||
const isFormValid = useMemo(
|
||||
() => indicesConfigurationFormState.isFormValid && logColumnsConfigurationFormState.isFormValid,
|
||||
[indicesConfigurationFormState.isFormValid, logColumnsConfigurationFormState.isFormValid]
|
||||
);
|
||||
const isFormValid = useMemo(() => indicesConfigurationFormState.isFormValid, [
|
||||
indicesConfigurationFormState.isFormValid,
|
||||
]);
|
||||
|
||||
const formState = useMemo(
|
||||
() => ({
|
||||
name: indicesConfigurationFormState.formState.name,
|
||||
description: indicesConfigurationFormState.formState.description,
|
||||
logAlias: indicesConfigurationFormState.formState.logAlias,
|
||||
metricAlias: indicesConfigurationFormState.formState.metricAlias,
|
||||
fields: {
|
||||
container: indicesConfigurationFormState.formState.containerField,
|
||||
|
@ -79,17 +60,15 @@ export const useSourceConfigurationFormState = (configuration?: InfraSourceConfi
|
|||
tiebreaker: indicesConfigurationFormState.formState.tiebreakerField,
|
||||
timestamp: indicesConfigurationFormState.formState.timestampField,
|
||||
},
|
||||
logColumns: logColumnsConfigurationFormState.formState.logColumns,
|
||||
anomalyThreshold: indicesConfigurationFormState.formState.anomalyThreshold,
|
||||
}),
|
||||
[indicesConfigurationFormState.formState, logColumnsConfigurationFormState.formState]
|
||||
[indicesConfigurationFormState.formState]
|
||||
);
|
||||
|
||||
const formStateChanges = useMemo(
|
||||
() => ({
|
||||
name: indicesConfigurationFormState.formStateChanges.name,
|
||||
description: indicesConfigurationFormState.formStateChanges.description,
|
||||
logAlias: indicesConfigurationFormState.formStateChanges.logAlias,
|
||||
metricAlias: indicesConfigurationFormState.formStateChanges.metricAlias,
|
||||
fields: {
|
||||
container: indicesConfigurationFormState.formStateChanges.containerField,
|
||||
|
@ -98,25 +77,18 @@ export const useSourceConfigurationFormState = (configuration?: InfraSourceConfi
|
|||
tiebreaker: indicesConfigurationFormState.formStateChanges.tiebreakerField,
|
||||
timestamp: indicesConfigurationFormState.formStateChanges.timestampField,
|
||||
},
|
||||
logColumns: logColumnsConfigurationFormState.formStateChanges.logColumns,
|
||||
anomalyThreshold: indicesConfigurationFormState.formStateChanges.anomalyThreshold,
|
||||
}),
|
||||
[
|
||||
indicesConfigurationFormState.formStateChanges,
|
||||
logColumnsConfigurationFormState.formStateChanges,
|
||||
]
|
||||
[indicesConfigurationFormState.formStateChanges]
|
||||
);
|
||||
|
||||
return {
|
||||
addLogColumn: logColumnsConfigurationFormState.addLogColumn,
|
||||
moveLogColumn: logColumnsConfigurationFormState.moveLogColumn,
|
||||
errors,
|
||||
formState,
|
||||
formStateChanges,
|
||||
isFormDirty,
|
||||
isFormValid,
|
||||
indicesConfigurationProps: indicesConfigurationFormState.fieldProps,
|
||||
logColumnConfigurationProps: logColumnsConfigurationFormState.logColumnConfigurationProps,
|
||||
resetForm,
|
||||
};
|
||||
};
|
|
@ -19,15 +19,15 @@ import { i18n } from '@kbn/i18n';
|
|||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { useCallback, useContext, useMemo } from 'react';
|
||||
|
||||
import { Source } from '../../containers/source';
|
||||
import { Source } from '../../../containers/metrics_source';
|
||||
import { FieldsConfigurationPanel } from './fields_configuration_panel';
|
||||
import { IndicesConfigurationPanel } from './indices_configuration_panel';
|
||||
import { NameConfigurationPanel } from './name_configuration_panel';
|
||||
import { NameConfigurationPanel } from '../../../components/source_configuration/name_configuration_panel';
|
||||
import { useSourceConfigurationFormState } from './source_configuration_form_state';
|
||||
import { SourceLoadingPage } from '../source_loading_page';
|
||||
import { Prompt } from '../../utils/navigation_warning_prompt';
|
||||
import { SourceLoadingPage } from '../../../components/source_loading_page';
|
||||
import { Prompt } from '../../../utils/navigation_warning_prompt';
|
||||
import { MLConfigurationPanel } from './ml_configuration_panel';
|
||||
import { useInfraMLCapabilitiesContext } from '../../containers/ml/infra_ml_capabilities';
|
||||
import { useInfraMLCapabilitiesContext } from '../../../containers/ml/infra_ml_capabilities';
|
||||
|
||||
interface SourceConfigurationSettingsProps {
|
||||
shouldAllowEdit: boolean;
|
|
@ -6,14 +6,14 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
InfraSavedSourceConfigurationColumn,
|
||||
InfraSavedSourceConfigurationFields,
|
||||
InfraSourceConfigurationColumn,
|
||||
InfraSourceConfigurationFieldColumn,
|
||||
InfraSourceConfigurationMessageColumn,
|
||||
InfraSourceConfigurationTimestampColumn,
|
||||
} from '../../common/http_api/source_api';
|
||||
} from '../../common/source_configuration/source_configuration';
|
||||
|
||||
export type LogColumnConfiguration = InfraSavedSourceConfigurationColumn;
|
||||
export type FieldLogColumnConfiguration = InfraSavedSourceConfigurationFields;
|
||||
export type LogColumnConfiguration = InfraSourceConfigurationColumn;
|
||||
export type FieldLogColumnConfiguration = InfraSourceConfigurationFieldColumn;
|
||||
export type MessageLogColumnConfiguration = InfraSourceConfigurationMessageColumn;
|
||||
export type TimestampLogColumnConfiguration = InfraSourceConfigurationTimestampColumn;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import {
|
|||
} from './routes/log_entries';
|
||||
import { initInventoryMetaRoute } from './routes/inventory_metadata';
|
||||
import { initLogSourceConfigurationRoutes, initLogSourceStatusRoutes } from './routes/log_sources';
|
||||
import { initSourceRoute } from './routes/source';
|
||||
import { initMetricsSourceConfigurationRoutes } from './routes/metrics_sources';
|
||||
import { initOverviewRoute } from './routes/overview';
|
||||
import { initAlertPreviewRoute } from './routes/alerting';
|
||||
import { initGetLogAlertsChartPreviewDataRoute } from './routes/log_alerts';
|
||||
|
@ -50,7 +50,7 @@ export const initInfraServer = (libs: InfraBackendLibs) => {
|
|||
initGetHostsAnomaliesRoute(libs);
|
||||
initSnapshotRoute(libs);
|
||||
initNodeDetailsRoute(libs);
|
||||
initSourceRoute(libs);
|
||||
initMetricsSourceConfigurationRoutes(libs);
|
||||
initValidateLogAnalysisDatasetsRoute(libs);
|
||||
initValidateLogAnalysisIndicesRoute(libs);
|
||||
initGetLogEntryExamplesRoute(libs);
|
||||
|
|
|
@ -34,7 +34,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter {
|
|||
options: InfraMetricsRequestOptions,
|
||||
rawRequest: KibanaRequest
|
||||
): Promise<NodeDetailsMetricData[]> {
|
||||
const indexPattern = `${options.sourceConfiguration.metricAlias},${options.sourceConfiguration.logAlias}`;
|
||||
const indexPattern = `${options.sourceConfiguration.metricAlias}`;
|
||||
const fields = findInventoryFields(options.nodeType, options.sourceConfiguration.fields);
|
||||
const nodeField = fields.id;
|
||||
|
||||
|
@ -112,7 +112,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter {
|
|||
);
|
||||
}
|
||||
|
||||
const indexPattern = `${options.sourceConfiguration.metricAlias},${options.sourceConfiguration.logAlias}`;
|
||||
const indexPattern = `${options.sourceConfiguration.metricAlias}`;
|
||||
const timerange = {
|
||||
min: options.timerange.from,
|
||||
max: options.timerange.to,
|
||||
|
@ -132,7 +132,7 @@ export class KibanaMetricsAdapter implements InfraMetricsAdapter {
|
|||
const calculatedInterval = await calculateMetricInterval(
|
||||
client,
|
||||
{
|
||||
indexPattern: `${options.sourceConfiguration.logAlias},${options.sourceConfiguration.metricAlias}`,
|
||||
indexPattern: `${options.sourceConfiguration.metricAlias}`,
|
||||
timestampField: options.sourceConfiguration.fields.timestamp,
|
||||
timerange: options.timerange,
|
||||
},
|
||||
|
|
|
@ -23,6 +23,7 @@ import { InfraTimerangeInput, SnapshotRequest } from '../../../../common/http_ap
|
|||
import { InfraSource } from '../../sources';
|
||||
import { UNGROUPED_FACTORY_KEY } from '../common/utils';
|
||||
import { getNodes } from '../../../routes/snapshot/lib/get_nodes';
|
||||
import { LogQueryFields } from '../../../services/log_queries/get_log_query_fields';
|
||||
|
||||
type ConditionResult = InventoryMetricConditions & {
|
||||
shouldFire: boolean[];
|
||||
|
@ -36,6 +37,7 @@ export const evaluateCondition = async (
|
|||
condition: InventoryMetricConditions,
|
||||
nodeType: InventoryItemType,
|
||||
source: InfraSource,
|
||||
logQueryFields: LogQueryFields,
|
||||
esClient: ElasticsearchClient,
|
||||
filterQuery?: string,
|
||||
lookbackSize?: number
|
||||
|
@ -58,6 +60,7 @@ export const evaluateCondition = async (
|
|||
metric,
|
||||
timerange,
|
||||
source,
|
||||
logQueryFields,
|
||||
filterQuery,
|
||||
customMetric
|
||||
);
|
||||
|
@ -101,6 +104,7 @@ const getData = async (
|
|||
metric: SnapshotMetricType,
|
||||
timerange: InfraTimerangeInput,
|
||||
source: InfraSource,
|
||||
logQueryFields: LogQueryFields,
|
||||
filterQuery?: string,
|
||||
customMetric?: SnapshotCustomMetricInput
|
||||
) => {
|
||||
|
@ -124,7 +128,7 @@ const getData = async (
|
|||
includeTimeseries: Boolean(timerange.lookbackSize),
|
||||
};
|
||||
try {
|
||||
const { nodes } = await getNodes(client, snapshotRequest, source);
|
||||
const { nodes } = await getNodes(client, snapshotRequest, source, logQueryFields);
|
||||
|
||||
if (!nodes.length) return { [UNGROUPED_FACTORY_KEY]: null }; // No Data state
|
||||
|
||||
|
|
|
@ -68,12 +68,18 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
|
|||
sourceId || 'default'
|
||||
);
|
||||
|
||||
const logQueryFields = await libs.getLogQueryFields(
|
||||
sourceId || 'default',
|
||||
services.savedObjectsClient
|
||||
);
|
||||
|
||||
const results = await Promise.all(
|
||||
criteria.map((c) =>
|
||||
evaluateCondition(
|
||||
c,
|
||||
nodeType,
|
||||
source,
|
||||
logQueryFields,
|
||||
services.scopedClusterClient.asCurrentUser,
|
||||
filterQuery
|
||||
)
|
||||
|
|
|
@ -14,10 +14,11 @@ import {
|
|||
isTooManyBucketsPreviewException,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
import { ElasticsearchClient } from '../../../../../../../src/core/server';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { InfraSource } from '../../../../common/source_configuration/source_configuration';
|
||||
import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
|
||||
import { InventoryItemType } from '../../../../common/inventory_models/types';
|
||||
import { evaluateCondition } from './evaluate_condition';
|
||||
import { LogQueryFields } from '../../../services/log_queries/get_log_query_fields';
|
||||
|
||||
interface InventoryMetricThresholdParams {
|
||||
criteria: InventoryMetricConditions[];
|
||||
|
@ -30,6 +31,7 @@ interface PreviewInventoryMetricThresholdAlertParams {
|
|||
esClient: ElasticsearchClient;
|
||||
params: InventoryMetricThresholdParams;
|
||||
source: InfraSource;
|
||||
logQueryFields: LogQueryFields;
|
||||
lookback: Unit;
|
||||
alertInterval: string;
|
||||
alertThrottle: string;
|
||||
|
@ -43,6 +45,7 @@ export const previewInventoryMetricThresholdAlert: (
|
|||
esClient,
|
||||
params,
|
||||
source,
|
||||
logQueryFields,
|
||||
lookback,
|
||||
alertInterval,
|
||||
alertThrottle,
|
||||
|
@ -68,7 +71,7 @@ export const previewInventoryMetricThresholdAlert: (
|
|||
try {
|
||||
const results = await Promise.all(
|
||||
criteria.map((c) =>
|
||||
evaluateCondition(c, nodeType, source, esClient, filterQuery, lookbackSize)
|
||||
evaluateCondition(c, nodeType, source, logQueryFields, esClient, filterQuery, lookbackSize)
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
isTooManyBucketsPreviewException,
|
||||
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||
} from '../../../../../common/alerting/metrics';
|
||||
import { InfraSource } from '../../../../../common/http_api/source_api';
|
||||
import { InfraSource } from '../../../../../common/source_configuration/source_configuration';
|
||||
import { InfraDatabaseSearchResponse } from '../../../adapters/framework/adapter_types';
|
||||
import { createAfterKeyHandler } from '../../../../utils/create_afterkey_handler';
|
||||
import { getAllCompositeData } from '../../../../utils/get_all_composite_data';
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
isTooManyBucketsPreviewException,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
import { ElasticsearchClient } from '../../../../../../../src/core/server';
|
||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||
import { InfraSource } from '../../../../common/source_configuration/source_configuration';
|
||||
import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
|
||||
import { PreviewResult } from '../common/types';
|
||||
import { MetricExpressionParams } from './types';
|
||||
|
|
|
@ -18,21 +18,16 @@ export class InfraFieldsDomain {
|
|||
public async getFields(
|
||||
requestContext: InfraPluginRequestHandlerContext,
|
||||
sourceId: string,
|
||||
indexType: 'LOGS' | 'METRICS' | 'ANY'
|
||||
indexType: 'LOGS' | 'METRICS'
|
||||
): Promise<InfraSourceIndexField[]> {
|
||||
const { configuration } = await this.libs.sources.getSourceConfiguration(
|
||||
requestContext.core.savedObjects.client,
|
||||
sourceId
|
||||
);
|
||||
const includeMetricIndices = ['ANY', 'METRICS'].includes(indexType);
|
||||
const includeLogIndices = ['ANY', 'LOGS'].includes(indexType);
|
||||
|
||||
const fields = await this.adapter.getIndexFields(
|
||||
requestContext,
|
||||
[
|
||||
...(includeMetricIndices ? [configuration.metricAlias] : []),
|
||||
...(includeLogIndices ? [configuration.logAlias] : []),
|
||||
].join(',')
|
||||
indexType === 'LOGS' ? configuration.logAlias : configuration.metricAlias
|
||||
);
|
||||
|
||||
return fields;
|
||||
|
|
|
@ -17,7 +17,7 @@ import { LogColumn, LogEntryCursor, LogEntry } from '../../../../common/log_entr
|
|||
import {
|
||||
InfraSourceConfiguration,
|
||||
InfraSources,
|
||||
SavedSourceConfigurationFieldColumnRuntimeType,
|
||||
SourceConfigurationFieldColumnRuntimeType,
|
||||
} from '../../sources';
|
||||
import { getBuiltinRules } from '../../../services/log_entries/message/builtin_rules';
|
||||
import {
|
||||
|
@ -349,7 +349,7 @@ const getRequiredFields = (
|
|||
): string[] => {
|
||||
const fieldsFromCustomColumns = configuration.logColumns.reduce<string[]>(
|
||||
(accumulatedFields, logColumn) => {
|
||||
if (SavedSourceConfigurationFieldColumnRuntimeType.is(logColumn)) {
|
||||
if (SourceConfigurationFieldColumnRuntimeType.is(logColumn)) {
|
||||
return [...accumulatedFields, logColumn.fieldColumn.field];
|
||||
}
|
||||
return accumulatedFields;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { InfraSourceConfiguration } from '../../common/http_api/source_api';
|
||||
import { InfraSourceConfiguration } from '../../common/source_configuration/source_configuration';
|
||||
import { InfraFieldsDomain } from './domains/fields_domain';
|
||||
import { InfraLogEntriesDomain } from './domains/log_entries_domain';
|
||||
import { InfraMetricsDomain } from './domains/metrics_domain';
|
||||
|
@ -13,6 +13,7 @@ import { InfraSources } from './sources';
|
|||
import { InfraSourceStatus } from './source_status';
|
||||
import { InfraConfig } from '../plugin';
|
||||
import { KibanaFramework } from './adapters/framework/kibana_framework_adapter';
|
||||
import { GetLogQueryFields } from '../services/log_queries/get_log_query_fields';
|
||||
|
||||
export interface InfraDomainLibs {
|
||||
fields: InfraFieldsDomain;
|
||||
|
@ -25,6 +26,7 @@ export interface InfraBackendLibs extends InfraDomainLibs {
|
|||
framework: KibanaFramework;
|
||||
sources: InfraSources;
|
||||
sourceStatus: InfraSourceStatus;
|
||||
getLogQueryFields: GetLogQueryFields;
|
||||
}
|
||||
|
||||
export interface InfraConfiguration {
|
||||
|
|
|
@ -120,5 +120,5 @@ export const query = async (
|
|||
ThrowReporter.report(HistogramResponseRT.decode(response.aggregations));
|
||||
}
|
||||
|
||||
throw new Error('Elasticsearch responsed with an unrecoginzed format.');
|
||||
throw new Error('Elasticsearch responded with an unrecognized format.');
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
LOGS_INDEX_PATTERN,
|
||||
TIMESTAMP_FIELD,
|
||||
} from '../../../common/constants';
|
||||
import { InfraSourceConfiguration } from '../../../common/http_api/source_api';
|
||||
import { InfraSourceConfiguration } from '../../../common/source_configuration/source_configuration';
|
||||
|
||||
export const defaultSourceConfiguration: InfraSourceConfiguration = {
|
||||
name: 'Default',
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
export * from './defaults';
|
||||
export { infraSourceConfigurationSavedObjectType } from './saved_object_type';
|
||||
export * from './sources';
|
||||
export * from '../../../common/http_api/source_api';
|
||||
export * from '../../../common/source_configuration/source_configuration';
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { SavedObjectMigrationFn } from 'src/core/server';
|
||||
import { InfraSourceConfiguration } from '../../../../common/http_api/source_api';
|
||||
import { InfraSourceConfiguration } from '../../../../common/source_configuration/source_configuration';
|
||||
|
||||
export const addNewIndexingStrategyIndexNames: SavedObjectMigrationFn<
|
||||
InfraSourceConfiguration,
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
SourceConfigurationSavedObjectRuntimeType,
|
||||
StaticSourceConfigurationRuntimeType,
|
||||
InfraSource,
|
||||
} from '../../../common/http_api/source_api';
|
||||
} from '../../../common/source_configuration/source_configuration';
|
||||
import { InfraConfig } from '../../../server';
|
||||
|
||||
interface Libs {
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Server } from '@hapi/hapi';
|
|||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { CoreSetup, PluginInitializerContext, Plugin } from 'src/core/server';
|
||||
import { InfraStaticSourceConfiguration } from '../common/http_api/source_api';
|
||||
import { InfraStaticSourceConfiguration } from '../common/source_configuration/source_configuration';
|
||||
import { inventoryViewSavedObjectType } from '../common/saved_objects/inventory_view';
|
||||
import { metricsExplorerViewSavedObjectType } from '../common/saved_objects/metrics_explorer_view';
|
||||
import { LOGS_FEATURE, METRICS_FEATURE } from './features';
|
||||
|
@ -30,6 +30,7 @@ import { InfraSourceStatus } from './lib/source_status';
|
|||
import { LogEntriesService } from './services/log_entries';
|
||||
import { InfraPluginRequestHandlerContext } from './types';
|
||||
import { UsageCollector } from './usage/usage_collector';
|
||||
import { createGetLogQueryFields } from './services/log_queries/get_log_query_fields';
|
||||
|
||||
export const config = {
|
||||
schema: schema.object({
|
||||
|
@ -123,6 +124,7 @@ export class InfraServerPlugin implements Plugin<InfraPluginSetup> {
|
|||
sources,
|
||||
sourceStatus,
|
||||
...domainLibs,
|
||||
getLogQueryFields: createGetLogQueryFields(sources),
|
||||
};
|
||||
|
||||
plugins.features.registerKibanaFeature(METRICS_FEATURE);
|
||||
|
|
|
@ -25,7 +25,11 @@ import { previewMetricAnomalyAlert } from '../../lib/alerting/metric_anomaly/pre
|
|||
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||
import { assertHasInfraMlPlugins } from '../../utils/request_context';
|
||||
|
||||
export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs) => {
|
||||
export const initAlertPreviewRoute = ({
|
||||
framework,
|
||||
sources,
|
||||
getLogQueryFields,
|
||||
}: InfraBackendLibs) => {
|
||||
framework.registerRoute(
|
||||
{
|
||||
method: 'post',
|
||||
|
@ -77,6 +81,10 @@ export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs)
|
|||
});
|
||||
}
|
||||
case METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID: {
|
||||
const logQueryFields = await getLogQueryFields(
|
||||
sourceId || 'default',
|
||||
requestContext.core.savedObjects.client
|
||||
);
|
||||
const {
|
||||
nodeType,
|
||||
criteria,
|
||||
|
@ -87,6 +95,7 @@ export const initAlertPreviewRoute = ({ framework, sources }: InfraBackendLibs)
|
|||
params: { criteria, filterQuery, nodeType },
|
||||
lookback,
|
||||
source,
|
||||
logQueryFields,
|
||||
alertInterval,
|
||||
alertThrottle,
|
||||
alertNotifyWhen,
|
||||
|
|
|
@ -8,63 +8,49 @@
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import Boom from '@hapi/boom';
|
||||
import { createValidationFunction } from '../../../common/runtime_types';
|
||||
import {
|
||||
InfraSourceStatus,
|
||||
SavedSourceConfigurationRuntimeType,
|
||||
SourceResponseRuntimeType,
|
||||
} from '../../../common/http_api/source_api';
|
||||
import { InfraBackendLibs } from '../../lib/infra_types';
|
||||
import { hasData } from '../../lib/sources/has_data';
|
||||
import { createSearchClient } from '../../lib/create_search_client';
|
||||
import { AnomalyThresholdRangeError } from '../../lib/sources/errors';
|
||||
import {
|
||||
partialMetricsSourceConfigurationPropertiesRT,
|
||||
metricsSourceConfigurationResponseRT,
|
||||
MetricsSourceStatus,
|
||||
} from '../../../common/metrics_sources';
|
||||
|
||||
const typeToInfraIndexType = (value: string | undefined) => {
|
||||
switch (value) {
|
||||
case 'metrics':
|
||||
return 'METRICS';
|
||||
case 'logs':
|
||||
return 'LOGS';
|
||||
default:
|
||||
return 'ANY';
|
||||
}
|
||||
};
|
||||
|
||||
export const initSourceRoute = (libs: InfraBackendLibs) => {
|
||||
export const initMetricsSourceConfigurationRoutes = (libs: InfraBackendLibs) => {
|
||||
const { framework } = libs;
|
||||
|
||||
framework.registerRoute(
|
||||
{
|
||||
method: 'get',
|
||||
path: '/api/metrics/source/{sourceId}/{type?}',
|
||||
path: '/api/metrics/source/{sourceId}',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
sourceId: schema.string(),
|
||||
type: schema.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const { type, sourceId } = request.params;
|
||||
const { sourceId } = request.params;
|
||||
|
||||
const [source, logIndexStatus, metricIndicesExist, indexFields] = await Promise.all([
|
||||
const [source, metricIndicesExist, indexFields] = await Promise.all([
|
||||
libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId),
|
||||
libs.sourceStatus.getLogIndexStatus(requestContext, sourceId),
|
||||
libs.sourceStatus.hasMetricIndices(requestContext, sourceId),
|
||||
libs.fields.getFields(requestContext, sourceId, typeToInfraIndexType(type)),
|
||||
libs.fields.getFields(requestContext, sourceId, 'METRICS'),
|
||||
]);
|
||||
|
||||
if (!source) {
|
||||
return response.notFound();
|
||||
}
|
||||
|
||||
const status: InfraSourceStatus = {
|
||||
logIndicesExist: logIndexStatus !== 'missing',
|
||||
const status: MetricsSourceStatus = {
|
||||
metricIndicesExist,
|
||||
indexFields,
|
||||
};
|
||||
|
||||
return response.ok({
|
||||
body: SourceResponseRuntimeType.encode({ source: { ...source, status } }),
|
||||
body: metricsSourceConfigurationResponseRT.encode({ source: { ...source, status } }),
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -77,7 +63,7 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
|
|||
params: schema.object({
|
||||
sourceId: schema.string(),
|
||||
}),
|
||||
body: createValidationFunction(SavedSourceConfigurationRuntimeType),
|
||||
body: createValidationFunction(partialMetricsSourceConfigurationPropertiesRT),
|
||||
},
|
||||
},
|
||||
framework.router.handleLegacyErrors(async (requestContext, request, response) => {
|
||||
|
@ -110,20 +96,18 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
|
|||
patchedSourceConfigurationProperties
|
||||
));
|
||||
|
||||
const [logIndexStatus, metricIndicesExist, indexFields] = await Promise.all([
|
||||
libs.sourceStatus.getLogIndexStatus(requestContext, sourceId),
|
||||
const [metricIndicesExist, indexFields] = await Promise.all([
|
||||
libs.sourceStatus.hasMetricIndices(requestContext, sourceId),
|
||||
libs.fields.getFields(requestContext, sourceId, typeToInfraIndexType('metrics')),
|
||||
libs.fields.getFields(requestContext, sourceId, 'METRICS'),
|
||||
]);
|
||||
|
||||
const status: InfraSourceStatus = {
|
||||
logIndicesExist: logIndexStatus !== 'missing',
|
||||
const status: MetricsSourceStatus = {
|
||||
metricIndicesExist,
|
||||
indexFields,
|
||||
};
|
||||
|
||||
return response.ok({
|
||||
body: SourceResponseRuntimeType.encode({
|
||||
body: metricsSourceConfigurationResponseRT.encode({
|
||||
source: { ...patchedSourceConfiguration, status },
|
||||
}),
|
||||
});
|
||||
|
@ -154,25 +138,23 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
|
|||
framework.registerRoute(
|
||||
{
|
||||
method: 'get',
|
||||
path: '/api/metrics/source/{sourceId}/{type}/hasData',
|
||||
path: '/api/metrics/source/{sourceId}/hasData',
|
||||
validate: {
|
||||
params: schema.object({
|
||||
sourceId: schema.string(),
|
||||
type: schema.string(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (requestContext, request, response) => {
|
||||
const { type, sourceId } = request.params;
|
||||
const { sourceId } = request.params;
|
||||
|
||||
const client = createSearchClient(requestContext, framework);
|
||||
const source = await libs.sources.getSourceConfiguration(
|
||||
requestContext.core.savedObjects.client,
|
||||
sourceId
|
||||
);
|
||||
const indexPattern =
|
||||
type === 'metrics' ? source.configuration.metricAlias : source.configuration.logAlias;
|
||||
const results = await hasData(indexPattern, client);
|
||||
|
||||
const results = await hasData(source.configuration.metricAlias, client);
|
||||
|
||||
return response.ok({
|
||||
body: { hasData: results },
|
|
@ -41,9 +41,15 @@ export const initSnapshotRoute = (libs: InfraBackendLibs) => {
|
|||
snapshotRequest.sourceId
|
||||
);
|
||||
|
||||
const logQueryFields = await libs.getLogQueryFields(
|
||||
snapshotRequest.sourceId,
|
||||
requestContext.core.savedObjects.client
|
||||
);
|
||||
|
||||
UsageCollector.countNode(snapshotRequest.nodeType);
|
||||
const client = createSearchClient(requestContext, framework);
|
||||
const snapshotResponse = await getNodes(client, snapshotRequest, source);
|
||||
|
||||
const snapshotResponse = await getNodes(client, snapshotRequest, source, logQueryFields);
|
||||
|
||||
return response.ok({
|
||||
body: SnapshotNodeResponseRT.encode(snapshotResponse),
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SnapshotRequest } from '../../../../common/http_api';
|
||||
import { InfraSource } from '../../../lib/sources';
|
||||
|
||||
export const calculateIndexPatterBasedOnMetrics = (
|
||||
options: SnapshotRequest,
|
||||
source: InfraSource
|
||||
) => {
|
||||
const { metrics } = options;
|
||||
if (metrics.every((m) => m.type === 'logRate')) {
|
||||
return source.configuration.logAlias;
|
||||
}
|
||||
if (metrics.some((m) => m.type === 'logRate')) {
|
||||
return `${source.configuration.logAlias},${source.configuration.metricAlias}`;
|
||||
}
|
||||
return source.configuration.metricAlias;
|
||||
};
|
|
@ -12,16 +12,24 @@ import { transformRequestToMetricsAPIRequest } from './transform_request_to_metr
|
|||
import { queryAllData } from './query_all_data';
|
||||
import { transformMetricsApiResponseToSnapshotResponse } from './trasform_metrics_ui_response';
|
||||
import { copyMissingMetrics } from './copy_missing_metrics';
|
||||
import { LogQueryFields } from '../../../services/log_queries/get_log_query_fields';
|
||||
|
||||
export const getNodes = async (
|
||||
export interface SourceOverrides {
|
||||
indexPattern: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
const transformAndQueryData = async (
|
||||
client: ESSearchClient,
|
||||
snapshotRequest: SnapshotRequest,
|
||||
source: InfraSource
|
||||
source: InfraSource,
|
||||
sourceOverrides?: SourceOverrides
|
||||
) => {
|
||||
const metricsApiRequest = await transformRequestToMetricsAPIRequest(
|
||||
client,
|
||||
source,
|
||||
snapshotRequest
|
||||
snapshotRequest,
|
||||
sourceOverrides
|
||||
);
|
||||
const metricsApiResponse = await queryAllData(client, metricsApiRequest);
|
||||
const snapshotResponse = transformMetricsApiResponseToSnapshotResponse(
|
||||
|
@ -32,3 +40,59 @@ export const getNodes = async (
|
|||
);
|
||||
return copyMissingMetrics(snapshotResponse);
|
||||
};
|
||||
|
||||
export const getNodes = async (
|
||||
client: ESSearchClient,
|
||||
snapshotRequest: SnapshotRequest,
|
||||
source: InfraSource,
|
||||
logQueryFields: LogQueryFields
|
||||
) => {
|
||||
let nodes;
|
||||
|
||||
if (snapshotRequest.metrics.find((metric) => metric.type === 'logRate')) {
|
||||
// *Only* the log rate metric has been requested
|
||||
if (snapshotRequest.metrics.length === 1) {
|
||||
nodes = await transformAndQueryData(client, snapshotRequest, source, logQueryFields);
|
||||
} else {
|
||||
// A scenario whereby a single host might be shipping metrics and logs.
|
||||
const metricsWithoutLogsMetrics = snapshotRequest.metrics.filter(
|
||||
(metric) => metric.type !== 'logRate'
|
||||
);
|
||||
const nodesWithoutLogsMetrics = await transformAndQueryData(
|
||||
client,
|
||||
{ ...snapshotRequest, metrics: metricsWithoutLogsMetrics },
|
||||
source
|
||||
);
|
||||
const logRateNodes = await transformAndQueryData(
|
||||
client,
|
||||
{ ...snapshotRequest, metrics: [{ type: 'logRate' }] },
|
||||
source,
|
||||
logQueryFields
|
||||
);
|
||||
// Merge nodes where possible - e.g. a single host is shipping metrics and logs
|
||||
const mergedNodes = nodesWithoutLogsMetrics.nodes.map((node) => {
|
||||
const logRateNode = logRateNodes.nodes.find(
|
||||
(_logRateNode) => node.name === _logRateNode.name
|
||||
);
|
||||
if (logRateNode) {
|
||||
// Remove this from the "leftovers"
|
||||
logRateNodes.nodes.filter((_node) => _node.name !== logRateNode.name);
|
||||
}
|
||||
return logRateNode
|
||||
? {
|
||||
...node,
|
||||
metrics: [...node.metrics, ...logRateNode.metrics],
|
||||
}
|
||||
: node;
|
||||
});
|
||||
nodes = {
|
||||
...nodesWithoutLogsMetrics,
|
||||
nodes: [...mergedNodes, ...logRateNodes.nodes],
|
||||
};
|
||||
}
|
||||
} else {
|
||||
nodes = await transformAndQueryData(client, snapshotRequest, source);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
};
|
||||
|
|
|
@ -12,13 +12,14 @@ import { InfraSource } from '../../../lib/sources';
|
|||
import { createTimeRangeWithInterval } from './create_timerange_with_interval';
|
||||
import { parseFilterQuery } from '../../../utils/serialized_query';
|
||||
import { transformSnapshotMetricsToMetricsAPIMetrics } from './transform_snapshot_metrics_to_metrics_api_metrics';
|
||||
import { calculateIndexPatterBasedOnMetrics } from './calculate_index_pattern_based_on_metrics';
|
||||
import { META_KEY } from './constants';
|
||||
import { SourceOverrides } from './get_nodes';
|
||||
|
||||
export const transformRequestToMetricsAPIRequest = async (
|
||||
client: ESSearchClient,
|
||||
source: InfraSource,
|
||||
snapshotRequest: SnapshotRequest
|
||||
snapshotRequest: SnapshotRequest,
|
||||
sourceOverrides?: SourceOverrides
|
||||
): Promise<MetricsAPIRequest> => {
|
||||
const timeRangeWithIntervalApplied = await createTimeRangeWithInterval(client, {
|
||||
...snapshotRequest,
|
||||
|
@ -27,9 +28,9 @@ export const transformRequestToMetricsAPIRequest = async (
|
|||
});
|
||||
|
||||
const metricsApiRequest: MetricsAPIRequest = {
|
||||
indexPattern: calculateIndexPatterBasedOnMetrics(snapshotRequest, source),
|
||||
indexPattern: sourceOverrides?.indexPattern ?? source.configuration.metricAlias,
|
||||
timerange: {
|
||||
field: source.configuration.fields.timestamp,
|
||||
field: sourceOverrides?.timestamp ?? source.configuration.fields.timestamp,
|
||||
from: timeRangeWithIntervalApplied.from,
|
||||
to: timeRangeWithIntervalApplied.to,
|
||||
interval: timeRangeWithIntervalApplied.interval,
|
||||
|
@ -74,7 +75,7 @@ export const transformRequestToMetricsAPIRequest = async (
|
|||
top_hits: {
|
||||
size: 1,
|
||||
_source: [inventoryFields.name],
|
||||
sort: [{ [source.configuration.fields.timestamp]: 'desc' }],
|
||||
sort: [{ [sourceOverrides?.timestamp ?? source.configuration.fields.timestamp]: 'desc' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SavedObjectsClientContract } from 'src/core/server';
|
||||
import { InfraSources } from '../../lib/sources';
|
||||
|
||||
// NOTE: TEMPORARY: This will become a subset of the new resolved KIP compatible log source configuration.
|
||||
export interface LogQueryFields {
|
||||
indexPattern: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
// NOTE: TEMPORARY: This will become a subset of the new resolved KIP compatible log source configuration.
|
||||
export const createGetLogQueryFields = (sources: InfraSources) => {
|
||||
return async (
|
||||
sourceId: string,
|
||||
savedObjectsClient: SavedObjectsClientContract
|
||||
): Promise<LogQueryFields> => {
|
||||
const source = await sources.getSourceConfiguration(savedObjectsClient, sourceId);
|
||||
|
||||
return {
|
||||
indexPattern: source.configuration.logAlias,
|
||||
timestamp: source.configuration.fields.timestamp,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type GetLogQueryFields = ReturnType<typeof createGetLogQueryFields>;
|
|
@ -15,16 +15,14 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
const supertest = getService('supertest');
|
||||
const fetchSource = async (): Promise<SourceResponse | undefined> => {
|
||||
const response = await supertest
|
||||
.get('/api/metrics/source/default/metrics')
|
||||
.get('/api/metrics/source/default')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.expect(200);
|
||||
return response.body;
|
||||
};
|
||||
const fetchHasData = async (
|
||||
type: 'logs' | 'metrics'
|
||||
): Promise<{ hasData: boolean } | undefined> => {
|
||||
const fetchHasData = async (): Promise<{ hasData: boolean } | undefined> => {
|
||||
const response = await supertest
|
||||
.get(`/api/metrics/source/default/${type}/hasData`)
|
||||
.get(`/api/metrics/source/default/hasData`)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.expect(200);
|
||||
return response.body;
|
||||
|
@ -34,41 +32,27 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
describe('8.0.0', () => {
|
||||
before(() => esArchiver.load('infra/8.0.0/logs_and_metrics'));
|
||||
after(() => esArchiver.unload('infra/8.0.0/logs_and_metrics'));
|
||||
describe('/api/metrics/source/default/metrics', () => {
|
||||
describe('/api/metrics/source/default', () => {
|
||||
it('should just work', async () => {
|
||||
const resp = fetchSource();
|
||||
return resp.then((data) => {
|
||||
expect(data).to.have.property('source');
|
||||
expect(data?.source.configuration.metricAlias).to.equal('metrics-*,metricbeat-*');
|
||||
expect(data?.source.configuration.logAlias).to.equal(
|
||||
'logs-*,filebeat-*,kibana_sample_data_logs*'
|
||||
);
|
||||
expect(data?.source.configuration.fields).to.eql({
|
||||
container: 'container.id',
|
||||
host: 'host.name',
|
||||
message: ['message', '@message'],
|
||||
pod: 'kubernetes.pod.uid',
|
||||
tiebreaker: '_doc',
|
||||
timestamp: '@timestamp',
|
||||
});
|
||||
expect(data?.source).to.have.property('status');
|
||||
expect(data?.source.status?.metricIndicesExist).to.equal(true);
|
||||
expect(data?.source.status?.logIndicesExist).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('/api/metrics/source/default/metrics/hasData', () => {
|
||||
describe('/api/metrics/source/default/hasData', () => {
|
||||
it('should just work', async () => {
|
||||
const resp = fetchHasData('metrics');
|
||||
return resp.then((data) => {
|
||||
expect(data).to.have.property('hasData');
|
||||
expect(data?.hasData).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('/api/metrics/source/default/logs/hasData', () => {
|
||||
it('should just work', async () => {
|
||||
const resp = fetchHasData('logs');
|
||||
const resp = fetchHasData();
|
||||
return resp.then((data) => {
|
||||
expect(data).to.have.property('hasData');
|
||||
expect(data?.hasData).to.be(true);
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
import expect from '@kbn/expect';
|
||||
|
||||
import {
|
||||
SourceResponse,
|
||||
InfraSavedSourceConfiguration,
|
||||
SourceResponseRuntimeType,
|
||||
} from '../../../../plugins/infra/common/http_api/source_api';
|
||||
MetricsSourceConfigurationResponse,
|
||||
PartialMetricsSourceConfigurationProperties,
|
||||
metricsSourceConfigurationResponseRT,
|
||||
} from '../../../../plugins/infra/common/metrics_sources';
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
|
@ -19,8 +19,8 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
const supertest = getService('supertest');
|
||||
const SOURCE_API_URL = '/api/metrics/source/default';
|
||||
const patchRequest = async (
|
||||
body: InfraSavedSourceConfiguration
|
||||
): Promise<SourceResponse | undefined> => {
|
||||
body: PartialMetricsSourceConfigurationProperties
|
||||
): Promise<MetricsSourceConfigurationResponse | undefined> => {
|
||||
const response = await supertest
|
||||
.patch(SOURCE_API_URL)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
|
@ -51,10 +51,9 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
name: 'UPDATED_NAME',
|
||||
description: 'UPDATED_DESCRIPTION',
|
||||
metricAlias: 'metricbeat-**',
|
||||
logAlias: 'filebeat-**',
|
||||
});
|
||||
|
||||
expect(SourceResponseRuntimeType.is(updateResponse)).to.be(true);
|
||||
expect(metricsSourceConfigurationResponseRT.is(updateResponse)).to.be(true);
|
||||
|
||||
const version = updateResponse?.source.version;
|
||||
const updatedAt = updateResponse?.source.updatedAt;
|
||||
|
@ -67,15 +66,12 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(configuration?.name).to.be('UPDATED_NAME');
|
||||
expect(configuration?.description).to.be('UPDATED_DESCRIPTION');
|
||||
expect(configuration?.metricAlias).to.be('metricbeat-**');
|
||||
expect(configuration?.logAlias).to.be('filebeat-**');
|
||||
expect(configuration?.fields.host).to.be('host.name');
|
||||
expect(configuration?.fields.pod).to.be('kubernetes.pod.uid');
|
||||
expect(configuration?.fields.tiebreaker).to.be('_doc');
|
||||
expect(configuration?.fields.timestamp).to.be('@timestamp');
|
||||
expect(configuration?.fields.container).to.be('container.id');
|
||||
expect(configuration?.logColumns).to.have.length(3);
|
||||
expect(configuration?.anomalyThreshold).to.be(50);
|
||||
expect(status?.logIndicesExist).to.be(true);
|
||||
expect(status?.metricIndicesExist).to.be(true);
|
||||
});
|
||||
|
||||
|
@ -105,8 +101,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(version).to.not.be(initialVersion);
|
||||
expect(updatedAt).to.be.greaterThan(createdAt || 0);
|
||||
expect(configuration?.metricAlias).to.be('metricbeat-**');
|
||||
expect(configuration?.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*');
|
||||
expect(status?.logIndicesExist).to.be(true);
|
||||
expect(status?.metricIndicesExist).to.be(true);
|
||||
});
|
||||
|
||||
|
@ -144,37 +138,6 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
expect(configuration?.fields.timestamp).to.be('@timestamp');
|
||||
});
|
||||
|
||||
it('applies a log column update to an existing source', async () => {
|
||||
const creationResponse = await patchRequest({
|
||||
name: 'NAME',
|
||||
});
|
||||
|
||||
const initialVersion = creationResponse?.source.version;
|
||||
const createdAt = creationResponse?.source.updatedAt;
|
||||
|
||||
const updateResponse = await patchRequest({
|
||||
logColumns: [
|
||||
{
|
||||
fieldColumn: {
|
||||
id: 'ADDED_COLUMN_ID',
|
||||
field: 'ADDED_COLUMN_FIELD',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const version = updateResponse?.source.version;
|
||||
const updatedAt = updateResponse?.source.updatedAt;
|
||||
const configuration = updateResponse?.source.configuration;
|
||||
expect(version).to.be.a('string');
|
||||
expect(version).to.not.be(initialVersion);
|
||||
expect(updatedAt).to.be.greaterThan(createdAt || 0);
|
||||
expect(configuration?.logColumns).to.have.length(1);
|
||||
expect(configuration?.logColumns[0]).to.have.key('fieldColumn');
|
||||
const fieldColumn = (configuration?.logColumns[0] as any).fieldColumn;
|
||||
expect(fieldColumn).to.have.property('id', 'ADDED_COLUMN_ID');
|
||||
expect(fieldColumn).to.have.property('field', 'ADDED_COLUMN_FIELD');
|
||||
});
|
||||
it('validates anomalyThreshold is between range 1-100', async () => {
|
||||
// create config with bad request
|
||||
await supertest
|
||||
|
|
|
@ -6,17 +6,17 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
InfraSavedSourceConfiguration,
|
||||
SourceResponse,
|
||||
} from '../../../plugins/infra/common/http_api/source_api';
|
||||
PartialMetricsSourceConfiguration,
|
||||
MetricsSourceConfigurationResponse,
|
||||
} from '../../../plugins/infra/common/metrics_sources';
|
||||
import { FtrProviderContext } from '../ftr_provider_context';
|
||||
|
||||
export function InfraOpsSourceConfigurationProvider({ getService }: FtrProviderContext) {
|
||||
const log = getService('log');
|
||||
const supertest = getService('supertest');
|
||||
const patchRequest = async (
|
||||
body: InfraSavedSourceConfiguration
|
||||
): Promise<SourceResponse | undefined> => {
|
||||
body: PartialMetricsSourceConfiguration
|
||||
): Promise<MetricsSourceConfigurationResponse | undefined> => {
|
||||
const response = await supertest
|
||||
.patch('/api/metrics/source/default')
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
|
@ -26,7 +26,10 @@ export function InfraOpsSourceConfigurationProvider({ getService }: FtrProviderC
|
|||
};
|
||||
|
||||
return {
|
||||
async createConfiguration(sourceId: string, sourceProperties: InfraSavedSourceConfiguration) {
|
||||
async createConfiguration(
|
||||
sourceId: string,
|
||||
sourceProperties: PartialMetricsSourceConfiguration
|
||||
) {
|
||||
log.debug(
|
||||
`Creating Infra UI source configuration "${sourceId}" with properties ${JSON.stringify(
|
||||
sourceProperties
|
||||
|
|
Loading…
Reference in a new issue