mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[apm] allow retrieval of metric indices (#167041)
### Summary Closes https://github.com/elastic/kibana/issues/166961 `/internal/apm/services/{serviceName}/infrastructure_attributes` route was disabled in serverless as it relied on an infra API to function. Since the infra plugin dependency was removed in https://github.com/elastic/kibana/pull/164094 we can reenable the route ### Testing I used a ccs cluster connected to edge-oblt and had to update the apm indices to also search the remote_cluster ``` xpack.apm.indices.metric: remote_cluster:metrics-apm*,remote_cluster:apm*,metrics-apm*,apm* xpack.apm.indices.transaction: remote_cluster:traces-apm*,remote_cluster:apm*,traces-apm*,apm* xpack.apm.indices.span: remote_cluster:traces-apm*,remote_cluster:apm*,traces-apm*,apm* xpack.apm.indices.error: remote_cluster:logs-apm*,remote_cluster:apm*,logs-apm*,apm* ``` - start serverless kibana - navigate to Applications -> Services, we need to select a [service linked to a container](https://github.com/elastic/kibana/blob/main/x-pack/plugins/apm/server/routes/infrastructure/get_host_names.ts#L23) to fully trigger the route logic (you can pick `quoteservice` if connected to edge-oblt data) - navigate to Logs tab - call to `/infrastructure_attributes` is successful
This commit is contained in:
parent
2bce7bbcbe
commit
88fdebdc81
6 changed files with 24 additions and 48 deletions
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types';
|
||||
import { APMRouteHandlerResources } from '../../../../routes/typings';
|
||||
import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes';
|
||||
|
||||
type InfraMetricsSearchParams = Omit<ESSearchRequest, 'index'> & {
|
||||
size: number;
|
||||
|
|
|
@ -1,25 +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 { SavedObjectsClientContract } from '@kbn/core/server';
|
||||
import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
|
||||
|
||||
export async function getInfraMetricIndices({
|
||||
infraPlugin,
|
||||
savedObjectsClient,
|
||||
}: {
|
||||
infraPlugin: Required<APMRouteHandlerResources['plugins']['infra']>;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
}): Promise<string> {
|
||||
if (!infraPlugin) {
|
||||
throw new Error('Infra Plugin needs to be setup');
|
||||
}
|
||||
const infra = await infraPlugin.start();
|
||||
const infraMetricIndices = await infra.getMetricIndices(savedObjectsClient);
|
||||
|
||||
return infraMetricIndices;
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import * as t from 'io-ts';
|
||||
import Boom from '@hapi/boom';
|
||||
import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
|
||||
import { getApmEventClient } from '../../lib/helpers/get_apm_event_client';
|
||||
import { environmentRt, kueryRt, rangeRt } from '../default_api_types';
|
||||
|
@ -30,10 +29,6 @@ const infrastructureRoute = createApmServerRoute({
|
|||
hostNames: string[];
|
||||
podNames: string[];
|
||||
}> => {
|
||||
if (!resources.plugins.infra) {
|
||||
throw Boom.notFound();
|
||||
}
|
||||
|
||||
const apmEventClient = await getApmEventClient(resources);
|
||||
const infraMetricsClient = createInfraMetricsClient(resources);
|
||||
const { params } = resources;
|
||||
|
|
|
@ -250,7 +250,7 @@ const serviceMetadataDetailsRoute = createApmServerRoute({
|
|||
end,
|
||||
});
|
||||
|
||||
if (serviceMetadataDetails?.container?.ids && resources.plugins.infra) {
|
||||
if (serviceMetadataDetails?.container?.ids) {
|
||||
const infraMetricsClient = createInfraMetricsClient(resources);
|
||||
const containerMetadata = await getServiceOverviewContainerMetadata({
|
||||
infraMetricsClient,
|
||||
|
@ -761,10 +761,7 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({
|
|||
end,
|
||||
});
|
||||
|
||||
if (
|
||||
serviceInstanceMetadataDetails?.container?.id &&
|
||||
resources.plugins.infra
|
||||
) {
|
||||
if (serviceInstanceMetadataDetails?.container?.id) {
|
||||
const infraMetricsClient = createInfraMetricsClient(resources);
|
||||
const containerMetadata = await getServiceInstanceContainerMetadata({
|
||||
infraMetricsClient,
|
||||
|
|
|
@ -7,18 +7,13 @@
|
|||
|
||||
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
|
||||
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
|
||||
import { MetricsDataClient } from './client';
|
||||
import { MetricsDataClient, DEFAULT_METRIC_INDICES } 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 client = new MetricsDataClient();
|
||||
const savedObjectsClient = {
|
||||
get: jest.fn().mockResolvedValue({ attributes: { metricIndices: 'foo,bar' } }),
|
||||
};
|
||||
|
@ -36,6 +31,10 @@ describe('MetricsDataClient', () => {
|
|||
});
|
||||
|
||||
it('falls back to provided handler when no metrics saved object exists', async () => {
|
||||
const client = new MetricsDataClient();
|
||||
client.setDefaultMetricIndicesHandler(async () => {
|
||||
return 'fallback-indices*';
|
||||
});
|
||||
const savedObjectsClient = {
|
||||
get: jest.fn().mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError()),
|
||||
};
|
||||
|
@ -51,5 +50,17 @@ describe('MetricsDataClient', () => {
|
|||
]);
|
||||
expect(indices).toEqual('fallback-indices*');
|
||||
});
|
||||
|
||||
it('falls back to static indices when no fallback exists', async () => {
|
||||
const client = new MetricsDataClient();
|
||||
const savedObjectsClient = {
|
||||
get: jest.fn().mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError()),
|
||||
};
|
||||
|
||||
const indices = await client.getMetricIndices({
|
||||
savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientContract,
|
||||
});
|
||||
expect(indices).toEqual(DEFAULT_METRIC_INDICES);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,21 +16,19 @@ import {
|
|||
metricsDataSourceSavedObjectName,
|
||||
} from '../saved_objects/metrics_data_source';
|
||||
|
||||
export const DEFAULT_METRIC_INDICES = 'metrics-*,metricbeat-*';
|
||||
|
||||
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);
|
||||
return this.getDefaultMetricIndices?.(options) ?? DEFAULT_METRIC_INDICES;
|
||||
}
|
||||
|
||||
throw err;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue