Skip to content

Commit

Permalink
[Metrics UI] Performance improvements for Observability Homepage (#70869
Browse files Browse the repository at this point in the history
)
  • Loading branch information
simianhacker authored Jul 7, 2020
1 parent b1ec391 commit 6e35798
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 24 deletions.
12 changes: 2 additions & 10 deletions x-pack/plugins/infra/public/metrics_overview_fetchers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ describe('Metrics UI Observability Homepage Functions', () => {
it('should return true when true', async () => {
const { core, mockedGetStartServices } = setup();
core.http.get.mockResolvedValue({
status: {
indexFields: [],
logIndicesExist: false,
metricIndicesExist: true,
},
hasData: true,
});
const hasData = createMetricsHasData(mockedGetStartServices);
const response = await hasData();
Expand All @@ -43,11 +39,7 @@ describe('Metrics UI Observability Homepage Functions', () => {
it('should return false when false', async () => {
const { core, mockedGetStartServices } = setup();
core.http.get.mockResolvedValue({
status: {
indexFields: [],
logIndicesExist: false,
metricIndicesExist: false,
},
hasData: false,
});
const hasData = createMetricsHasData(mockedGetStartServices);
const response = await hasData();
Expand Down
7 changes: 4 additions & 3 deletions x-pack/plugins/infra/public/metrics_overview_fetchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ import {
} from '../common/http_api/snapshot_api';
import { SnapshotMetricType } from '../common/inventory_models/types';
import { InfraClientCoreSetup } from './types';
import { SourceResponse } from '../common/http_api/source_api';

export const createMetricsHasData = (
getStartServices: InfraClientCoreSetup['getStartServices']
) => async () => {
const [coreServices] = await getStartServices();
const { http } = coreServices;
const results = await http.get<SourceResponse>('/api/metrics/source/default/metrics');
return results.status.metricIndicesExist;
const results = await http.get<{ hasData: boolean }>(
'/api/metrics/source/default/metrics/hasData'
);
return results.hasData;
};

export const average = (values: number[]) => (values.length ? sum(values) / values.length : 0);
Expand Down
52 changes: 41 additions & 11 deletions x-pack/plugins/infra/server/routes/source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,21 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
try {
const { type, sourceId } = request.params;

const source = await libs.sources.getSourceConfiguration(
requestContext.core.savedObjects.client,
sourceId
);
const [source, logIndicesExist, metricIndicesExist, indexFields] = await Promise.all([
libs.sources.getSourceConfiguration(requestContext.core.savedObjects.client, sourceId),
libs.sourceStatus.hasLogIndices(requestContext, sourceId),
libs.sourceStatus.hasMetricIndices(requestContext, sourceId),
libs.fields.getFields(requestContext, sourceId, typeToInfraIndexType(type)),
]);

if (!source) {
return response.notFound();
}

const status = {
logIndicesExist: await libs.sourceStatus.hasLogIndices(requestContext, sourceId),
metricIndicesExist: await libs.sourceStatus.hasMetricIndices(requestContext, sourceId),
indexFields: await libs.fields.getFields(
requestContext,
sourceId,
typeToInfraIndexType(type)
),
logIndicesExist,
metricIndicesExist,
indexFields,
};

return response.ok({
Expand All @@ -65,4 +64,35 @@ export const initSourceRoute = (libs: InfraBackendLibs) => {
}
}
);

framework.registerRoute(
{
method: 'get',
path: '/api/metrics/source/{sourceId}/{type}/hasData',
validate: {
params: schema.object({
sourceId: schema.string(),
type: schema.string(),
}),
},
},
async (requestContext, request, response) => {
try {
const { type, sourceId } = request.params;

const hasData =
type === 'metrics'
? await libs.sourceStatus.hasMetricIndices(requestContext, sourceId)
: await libs.sourceStatus.hasLogIndices(requestContext, sourceId);

return response.ok({
body: { hasData },
});
} catch (error) {
return response.internalError({
body: error.message,
});
}
}
);
};
79 changes: 79 additions & 0 deletions x-pack/test/api_integration/apis/metrics_ui/http_source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import expect from '@kbn/expect';

import { SourceResponse } from '../../../../plugins/infra/server/lib/sources';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function ({ getService }: FtrProviderContext) {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
const fetchSource = async (): Promise<SourceResponse | undefined> => {
const response = await supertest
.get('/api/metrics/source/default/metrics')
.set('kbn-xsrf', 'xxx')
.expect(200);
return response.body;
};
const fetchHasData = async (
type: 'logs' | 'metrics'
): Promise<{ hasData: boolean } | undefined> => {
const response = await supertest
.get(`/api/metrics/source/default/${type}/hasData`)
.set('kbn-xsrf', 'xxx')
.expect(200);
return response.body;
};

describe('Source API via HTTP', () => {
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', () => {
it('should just work', () => {
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).to.have.property('status');
expect(data?.status.metricIndicesExist).to.equal(true);
expect(data?.status.logIndicesExist).to.equal(true);
});
});
});
describe('/api/metrics/source/default/metrics/hasData', () => {
it('should just work', () => {
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', () => {
const resp = fetchHasData('logs');
return resp.then((data) => {
expect(data).to.have.property('hasData');
expect(data?.hasData).to.be(true);
});
});
});
});
});
}
1 change: 1 addition & 0 deletions x-pack/test/api_integration/apis/metrics_ui/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ export default function ({ loadTestFile }) {
loadTestFile(require.resolve('./metrics_explorer'));
loadTestFile(require.resolve('./feature_controls'));
loadTestFile(require.resolve('./ip_to_hostname'));
loadTestFile(require.resolve('./http_source'));
});
}

0 comments on commit 6e35798

Please sign in to comment.