mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
chore(slo): update telemetry data (#206135)
This commit is contained in:
parent
b8cda36aa8
commit
9618e42548
8 changed files with 293 additions and 60 deletions
|
@ -7251,7 +7251,39 @@
|
|||
"total": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of slos in the cluster"
|
||||
"description": "The total number of SLOs in the cluster"
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of SLO definitions in the cluster"
|
||||
}
|
||||
},
|
||||
"total_with_ccs": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of SLO definitions using CCS in the cluster"
|
||||
}
|
||||
},
|
||||
"total_with_groups": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of SLO definitions using groups in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"instances": {
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The total number of SLO instances in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"by_status": {
|
||||
|
@ -7259,13 +7291,13 @@
|
|||
"enabled": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of enabled slos in the cluster"
|
||||
"description": "The number of enabled SLOs in the cluster"
|
||||
}
|
||||
},
|
||||
"disabled": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of disabled slos in the cluster"
|
||||
"description": "The number of disabled SLOs in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7275,7 +7307,7 @@
|
|||
"DYNAMIC_KEY": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of slos by sli type in the cluster"
|
||||
"description": "The number of SLOs by sli type in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7285,7 +7317,7 @@
|
|||
"DYNAMIC_KEY": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of slos by rolling duration in the cluster"
|
||||
"description": "The number of SLOs by rolling duration in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7295,7 +7327,7 @@
|
|||
"DYNAMIC_KEY": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of slos by calendar aligned duration in the cluster"
|
||||
"description": "The number of SLOs by calendar aligned duration in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7305,13 +7337,13 @@
|
|||
"occurrences": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of slos by timeslices budgeting method in the cluster"
|
||||
"description": "The number of SLOs by timeslices budgeting method in the cluster"
|
||||
}
|
||||
},
|
||||
"timeslices": {
|
||||
"type": "long",
|
||||
"_meta": {
|
||||
"description": "The number of slos by occurrences budgeting method in the cluster"
|
||||
"description": "The number of SLOs by occurrences budgeting method in the cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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/jest_integration',
|
||||
rootDir: '../../../../..',
|
||||
roots: ['<rootDir>/x-pack/solutions/observability/plugins/slo'],
|
||||
};
|
|
@ -1,42 +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 { savedObjectsRepositoryMock, ElasticsearchClientMock } from '@kbn/core/server/mocks';
|
||||
import { CollectorFetchContext } from '@kbn/usage-collection-plugin/server';
|
||||
import { fetcher } from './fetcher';
|
||||
|
||||
let savedObjectClient: ReturnType<typeof savedObjectsRepositoryMock.create>;
|
||||
|
||||
let closeMock: jest.Mock;
|
||||
let esClient: ElasticsearchClientMock;
|
||||
|
||||
describe('SLO usage collector fetcher', () => {
|
||||
beforeEach(() => {
|
||||
savedObjectClient = savedObjectsRepositoryMock.create();
|
||||
closeMock = jest.fn();
|
||||
});
|
||||
|
||||
it('without any existing slo', async () => {
|
||||
savedObjectClient.createPointInTimeFinder.mockReturnValue({
|
||||
find: async function* find() {
|
||||
return {
|
||||
[Symbol.asyncIterator]: async () => {},
|
||||
next: () => {},
|
||||
};
|
||||
},
|
||||
close: closeMock,
|
||||
});
|
||||
|
||||
const results = await fetcher({
|
||||
soClient: savedObjectClient,
|
||||
esClient,
|
||||
} as CollectorFetchContext);
|
||||
|
||||
expect(closeMock).toHaveBeenCalled();
|
||||
expect(results.slo.total).toEqual(0);
|
||||
});
|
||||
});
|
|
@ -4,10 +4,13 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { isCCSRemoteIndexName } from '@kbn/es-query';
|
||||
import { ALL_VALUE } from '@kbn/slo-schema';
|
||||
import { CollectorFetchContext } from '@kbn/usage-collection-plugin/server';
|
||||
import { StoredSLODefinition } from '../../domain/models';
|
||||
import { SO_SLO_TYPE } from '../../saved_objects';
|
||||
import { Usage } from './type';
|
||||
import { SLO_SUMMARY_DESTINATION_INDEX_PATTERN } from '../../../common/constants';
|
||||
|
||||
export const fetcher = async (context: CollectorFetchContext) => {
|
||||
const finder = context.soClient.createPointInTimeFinder<StoredSLODefinition>({
|
||||
|
@ -15,8 +18,31 @@ export const fetcher = async (context: CollectorFetchContext) => {
|
|||
perPage: 100,
|
||||
});
|
||||
|
||||
const totalInstances = await context.esClient.count({
|
||||
index: SLO_SUMMARY_DESTINATION_INDEX_PATTERN,
|
||||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
term: {
|
||||
isTempDoc: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let usage: Usage['slo'] = {
|
||||
total: 0,
|
||||
definitions: {
|
||||
total: 0,
|
||||
total_with_ccs: 0,
|
||||
total_with_groups: 0,
|
||||
},
|
||||
instances: {
|
||||
total: totalInstances?.count ?? 0,
|
||||
},
|
||||
by_status: {
|
||||
enabled: 0,
|
||||
disabled: 0,
|
||||
|
@ -34,7 +60,16 @@ export const fetcher = async (context: CollectorFetchContext) => {
|
|||
usage = response.saved_objects.reduce((acc, so) => {
|
||||
return {
|
||||
...acc,
|
||||
total: acc.total + 1,
|
||||
total: acc.total + 1, // deprecated in favor of definitions.total
|
||||
definitions: {
|
||||
total: acc.definitions.total + 1,
|
||||
total_with_ccs: isCCSRemoteIndexName(so.attributes.indicator.params.index)
|
||||
? acc.definitions.total_with_ccs + 1
|
||||
: acc.definitions.total_with_ccs,
|
||||
total_with_groups: [so.attributes.groupBy].flat().includes(ALL_VALUE)
|
||||
? acc.definitions.total_with_groups
|
||||
: acc.definitions.total_with_groups + 1,
|
||||
},
|
||||
by_status: {
|
||||
...acc.by_status,
|
||||
...(so.attributes.enabled && { enabled: acc.by_status.enabled + 1 }),
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* 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 {
|
||||
createTestServers,
|
||||
type TestElasticsearchUtils,
|
||||
type TestKibanaUtils,
|
||||
} from '@kbn/core-test-helpers-kbn-server';
|
||||
import {
|
||||
SavedObjectsClient,
|
||||
type ElasticsearchClient,
|
||||
type Logger,
|
||||
type SavedObjectsClientContract,
|
||||
} from '@kbn/core/server';
|
||||
import { KibanaSavedObjectsSLORepository, SLORepository } from '../../../services';
|
||||
import {
|
||||
createAPMTransactionDurationIndicator,
|
||||
createAPMTransactionErrorRateIndicator,
|
||||
createKQLCustomIndicator,
|
||||
createMetricCustomIndicator,
|
||||
createSLO,
|
||||
createSLOWithTimeslicesBudgetingMethod,
|
||||
createSyntheticsAvailabilityIndicator,
|
||||
createTimesliceMetricIndicator,
|
||||
} from '../../../services/fixtures/slo';
|
||||
import { fetcher } from '../fetcher';
|
||||
|
||||
const createLoggerMock = (): jest.Mocked<Logger> => {
|
||||
const logger = {
|
||||
debug: jest.fn(),
|
||||
info: jest.fn(),
|
||||
error: jest.fn(),
|
||||
get: jest.fn(),
|
||||
} as unknown as jest.Mocked<Logger>;
|
||||
|
||||
logger.get.mockReturnValue(logger);
|
||||
|
||||
return logger;
|
||||
};
|
||||
|
||||
describe('SLO usage collector fetcher', () => {
|
||||
let esServer: TestElasticsearchUtils;
|
||||
let esClient: ElasticsearchClient;
|
||||
let soClient: SavedObjectsClientContract;
|
||||
let kibanaServer: TestKibanaUtils;
|
||||
let sloRepository: SLORepository;
|
||||
let loggerMock: jest.Mocked<Logger>;
|
||||
|
||||
beforeAll(async () => {
|
||||
await createServers();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await stopServers();
|
||||
});
|
||||
|
||||
describe('with some SLOs', () => {
|
||||
beforeEach(async () => {
|
||||
await Promise.all([
|
||||
sloRepository.create(createSLO({ indicator: createAPMTransactionErrorRateIndicator() })),
|
||||
sloRepository.create(createSLO({ indicator: createAPMTransactionDurationIndicator() })),
|
||||
sloRepository.create(createSLO({ indicator: createSyntheticsAvailabilityIndicator() })),
|
||||
sloRepository.create(createSLO({ indicator: createKQLCustomIndicator() })),
|
||||
sloRepository.create(
|
||||
createSLOWithTimeslicesBudgetingMethod({ indicator: createMetricCustomIndicator() })
|
||||
),
|
||||
sloRepository.create(
|
||||
createSLOWithTimeslicesBudgetingMethod({ indicator: createTimesliceMetricIndicator() })
|
||||
),
|
||||
sloRepository.create(
|
||||
createSLO({ groupBy: ['host.name'], indicator: createKQLCustomIndicator() })
|
||||
),
|
||||
sloRepository.create(
|
||||
createSLO({ groupBy: 'host.name', indicator: createKQLCustomIndicator() })
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
it('returns the correct metrics', async () => {
|
||||
const results = await fetcher({ soClient, esClient });
|
||||
|
||||
expect(results.slo).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"by_budgeting_method": Object {
|
||||
"occurrences": 6,
|
||||
"timeslices": 2,
|
||||
},
|
||||
"by_calendar_aligned_duration": Object {},
|
||||
"by_rolling_duration": Object {
|
||||
"7d": 8,
|
||||
},
|
||||
"by_sli_type": Object {
|
||||
"sli.apm.transactionDuration": 1,
|
||||
"sli.apm.transactionErrorRate": 1,
|
||||
"sli.kql.custom": 3,
|
||||
"sli.metric.custom": 1,
|
||||
"sli.metric.timeslice": 1,
|
||||
"sli.synthetics.availability": 1,
|
||||
},
|
||||
"by_status": Object {
|
||||
"disabled": 0,
|
||||
"enabled": 8,
|
||||
},
|
||||
"definitions": Object {
|
||||
"total": 8,
|
||||
"total_with_ccs": 0,
|
||||
"total_with_groups": 2,
|
||||
},
|
||||
"instances": Object {
|
||||
"total": 0,
|
||||
},
|
||||
"total": 8,
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
async function createServers() {
|
||||
const { startES, startKibana } = createTestServers({
|
||||
adjustTimeout: jest.setTimeout,
|
||||
settings: {
|
||||
es: {
|
||||
license: 'trial',
|
||||
},
|
||||
kbn: {
|
||||
cliArgs: {
|
||||
oss: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
esServer = await startES();
|
||||
kibanaServer = await startKibana();
|
||||
|
||||
esClient = kibanaServer.coreStart.elasticsearch.client.asInternalUser;
|
||||
soClient = new SavedObjectsClient(
|
||||
kibanaServer.coreStart.savedObjects.createInternalRepository()
|
||||
);
|
||||
loggerMock = createLoggerMock();
|
||||
|
||||
sloRepository = new KibanaSavedObjectsSLORepository(soClient, loggerMock);
|
||||
}
|
||||
|
||||
async function stopServers() {
|
||||
if (kibanaServer) {
|
||||
await kibanaServer.stop();
|
||||
}
|
||||
if (esServer) {
|
||||
await esServer.stop();
|
||||
}
|
||||
|
||||
jest.clearAllMocks();
|
||||
}
|
||||
});
|
|
@ -21,20 +21,48 @@ export function registerSloUsageCollector(usageCollection?: UsageCollectionSetup
|
|||
total: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of slos in the cluster',
|
||||
description: 'The total number of SLOs in the cluster',
|
||||
},
|
||||
},
|
||||
definitions: {
|
||||
total: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of SLO definitions in the cluster',
|
||||
},
|
||||
},
|
||||
total_with_ccs: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of SLO definitions using CCS in the cluster',
|
||||
},
|
||||
},
|
||||
total_with_groups: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of SLO definitions using groups in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
instances: {
|
||||
total: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The total number of SLO instances in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
by_status: {
|
||||
enabled: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of enabled slos in the cluster',
|
||||
description: 'The number of enabled SLOs in the cluster',
|
||||
},
|
||||
},
|
||||
disabled: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of disabled slos in the cluster',
|
||||
description: 'The number of disabled SLOs in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -42,7 +70,7 @@ export function registerSloUsageCollector(usageCollection?: UsageCollectionSetup
|
|||
DYNAMIC_KEY: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of slos by sli type in the cluster',
|
||||
description: 'The number of SLOs by sli type in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -50,7 +78,7 @@ export function registerSloUsageCollector(usageCollection?: UsageCollectionSetup
|
|||
DYNAMIC_KEY: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of slos by rolling duration in the cluster',
|
||||
description: 'The number of SLOs by rolling duration in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -58,7 +86,7 @@ export function registerSloUsageCollector(usageCollection?: UsageCollectionSetup
|
|||
DYNAMIC_KEY: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of slos by calendar aligned duration in the cluster',
|
||||
description: 'The number of SLOs by calendar aligned duration in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -66,13 +94,13 @@ export function registerSloUsageCollector(usageCollection?: UsageCollectionSetup
|
|||
occurrences: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of slos by timeslices budgeting method in the cluster',
|
||||
description: 'The number of SLOs by timeslices budgeting method in the cluster',
|
||||
},
|
||||
},
|
||||
timeslices: {
|
||||
type: 'long',
|
||||
_meta: {
|
||||
description: 'The number of slos by occurrences budgeting method in the cluster',
|
||||
description: 'The number of SLOs by occurrences budgeting method in the cluster',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -7,7 +7,15 @@
|
|||
|
||||
export interface Usage {
|
||||
slo: {
|
||||
total: number;
|
||||
total: number; // deprecated
|
||||
definitions: {
|
||||
total: number;
|
||||
total_with_ccs: number;
|
||||
total_with_groups: number;
|
||||
};
|
||||
instances: {
|
||||
total: number;
|
||||
};
|
||||
by_status: {
|
||||
enabled: number;
|
||||
disabled: number;
|
||||
|
|
|
@ -101,5 +101,6 @@
|
|||
"@kbn/discover-shared-plugin",
|
||||
"@kbn/server-route-repository-client",
|
||||
"@kbn/security-plugin-types-public",
|
||||
"@kbn/core-test-helpers-kbn-server",
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue