mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[Metrics] metrics_data_access plugin (#164094)
## Summary Closes https://github.com/elastic/kibana/issues/161876 Creates a plugin providing utilities to access metrics data. The plugin only exposes a server API which includes a client with two methods: - `getMetricIndices` to retrieve the user-defined indices where metrics are located - `updateMetricIndices` to update the indices The client is now used where we previously relied on infra plugin to provide the configuration, in APM and Infra. The plugin persists the configuration in a new saved object `metrics-data-source`. Because this configuration was previously stored in the `infrastructure-ui-source`, the plugin relies on a fallback to reuse any existing value (see additional context https://github.com/elastic/kibana/issues/161876#issuecomment-1673537400). ### Reviewers There are no functional changes outside of Infra Monitoring UI and APM UI, other codeowners are involved because this introduces a new saved object - APM - the change introduces a drop-in replacement of the `infra.getMetricIndices` call. The ui code still relies on infra plugin for a couple of components so we can't drop the dependency yet, those we'll need to be moved to a tier 2 plugin (more details in https://github.com/elastic/observability-dev/discussions/2787 (internal)) in a separate issue ### Testing You'll need metrics data to verify data fetching works (I've used an edge-oblt cluster) 1. Navigate to Infrastructure Settings and verify metric indices are configured with the default value of `infrastructure-ui-source` 2. Update metric indices settings (if connected to oblt cluster add `remote_cluster:..` indices) 3. Verify `metrics-data-source` saved object is persisted with correct attributes 4. Verify Infrastructure Inventory is pulling data from the newly configured indices 5. Go to APM services, verify service Infrastructure pulls data from newly configured indices --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Jason Rhodes <jason.rhodes@elastic.co>
This commit is contained in:
parent
688980ce34
commit
d78ecfea34
39 changed files with 372 additions and 69 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -495,6 +495,7 @@ x-pack/examples/third_party_maps_source_example @elastic/kibana-gis
|
|||
src/plugins/maps_ems @elastic/kibana-gis
|
||||
x-pack/plugins/maps @elastic/kibana-gis
|
||||
x-pack/packages/maps/vector_tile_utils @elastic/kibana-gis
|
||||
x-pack/plugins/metrics_data_access @elastic/infra-monitoring-ui
|
||||
x-pack/packages/ml/agg_utils @elastic/ml-ui
|
||||
x-pack/packages/ml/anomaly_utils @elastic/ml-ui
|
||||
x-pack/packages/ml/category_validator @elastic/ml-ui
|
||||
|
|
|
@ -648,6 +648,10 @@ using the CURL scripts in the scripts folder.
|
|||
|Visualize geo data from Elasticsearch or 3rd party geo-services.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/metrics_data_access/README.md[metricsDataAccess]
|
||||
|Exposes utilities to access metrics data.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/x-pack/plugins/ml/readme.md[ml]
|
||||
|This plugin provides access to the machine learning features provided by
|
||||
Elastic.
|
||||
|
|
|
@ -514,6 +514,7 @@
|
|||
"@kbn/maps-ems-plugin": "link:src/plugins/maps_ems",
|
||||
"@kbn/maps-plugin": "link:x-pack/plugins/maps",
|
||||
"@kbn/maps-vector-tile-utils": "link:x-pack/packages/maps/vector_tile_utils",
|
||||
"@kbn/metrics-data-access-plugin": "link:x-pack/plugins/metrics_data_access",
|
||||
"@kbn/ml-agg-utils": "link:x-pack/packages/ml/agg_utils",
|
||||
"@kbn/ml-anomaly-utils": "link:x-pack/packages/ml/anomaly_utils",
|
||||
"@kbn/ml-category-validator": "link:x-pack/packages/ml/category_validator",
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"metrics-data-source": {
|
||||
"dynamic": false,
|
||||
"properties": {}
|
||||
},
|
||||
"url": {
|
||||
"dynamic": false,
|
||||
"properties": {
|
||||
|
|
|
@ -105,6 +105,7 @@ const STANDARD_LIST_TYPES = [
|
|||
'osquery-saved-query',
|
||||
'osquery-pack',
|
||||
'infrastructure-ui-source',
|
||||
'metrics-data-source',
|
||||
'metrics-explorer-view',
|
||||
'inventory-view',
|
||||
'infrastructure-monitoring-log-view',
|
||||
|
|
|
@ -115,6 +115,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
|
|||
"lens-ui-telemetry": "8c47a9e393861f76e268345ecbadfc8a5fb1e0bd",
|
||||
"maintenance-window": "d893544460abad56ff7a0e25b78f78776dfe10d1",
|
||||
"map": "76c71023bd198fb6b1163b31bafd926fe2ceb9da",
|
||||
"metrics-data-source": "81b69dc9830699d9ead5ac8dcb9264612e2a3c89",
|
||||
"metrics-explorer-view": "98cf395d0e87b89ab63f173eae16735584a8ff42",
|
||||
"ml-job": "150e1ab260e87f9963cc99e013304b9c54703dab",
|
||||
"ml-module": "2225cbb4bd508ea5f69db4b848be9d8a74b60198",
|
||||
|
|
|
@ -84,6 +84,7 @@ const previouslyRegisteredTypes = [
|
|||
'maintenance-window',
|
||||
'map',
|
||||
'maps-telemetry',
|
||||
'metrics-data-source',
|
||||
'metrics-explorer-view',
|
||||
'ml-job',
|
||||
'ml-trained-model',
|
||||
|
|
|
@ -235,6 +235,7 @@ describe('split .kibana index into multiple system indices', () => {
|
|||
"lens-ui-telemetry",
|
||||
"maintenance-window",
|
||||
"map",
|
||||
"metrics-data-source",
|
||||
"metrics-explorer-view",
|
||||
"ml-job",
|
||||
"ml-module",
|
||||
|
|
|
@ -984,6 +984,8 @@
|
|||
"@kbn/maps-plugin/*": ["x-pack/plugins/maps/*"],
|
||||
"@kbn/maps-vector-tile-utils": ["x-pack/packages/maps/vector_tile_utils"],
|
||||
"@kbn/maps-vector-tile-utils/*": ["x-pack/packages/maps/vector_tile_utils/*"],
|
||||
"@kbn/metrics-data-access-plugin": ["x-pack/plugins/metrics_data_access"],
|
||||
"@kbn/metrics-data-access-plugin/*": ["x-pack/plugins/metrics_data_access/*"],
|
||||
"@kbn/ml-agg-utils": ["x-pack/packages/ml/agg_utils"],
|
||||
"@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"],
|
||||
"@kbn/ml-anomaly-utils": ["x-pack/packages/ml/anomaly_utils"],
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"logsShared",
|
||||
"inspector",
|
||||
"licensing",
|
||||
"metricsDataAccess",
|
||||
"observability",
|
||||
"observabilityShared",
|
||||
"exploratoryView",
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
*/
|
||||
|
||||
import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types';
|
||||
import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes';
|
||||
import { getInfraMetricIndices } from '../../get_infra_metric_indices';
|
||||
import { APMRouteHandlerResources } from '../../../../routes/typings';
|
||||
|
||||
type InfraMetricsSearchParams = Omit<ESSearchRequest, 'index'> & {
|
||||
size: number;
|
||||
|
@ -17,6 +16,8 @@ type InfraMetricsSearchParams = Omit<ESSearchRequest, 'index'> & {
|
|||
export type InfraMetricsClient = ReturnType<typeof createInfraMetricsClient>;
|
||||
|
||||
export function createInfraMetricsClient(resources: APMRouteHandlerResources) {
|
||||
const metricsClient = resources.plugins.metricsDataAccess.setup.client;
|
||||
|
||||
return {
|
||||
async search<TDocument, TParams extends InfraMetricsSearchParams>(
|
||||
opts: TParams
|
||||
|
@ -26,8 +27,7 @@ export function createInfraMetricsClient(resources: APMRouteHandlerResources) {
|
|||
elasticsearch: { client: esClient },
|
||||
} = await resources.context.core;
|
||||
|
||||
const indexName = await getInfraMetricIndices({
|
||||
infraPlugin: resources.plugins.infra,
|
||||
const indexName = await metricsClient.getMetricIndices({
|
||||
savedObjectsClient,
|
||||
});
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ import {
|
|||
FleetSetupContract as FleetPluginSetup,
|
||||
FleetStartContract as FleetPluginStart,
|
||||
} from '@kbn/fleet-plugin/server';
|
||||
import { InfraPluginStart, InfraPluginSetup } from '@kbn/infra-plugin/server';
|
||||
import { MetricsDataPluginSetup } from '@kbn/metrics-data-access-plugin/server';
|
||||
import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server';
|
||||
|
||||
import {
|
||||
|
@ -79,7 +79,7 @@ export interface APMPluginSetupDependencies {
|
|||
licensing: LicensingPluginSetup;
|
||||
observability: ObservabilityPluginSetup;
|
||||
ruleRegistry: RuleRegistryPluginSetupContract;
|
||||
infra?: InfraPluginSetup;
|
||||
metricsDataAccess: MetricsDataPluginSetup;
|
||||
dataViews: {};
|
||||
share: SharePluginSetup;
|
||||
|
||||
|
@ -105,7 +105,7 @@ export interface APMPluginStartDependencies {
|
|||
licensing: LicensingPluginStart;
|
||||
observability: undefined;
|
||||
ruleRegistry: RuleRegistryPluginStartContract;
|
||||
infra: InfraPluginStart;
|
||||
metricsDataAccess: MetricsDataPluginSetup;
|
||||
dataViews: DataViewsServerPluginStart;
|
||||
share: undefined;
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
"@kbn/discover-plugin",
|
||||
"@kbn/observability-ai-assistant-plugin",
|
||||
"@kbn/apm-data-access-plugin",
|
||||
"@kbn/metrics-data-access-plugin",
|
||||
"@kbn/profiling-data-access-plugin",
|
||||
"@kbn/profiling-utils",
|
||||
"@kbn/core-analytics-server",
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"fieldFormats",
|
||||
"lens",
|
||||
"logsShared",
|
||||
"metricsDataAccess",
|
||||
"observability",
|
||||
"observabilityAIAssistant",
|
||||
"observabilityShared",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server';
|
||||
import { logViewSavedObjectName } from '@kbn/logs-shared-plugin/server';
|
||||
import { metricsDataSourceSavedObjectName } from '@kbn/metrics-data-access-plugin/server';
|
||||
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
|
||||
import { LOG_DOCUMENT_COUNT_RULE_TYPE_ID } from '../common/alerting/logs/log_threshold/types';
|
||||
import {
|
||||
|
@ -42,7 +43,7 @@ export const METRICS_FEATURE = {
|
|||
catalogue: ['infraops', 'metrics'],
|
||||
api: ['infra', 'rac'],
|
||||
savedObject: {
|
||||
all: ['infrastructure-ui-source'],
|
||||
all: ['infrastructure-ui-source', metricsDataSourceSavedObjectName],
|
||||
read: ['index-pattern'],
|
||||
},
|
||||
alerting: {
|
||||
|
@ -64,7 +65,7 @@ export const METRICS_FEATURE = {
|
|||
api: ['infra', 'rac'],
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: ['infrastructure-ui-source', 'index-pattern'],
|
||||
read: ['infrastructure-ui-source', 'index-pattern', metricsDataSourceSavedObjectName],
|
||||
},
|
||||
alerting: {
|
||||
rule: {
|
||||
|
|
|
@ -26,6 +26,7 @@ import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/serve
|
|||
import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server';
|
||||
import { LogsSharedPluginSetup, LogsSharedPluginStart } from '@kbn/logs-shared-plugin/server';
|
||||
import { VersionedRouteConfig } from '@kbn/core-http-server';
|
||||
import { MetricsDataPluginSetup } from '@kbn/metrics-data-access-plugin/server';
|
||||
|
||||
export interface InfraServerPluginSetupDeps {
|
||||
alerting: AlertingPluginContract;
|
||||
|
@ -40,6 +41,7 @@ export interface InfraServerPluginSetupDeps {
|
|||
visTypeTimeseries: VisTypeTimeseriesSetup;
|
||||
ml?: MlPluginSetup;
|
||||
logsShared: LogsSharedPluginSetup;
|
||||
metricsDataAccess: MetricsDataPluginSetup;
|
||||
}
|
||||
|
||||
export interface InfraServerPluginStartDeps {
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
import { LifecycleAlertServices } from '@kbn/rule-registry-plugin/server';
|
||||
import { ruleRegistryMocks } from '@kbn/rule-registry-plugin/server/mocks';
|
||||
import { createLifecycleRuleExecutorMock } from '@kbn/rule-registry-plugin/server/utils/create_lifecycle_rule_executor_mock';
|
||||
import { MetricsDataClient } from '@kbn/metrics-data-access-plugin/server';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
|
@ -1908,6 +1909,9 @@ const createMockStaticConfiguration = (sources: any): InfraConfig => ({
|
|||
const mockLibs: any = {
|
||||
sources: new InfraSources({
|
||||
config: createMockStaticConfiguration({}),
|
||||
metricsClient: {
|
||||
getMetricIndices: jest.fn().mockResolvedValue('metrics-*,metricbeat-*'),
|
||||
} as unknown as MetricsDataClient,
|
||||
}),
|
||||
configuration: createMockStaticConfiguration({}),
|
||||
metricsRules: {
|
||||
|
|
|
@ -12,6 +12,7 @@ import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
|
|||
import { ObservabilityConfig } from '@kbn/observability-plugin/server';
|
||||
import type { LocatorPublic } from '@kbn/share-plugin/common';
|
||||
import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server';
|
||||
import type { MetricsDataClient } from '@kbn/metrics-data-access-plugin/server';
|
||||
import { RulesServiceSetup } from '../services/rules';
|
||||
import { InfraConfig, InfraPluginStartServicesAccessor } from '../types';
|
||||
import { KibanaFramework } from './adapters/framework/kibana_framework_adapter';
|
||||
|
@ -39,4 +40,5 @@ export interface InfraBackendLibs extends InfraDomainLibs {
|
|||
handleEsError: typeof handleEsError;
|
||||
logger: Logger;
|
||||
alertsLocator?: LocatorPublic<AlertsLocatorParams>;
|
||||
metricsClient: MetricsDataClient;
|
||||
}
|
||||
|
|
|
@ -1,30 +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 { savedObjectsClientMock } from '@kbn/core/server/mocks';
|
||||
import { defaultSourceConfiguration, InfraSource } from '../sources';
|
||||
import { createInfraSourcesMock } from '../sources/mocks';
|
||||
import { makeGetMetricIndices } from './make_get_metric_indices';
|
||||
|
||||
describe('getMetricIndices', () => {
|
||||
it('should return the indices from a resolved configuration', async () => {
|
||||
const sourceConfiguration: InfraSource = {
|
||||
id: 'default',
|
||||
origin: 'stored',
|
||||
configuration: defaultSourceConfiguration,
|
||||
};
|
||||
const infraSourcesMock = createInfraSourcesMock();
|
||||
infraSourcesMock.getSourceConfiguration.mockResolvedValueOnce(sourceConfiguration);
|
||||
|
||||
const getMetricIndices = makeGetMetricIndices(infraSourcesMock);
|
||||
|
||||
const savedObjectsClient = savedObjectsClientMock.create();
|
||||
const metricIndices = await getMetricIndices(savedObjectsClient);
|
||||
|
||||
expect(metricIndices).toEqual(defaultSourceConfiguration.metricAlias);
|
||||
});
|
||||
});
|
|
@ -1,16 +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 type { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import type { IInfraSources } from '../sources';
|
||||
|
||||
export function makeGetMetricIndices(metricSources: IInfraSources) {
|
||||
return async (savedObjectsClient: SavedObjectsClientContract, sourceId: string = 'default') => {
|
||||
const source = await metricSources.getSourceConfiguration(savedObjectsClient, sourceId);
|
||||
return source.configuration.metricAlias;
|
||||
};
|
||||
}
|
|
@ -10,6 +10,7 @@ import type { InfraSources } from './sources';
|
|||
type IInfraSources = Pick<InfraSources, keyof InfraSources>;
|
||||
|
||||
export const createInfraSourcesMock = (): jest.Mocked<IInfraSources> => ({
|
||||
getInfraSourceConfiguration: jest.fn(),
|
||||
getSourceConfiguration: jest.fn(),
|
||||
createSourceConfiguration: jest.fn(),
|
||||
deleteSourceConfiguration: jest.fn(),
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { SavedObject } from '@kbn/core/server';
|
||||
import { MetricsDataClient } from '@kbn/metrics-data-access-plugin/server';
|
||||
import { InfraConfig } from '../../types';
|
||||
import { infraSourceConfigurationSavedObjectName } from './saved_object_type';
|
||||
import { InfraSources } from './sources';
|
||||
|
@ -15,6 +16,7 @@ describe('the InfraSources lib', () => {
|
|||
test('returns a source configuration if it exists', async () => {
|
||||
const sourcesLib = new InfraSources({
|
||||
config: createMockStaticConfiguration({}),
|
||||
metricsClient: createMockMetricsDataClient('METRIC_ALIAS'),
|
||||
});
|
||||
|
||||
const request: any = createRequestContext({
|
||||
|
@ -56,6 +58,7 @@ describe('the InfraSources lib', () => {
|
|||
logIndices: { type: 'index_pattern', indexPatternId: 'LOG_ALIAS' },
|
||||
},
|
||||
}),
|
||||
metricsClient: createMockMetricsDataClient('METRIC_ALIAS'),
|
||||
});
|
||||
|
||||
const request: any = createRequestContext({
|
||||
|
@ -83,6 +86,7 @@ describe('the InfraSources lib', () => {
|
|||
test('adds missing attributes from the default configuration to a source configuration', async () => {
|
||||
const sourcesLib = new InfraSources({
|
||||
config: createMockStaticConfiguration({}),
|
||||
metricsClient: createMockMetricsDataClient(),
|
||||
});
|
||||
|
||||
const request: any = createRequestContext({
|
||||
|
@ -128,6 +132,12 @@ const createMockStaticConfiguration = (sources: any): InfraConfig => ({
|
|||
enabled: true,
|
||||
});
|
||||
|
||||
const createMockMetricsDataClient = (metricAlias: string = 'metrics-*,metricbeat-*') =>
|
||||
({
|
||||
getMetricIndices: jest.fn().mockResolvedValue(metricAlias),
|
||||
updateMetricIndices: jest.fn(),
|
||||
} as unknown as MetricsDataClient);
|
||||
|
||||
const createRequestContext = (savedObject?: SavedObject<unknown>) => {
|
||||
return {
|
||||
core: {
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
SavedObjectsClientContract,
|
||||
SavedObjectsErrorHelpers,
|
||||
} from '@kbn/core/server';
|
||||
import { MetricsDataClient } from '@kbn/metrics-data-access-plugin/server';
|
||||
import {
|
||||
InfraSavedSourceConfiguration,
|
||||
InfraSource,
|
||||
|
@ -35,6 +36,7 @@ import { infraSourceConfigurationSavedObjectName } from './saved_object_type';
|
|||
|
||||
interface Libs {
|
||||
config: InfraConfig;
|
||||
metricsClient: MetricsDataClient;
|
||||
}
|
||||
|
||||
// extract public interface
|
||||
|
@ -48,7 +50,7 @@ export class InfraSources {
|
|||
this.libs = libs;
|
||||
}
|
||||
|
||||
public async getSourceConfiguration(
|
||||
public async getInfraSourceConfiguration(
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
sourceId: string
|
||||
): Promise<InfraSource> {
|
||||
|
@ -90,6 +92,21 @@ export class InfraSources {
|
|||
return savedSourceConfiguration;
|
||||
}
|
||||
|
||||
public async getSourceConfiguration(
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
sourceId: string
|
||||
): Promise<InfraSource> {
|
||||
const sourceConfiguration = await this.getInfraSourceConfiguration(
|
||||
savedObjectsClient,
|
||||
sourceId
|
||||
);
|
||||
const metricAlias = await this.libs.metricsClient.getMetricIndices({
|
||||
savedObjectsClient,
|
||||
});
|
||||
sourceConfiguration.configuration.metricAlias = metricAlias;
|
||||
return sourceConfiguration;
|
||||
}
|
||||
|
||||
public async getAllSourceConfigurations(savedObjectsClient: SavedObjectsClientContract) {
|
||||
const staticDefaultSourceConfiguration = await this.getStaticDefaultSourceConfiguration();
|
||||
|
||||
|
@ -129,6 +146,11 @@ export class InfraSources {
|
|||
})
|
||||
);
|
||||
|
||||
await this.libs.metricsClient.updateMetricIndices({
|
||||
savedObjectsClient,
|
||||
metricIndices: newSourceConfiguration.metricAlias,
|
||||
});
|
||||
|
||||
return {
|
||||
...createdSourceConfiguration,
|
||||
configuration: mergeSourceConfiguration(
|
||||
|
@ -180,6 +202,11 @@ export class InfraSources {
|
|||
})
|
||||
);
|
||||
|
||||
await this.libs.metricsClient.updateMetricIndices({
|
||||
savedObjectsClient,
|
||||
metricIndices: updatedSourceConfiguration.configuration.metricAlias!,
|
||||
});
|
||||
|
||||
return {
|
||||
...updatedSourceConfiguration,
|
||||
configuration: mergeSourceConfiguration(
|
||||
|
|
|
@ -27,7 +27,6 @@ const createInfraSetupMock = () => {
|
|||
|
||||
const createInfraStartMock = () => {
|
||||
const infraStartMock: jest.Mocked<InfraPluginStart> = {
|
||||
getMetricIndices: jest.fn(),
|
||||
inventoryViews: createInventoryViewsServiceStartMock(),
|
||||
metricsExplorerViews: createMetricsExplorerViewsServiceStartMock(),
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { Logger } from '@kbn/logging';
|
||||
import { alertsLocatorID } from '@kbn/observability-plugin/common';
|
||||
import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common';
|
||||
import { GetMetricIndicesOptions } from '@kbn/metrics-data-access-plugin/server';
|
||||
import {
|
||||
DISCOVER_APP_TARGET,
|
||||
LOGS_APP_TARGET,
|
||||
|
@ -41,7 +42,6 @@ import {
|
|||
import { InfraFieldsDomain } from './lib/domains/fields_domain';
|
||||
import { InfraMetricsDomain } from './lib/domains/metrics_domain';
|
||||
import { InfraBackendLibs, InfraDomainLibs } from './lib/infra_types';
|
||||
import { makeGetMetricIndices } from './lib/metrics/make_get_metric_indices';
|
||||
import { infraSourceConfigurationSavedObjectType, InfraSources } from './lib/sources';
|
||||
import { InfraSourceStatus } from './lib/source_status';
|
||||
import { inventoryViewSavedObjectType, metricsExplorerViewSavedObjectType } from './saved_objects';
|
||||
|
@ -153,8 +153,17 @@ export class InfraServerPlugin
|
|||
|
||||
setup(core: InfraPluginCoreSetup, plugins: InfraServerPluginSetupDeps) {
|
||||
const framework = new KibanaFramework(core, this.config, plugins);
|
||||
const metricsClient = plugins.metricsDataAccess.client;
|
||||
metricsClient.setDefaultMetricIndicesHandler(async (options: GetMetricIndicesOptions) => {
|
||||
const sourceConfiguration = await sources.getInfraSourceConfiguration(
|
||||
options.savedObjectsClient,
|
||||
'default'
|
||||
);
|
||||
return sourceConfiguration.configuration.metricAlias;
|
||||
});
|
||||
const sources = new InfraSources({
|
||||
config: this.config,
|
||||
metricsClient,
|
||||
});
|
||||
const sourceStatus = new InfraSourceStatus(
|
||||
new InfraElasticsearchSourceStatusAdapter(framework),
|
||||
|
@ -186,6 +195,7 @@ export class InfraServerPlugin
|
|||
framework,
|
||||
sources,
|
||||
sourceStatus,
|
||||
metricsClient,
|
||||
...domainLibs,
|
||||
handleEsError,
|
||||
logsRules: this.logsRules.setup(core, plugins),
|
||||
|
@ -202,7 +212,7 @@ export class InfraServerPlugin
|
|||
|
||||
// Register an handler to retrieve the fallback logView starting from a source configuration
|
||||
plugins.logsShared.logViews.registerLogViewFallbackHandler(async (sourceId, { soClient }) => {
|
||||
const sourceConfiguration = await sources.getSourceConfiguration(soClient, sourceId);
|
||||
const sourceConfiguration = await sources.getInfraSourceConfiguration(soClient, sourceId);
|
||||
return mapSourceToLogView(sourceConfiguration);
|
||||
});
|
||||
plugins.logsShared.logViews.setLogViewsStaticConfig({
|
||||
|
@ -270,7 +280,6 @@ export class InfraServerPlugin
|
|||
return {
|
||||
inventoryViews,
|
||||
metricsExplorerViews,
|
||||
getMetricIndices: makeGetMetricIndices(this.libs.sources),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import type {
|
||||
CoreSetup,
|
||||
CustomRequestHandlerContext,
|
||||
SavedObjectsClientContract,
|
||||
} from '@kbn/core/server';
|
||||
import type { CoreSetup, CustomRequestHandlerContext } from '@kbn/core/server';
|
||||
import type { SearchRequestHandlerContext } from '@kbn/data-plugin/server';
|
||||
import type { MlPluginSetup } from '@kbn/ml-plugin/server';
|
||||
import type { InfraStaticSourceConfiguration } from '../common/source_configuration/source_configuration';
|
||||
|
@ -37,10 +33,6 @@ export interface InfraPluginSetup {
|
|||
export interface InfraPluginStart {
|
||||
inventoryViews: InventoryViewsServiceStart;
|
||||
metricsExplorerViews: MetricsExplorerViewsServiceStart;
|
||||
getMetricIndices: (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
sourceId?: string
|
||||
) => Promise<string>;
|
||||
}
|
||||
|
||||
export type MlSystem = ReturnType<MlPluginSetup['mlSystemProvider']>;
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
"@kbn/licensing-plugin",
|
||||
"@kbn/aiops-utils",
|
||||
"@kbn/lens-embeddable-utils",
|
||||
"@kbn/metrics-data-access-plugin",
|
||||
"@kbn/expressions-plugin"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
|
|
3
x-pack/plugins/metrics_data_access/README.md
Executable file
3
x-pack/plugins/metrics_data_access/README.md
Executable file
|
@ -0,0 +1,3 @@
|
|||
# Metrics Data Access
|
||||
|
||||
Exposes utilities to access metrics data.
|
15
x-pack/plugins/metrics_data_access/jest.config.js
Normal file
15
x-pack/plugins/metrics_data_access/jest.config.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../..',
|
||||
roots: ['<rootDir>/x-pack/plugins/metrics_data_access'],
|
||||
coverageDirectory: '<rootDir>/target/kibana-coverage/jest/x-pack/plugins/metrics_data_access',
|
||||
coverageReporters: ['text', 'html'],
|
||||
collectCoverageFrom: ['<rootDir>/x-pack/plugins/metrics_data/{server}/**/*.test.ts'],
|
||||
};
|
15
x-pack/plugins/metrics_data_access/kibana.jsonc
Normal file
15
x-pack/plugins/metrics_data_access/kibana.jsonc
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"type": "plugin",
|
||||
"id": "@kbn/metrics-data-access-plugin",
|
||||
"owner": "@elastic/infra-monitoring-ui",
|
||||
"description": "Exposes utilities for accessing metrics data",
|
||||
"plugin": {
|
||||
"id": "metricsDataAccess",
|
||||
"server": true,
|
||||
"browser": false,
|
||||
"configPath": ["xpack", "metrics_data_access"],
|
||||
"requiredPlugins": [],
|
||||
"requiredBundles": [],
|
||||
"extraPublicDirs": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 { SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
|
||||
import { MetricsDataClient } from './client';
|
||||
import { metricsDataSourceSavedObjectName } from '../saved_objects/metrics_data_source';
|
||||
|
||||
describe('MetricsDataClient', () => {
|
||||
const client = new MetricsDataClient();
|
||||
|
||||
client.setDefaultMetricIndicesHandler(async () => {
|
||||
return 'fallback-indices*';
|
||||
});
|
||||
|
||||
describe('metric indices', () => {
|
||||
it('retrieves metrics saved object', async () => {
|
||||
const savedObjectsClient = {
|
||||
get: jest.fn().mockResolvedValue({ attributes: { metricIndices: 'foo,bar' } }),
|
||||
};
|
||||
|
||||
const indices = await client.getMetricIndices({
|
||||
savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientContract,
|
||||
});
|
||||
|
||||
expect(savedObjectsClient.get.mock.calls.length).toEqual(1);
|
||||
expect(savedObjectsClient.get.mock.calls[0]).toEqual([
|
||||
metricsDataSourceSavedObjectName,
|
||||
'default',
|
||||
]);
|
||||
expect(indices).toEqual('foo,bar');
|
||||
});
|
||||
|
||||
it('falls back to provided handler when no metrics saved object exists', async () => {
|
||||
const savedObjectsClient = {
|
||||
get: jest.fn().mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError()),
|
||||
};
|
||||
|
||||
const indices = await client.getMetricIndices({
|
||||
savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientContract,
|
||||
});
|
||||
|
||||
expect(savedObjectsClient.get.mock.calls.length).toEqual(1);
|
||||
expect(savedObjectsClient.get.mock.calls[0]).toEqual([
|
||||
metricsDataSourceSavedObjectName,
|
||||
'default',
|
||||
]);
|
||||
expect(indices).toEqual('fallback-indices*');
|
||||
});
|
||||
});
|
||||
});
|
55
x-pack/plugins/metrics_data_access/server/client/client.ts
Normal file
55
x-pack/plugins/metrics_data_access/server/client/client.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 { SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import {
|
||||
DefaultMetricIndicesHandler,
|
||||
GetMetricIndicesOptions,
|
||||
UpdateMetricIndicesOptions,
|
||||
} from '../types';
|
||||
import {
|
||||
MetricsDataSavedObject,
|
||||
metricsDataSourceSavedObjectName,
|
||||
} from '../saved_objects/metrics_data_source';
|
||||
|
||||
export class MetricsDataClient {
|
||||
private readonly defaultSavedObjectId = 'default';
|
||||
private getDefaultMetricIndices: DefaultMetricIndicesHandler = null;
|
||||
|
||||
async getMetricIndices(options: GetMetricIndicesOptions): Promise<string> {
|
||||
if (!this.getDefaultMetricIndices) {
|
||||
throw new Error('Missing getMetricsIndices fallback');
|
||||
}
|
||||
|
||||
const metricIndices = await options.savedObjectsClient
|
||||
.get<MetricsDataSavedObject>(metricsDataSourceSavedObjectName, this.defaultSavedObjectId)
|
||||
.then(({ attributes }) => attributes.metricIndices)
|
||||
.catch((err) => {
|
||||
if (SavedObjectsErrorHelpers.isNotFoundError(err)) {
|
||||
return this.getDefaultMetricIndices!(options);
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
return metricIndices;
|
||||
}
|
||||
|
||||
async updateMetricIndices(options: UpdateMetricIndicesOptions) {
|
||||
const object = await options.savedObjectsClient.create(
|
||||
metricsDataSourceSavedObjectName,
|
||||
{
|
||||
metricIndices: options.metricIndices,
|
||||
},
|
||||
{ id: this.defaultSavedObjectId, overwrite: true }
|
||||
);
|
||||
return object;
|
||||
}
|
||||
|
||||
setDefaultMetricIndicesHandler(handler: DefaultMetricIndicesHandler) {
|
||||
this.getDefaultMetricIndices = handler;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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 { MetricsDataClient } from './client';
|
24
x-pack/plugins/metrics_data_access/server/index.ts
Normal file
24
x-pack/plugins/metrics_data_access/server/index.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 { PluginInitializerContext } from '@kbn/core/server';
|
||||
import { MetricsDataPlugin } from './plugin';
|
||||
|
||||
export type {
|
||||
MetricsDataPluginSetup,
|
||||
GetMetricIndicesOptions,
|
||||
UpdateMetricIndicesOptions,
|
||||
DefaultMetricIndicesHandler,
|
||||
} from './types';
|
||||
|
||||
export { metricsDataSourceSavedObjectName } from './saved_objects/metrics_data_source';
|
||||
|
||||
export { MetricsDataClient } from './client';
|
||||
|
||||
export function plugin(context: PluginInitializerContext) {
|
||||
return new MetricsDataPlugin(context);
|
||||
}
|
32
x-pack/plugins/metrics_data_access/server/plugin.ts
Normal file
32
x-pack/plugins/metrics_data_access/server/plugin.ts
Normal file
|
@ -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 { CoreSetup, PluginInitializerContext, Plugin } from '@kbn/core/server';
|
||||
import { MetricsDataPluginSetup } from './types';
|
||||
import { MetricsDataClient } from './client';
|
||||
import { metricsDataSourceSavedObjectType } from './saved_objects/metrics_data_source';
|
||||
|
||||
export class MetricsDataPlugin implements Plugin<MetricsDataPluginSetup, {}, {}, {}> {
|
||||
private metricsClient: MetricsDataClient | null = null;
|
||||
|
||||
constructor(context: PluginInitializerContext) {}
|
||||
|
||||
public setup(core: CoreSetup) {
|
||||
core.savedObjects.registerType(metricsDataSourceSavedObjectType);
|
||||
|
||||
this.metricsClient = new MetricsDataClient();
|
||||
return {
|
||||
client: this.metricsClient,
|
||||
};
|
||||
}
|
||||
|
||||
public start() {
|
||||
return {};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 type { SavedObject, SavedObjectsType } from '@kbn/core/server';
|
||||
|
||||
export const metricsDataSourceSavedObjectName = 'metrics-data-source';
|
||||
|
||||
export interface MetricsDataSavedObject {
|
||||
metricIndices: string;
|
||||
}
|
||||
|
||||
export const metricsDataSourceSavedObjectType: SavedObjectsType = {
|
||||
name: metricsDataSourceSavedObjectName,
|
||||
hidden: false,
|
||||
namespaceType: 'single',
|
||||
management: {
|
||||
defaultSearchField: 'name',
|
||||
displayName: 'metrics data source',
|
||||
getTitle(savedObject: SavedObject<MetricsDataSavedObject>) {
|
||||
return `Metrics data source [id=${savedObject.id}]`;
|
||||
},
|
||||
icon: 'metricsApp',
|
||||
importableAndExportable: true,
|
||||
},
|
||||
mappings: {
|
||||
dynamic: false,
|
||||
properties: {},
|
||||
},
|
||||
};
|
26
x-pack/plugins/metrics_data_access/server/types.ts
Normal file
26
x-pack/plugins/metrics_data_access/server/types.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 '@kbn/core-saved-objects-api-server';
|
||||
|
||||
import { MetricsDataClient } from './client';
|
||||
|
||||
export interface MetricsDataPluginSetup {
|
||||
client: MetricsDataClient;
|
||||
}
|
||||
|
||||
export interface GetMetricIndicesOptions {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
}
|
||||
|
||||
export type UpdateMetricIndicesOptions = GetMetricIndicesOptions & {
|
||||
metricIndices: string;
|
||||
};
|
||||
|
||||
export type DefaultMetricIndicesHandler =
|
||||
| ((options: GetMetricIndicesOptions) => Promise<string>)
|
||||
| null;
|
12
x-pack/plugins/metrics_data_access/tsconfig.json
Normal file
12
x-pack/plugins/metrics_data_access/tsconfig.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types"
|
||||
},
|
||||
"include": ["../../../typings/**/*", "server/**/*"],
|
||||
"exclude": ["target/**/*"],
|
||||
"kbn_references": [
|
||||
"@kbn/core",
|
||||
"@kbn/core-saved-objects-api-server",
|
||||
]
|
||||
}
|
|
@ -4910,6 +4910,10 @@
|
|||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/metrics-data-access-plugin@link:x-pack/plugins/metrics_data_access":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/ml-agg-utils@link:x-pack/packages/ml/agg_utils":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue