Skip to content

Commit

Permalink
feat(slo): global and slo specific diagnosis (#153118)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdelemme authored Mar 14, 2023
1 parent 0343c63 commit c226c07
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/kbn-slo-schema/src/rest_specs/slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ const findSLOResponseSchema = t.type({
const fetchHistoricalSummaryParamsSchema = t.type({ body: t.type({ sloIds: t.array(t.string) }) });
const fetchHistoricalSummaryResponseSchema = t.record(t.string, t.array(historicalSummarySchema));

const getSLODiagnosisParamsSchema = t.type({
path: t.type({ id: t.string }),
});

type SLOResponse = t.OutputOf<typeof sloResponseSchema>;
type SLOWithSummaryResponse = t.OutputOf<typeof sloWithSummaryResponseSchema>;

Expand Down Expand Up @@ -147,6 +151,7 @@ export {
deleteSLOParamsSchema,
findSLOParamsSchema,
findSLOResponseSchema,
getSLODiagnosisParamsSchema,
getSLOParamsSchema,
getSLOResponseSchema,
fetchHistoricalSummaryParamsSchema,
Expand Down
32 changes: 32 additions & 0 deletions x-pack/plugins/observability/server/routes/slo/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
deleteSLOParamsSchema,
fetchHistoricalSummaryParamsSchema,
findSLOParamsSchema,
getSLODiagnosisParamsSchema,
getSLOParamsSchema,
manageSLOParamsSchema,
updateSLOParamsSchema,
Expand Down Expand Up @@ -38,6 +39,7 @@ import { FetchHistoricalSummary } from '../../services/slo/fetch_historical_summ
import type { IndicatorTypes } from '../../domain/models';
import type { ObservabilityRequestHandlerContext } from '../../types';
import { ManageSLO } from '../../services/slo/manage_slo';
import { getGlobalDiagnosis, getSloDiagnosis } from '../../services/slo/get_diagnosis';

const transformGenerators: Record<IndicatorTypes, TransformGenerator> = {
'sli.apm.transactionDuration': new ApmTransactionDurationTransformGenerator(),
Expand Down Expand Up @@ -238,6 +240,34 @@ const fetchHistoricalSummary = createObservabilityServerRoute({
},
});

const getDiagnosisRoute = createObservabilityServerRoute({
endpoint: 'GET /internal/observability/slos/_diagnosis',
options: {
tags: [],
},
params: undefined,
handler: async ({ context }) => {
const esClient = (await context.core).elasticsearch.client.asCurrentUser;
const licensing = await context.licensing;

return getGlobalDiagnosis(esClient, licensing);
},
});

const getSloDiagnosisRoute = createObservabilityServerRoute({
endpoint: 'GET /internal/observability/slos/{id}/_diagnosis',
options: {
tags: [],
},
params: getSLODiagnosisParamsSchema,
handler: async ({ context, params }) => {
const esClient = (await context.core).elasticsearch.client.asCurrentUser;
const soClient = (await context.core).savedObjects.client;

return getSloDiagnosis(params.path.id, { esClient, soClient });
},
});

export const slosRouteRepository = {
...createSLORoute,
...deleteSLORoute,
Expand All @@ -247,4 +277,6 @@ export const slosRouteRepository = {
...findSLORoute,
...getSLORoute,
...updateSLORoute,
...getDiagnosisRoute,
...getSloDiagnosisRoute,
};
103 changes: 103 additions & 0 deletions x-pack/plugins/observability/server/services/slo/get_diagnosis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* 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 { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server';

import {
getSLOTransformId,
SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME,
SLO_COMPONENT_TEMPLATE_SETTINGS_NAME,
SLO_INDEX_TEMPLATE_NAME,
SLO_INGEST_PIPELINE_NAME,
} from '../../assets/constants';
import { StoredSLO } from '../../domain/models';
import { SO_SLO_TYPE } from '../../saved_objects';

const OK = 'OK';
const NOT_OK = 'NOT_OK';

export async function getGlobalDiagnosis(
esClient: ElasticsearchClient,
licensing: LicensingApiRequestHandlerContext
) {
const licenseInfo = licensing.license.toJSON();
const userPrivileges = await esClient.security.getUserPrivileges();
const sloResources = await getSloResourcesDiagnosis(esClient);

return {
licenseAndFeatures: licenseInfo,
userPrivileges,
sloResources,
};
}

export async function getSloDiagnosis(
sloId: string,
services: { esClient: ElasticsearchClient; soClient: SavedObjectsClientContract }
) {
const { esClient, soClient } = services;

const sloResources = await getSloResourcesDiagnosis(esClient);

let sloSavedObject;
try {
sloSavedObject = await soClient.get<StoredSLO>(SO_SLO_TYPE, sloId);
} catch (err) {
// noop
}

const sloTransformStats = await esClient.transform.getTransformStats({
transform_id: getSLOTransformId(sloId, sloSavedObject?.attributes.revision ?? 1),
});

let dataSample;
if (sloSavedObject?.attributes.indicator.params.index) {
const slo = sloSavedObject.attributes;
dataSample = await esClient.search({
index: slo.indicator.params.index,
sort: { [slo.settings.timestampField]: 'desc' },
size: 5,
});
}

return {
sloResources,
sloSavedObject: sloSavedObject ?? NOT_OK,
sloTransformStats,
dataSample: dataSample ?? NOT_OK,
};
}

async function getSloResourcesDiagnosis(esClient: ElasticsearchClient) {
const indexTemplateExists = await esClient.indices.existsIndexTemplate({
name: SLO_INDEX_TEMPLATE_NAME,
});

const mappingsTemplateExists = await esClient.cluster.existsComponentTemplate({
name: SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME,
});

const settingsTemplateExists = await esClient.cluster.existsComponentTemplate({
name: SLO_COMPONENT_TEMPLATE_SETTINGS_NAME,
});

let ingestPipelineExists = true;
try {
await esClient.ingest.getPipeline({ id: SLO_INGEST_PIPELINE_NAME });
} catch (err) {
ingestPipelineExists = false;
}

return {
[SLO_INDEX_TEMPLATE_NAME]: indexTemplateExists ? OK : NOT_OK,
[SLO_COMPONENT_TEMPLATE_MAPPINGS_NAME]: mappingsTemplateExists ? OK : NOT_OK,
[SLO_COMPONENT_TEMPLATE_SETTINGS_NAME]: settingsTemplateExists ? OK : NOT_OK,
[SLO_INGEST_PIPELINE_NAME]: ingestPipelineExists ? OK : NOT_OK,
};
}
1 change: 1 addition & 0 deletions x-pack/plugins/observability/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"@kbn/alerts-as-data-utils",
"@kbn/core-application-browser",
"@kbn/files-plugin",
"@kbn/core-elasticsearch-server",
],
"exclude": [
"target/**/*",
Expand Down

0 comments on commit c226c07

Please sign in to comment.