mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Uptime] Fix filters in query for fetching monitor attached rules (#115921)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
d4d470d938
commit
45476dcbe6
4 changed files with 369 additions and 30 deletions
109
x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_details.test.ts.snap
generated
Normal file
109
x-pack/plugins/uptime/server/lib/requests/__snapshots__/get_monitor_details.test.ts.snap
generated
Normal file
|
@ -0,0 +1,109 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`getMonitorDetails getMonitorAlerts should use expected filters for the query 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"body": Object {
|
||||
"aggs": Object {
|
||||
"monitors": Object {
|
||||
"terms": Object {
|
||||
"field": "monitor.id",
|
||||
"size": 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
"query": Object {
|
||||
"bool": Object {
|
||||
"filter": Array [
|
||||
Object {
|
||||
"term": Object {
|
||||
"monitor.id": "fooID",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"bool": Object {
|
||||
"filter": Array [
|
||||
Object {
|
||||
"bool": Object {
|
||||
"minimum_should_match": 1,
|
||||
"should": Array [
|
||||
Object {
|
||||
"match": Object {
|
||||
"monitor.type": "http",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"bool": Object {
|
||||
"minimum_should_match": 1,
|
||||
"should": Array [
|
||||
Object {
|
||||
"match_phrase": Object {
|
||||
"url.domain": "www.cnn.com",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
"size": 0,
|
||||
},
|
||||
"index": "heartbeat-8*,synthetics-*",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`getMonitorDetails getMonitorDetails will provide expected calls 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"body": Object {
|
||||
"_source": Array [
|
||||
"error",
|
||||
"@timestamp",
|
||||
],
|
||||
"query": Object {
|
||||
"bool": Object {
|
||||
"filter": Array [
|
||||
Object {
|
||||
"range": Object {
|
||||
"@timestamp": Object {
|
||||
"gte": "now-15m",
|
||||
"lte": "now",
|
||||
},
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"term": Object {
|
||||
"monitor.id": "fooID",
|
||||
},
|
||||
},
|
||||
],
|
||||
"must": Array [
|
||||
Object {
|
||||
"exists": Object {
|
||||
"field": "error",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
"size": 1,
|
||||
"sort": Array [
|
||||
Object {
|
||||
"@timestamp": Object {
|
||||
"order": "desc",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"index": "heartbeat-8*,synthetics-*",
|
||||
},
|
||||
]
|
||||
`;
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* 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 { mockSearchResult } from './helper';
|
||||
import { getMonitorAlerts, getMonitorDetails } from './get_monitor_details';
|
||||
import * as statusCheck from '../alerts/status_check';
|
||||
|
||||
describe('getMonitorDetails', () => {
|
||||
it('getMonitorDetails will provide expected calls', async () => {
|
||||
expect.assertions(2);
|
||||
|
||||
const uptimeEsClient = mockSearchResult([{ _source: { id: 1 } }]);
|
||||
|
||||
await getMonitorDetails({
|
||||
uptimeEsClient,
|
||||
monitorId: 'fooID',
|
||||
dateStart: 'now-15m',
|
||||
dateEnd: 'now',
|
||||
rulesClient: { find: jest.fn().mockReturnValue({ data: [] }) },
|
||||
});
|
||||
expect(uptimeEsClient.baseESClient.search).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect((uptimeEsClient.baseESClient.search as jest.Mock).mock.calls[0]).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('getMonitorAlerts', () => {
|
||||
it('should use expected filters for the query', async function () {
|
||||
const uptimeEsClient = mockSearchResult([{ _source: { id: 1 } }]);
|
||||
|
||||
jest.spyOn(statusCheck, 'formatFilterString').mockImplementation(async () => ({
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
bool: { should: [{ match: { 'monitor.type': 'http' } }], minimum_should_match: 1 },
|
||||
},
|
||||
{
|
||||
bool: {
|
||||
should: [{ match_phrase: { 'url.domain': 'www.cnn.com' } }],
|
||||
minimum_should_match: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
|
||||
await getMonitorAlerts({
|
||||
uptimeEsClient,
|
||||
monitorId: 'fooID',
|
||||
rulesClient: {
|
||||
find: jest.fn().mockReturnValue({ data: dummyAlertRules.data }),
|
||||
},
|
||||
});
|
||||
expect(uptimeEsClient.baseESClient.search).toHaveBeenCalledTimes(3);
|
||||
|
||||
const esParams = (uptimeEsClient.baseESClient.search as jest.Mock).mock.calls[0];
|
||||
|
||||
expect(esParams[0].body.query).toEqual({
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
term: {
|
||||
'monitor.id': 'fooID',
|
||||
},
|
||||
},
|
||||
{
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
bool: {
|
||||
minimum_should_match: 1,
|
||||
should: [
|
||||
{
|
||||
match: {
|
||||
'monitor.type': 'http',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
bool: {
|
||||
minimum_should_match: 1,
|
||||
should: [
|
||||
{
|
||||
match_phrase: {
|
||||
'url.domain': 'www.cnn.com',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
expect(esParams).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const dummyAlertRules = {
|
||||
page: 1,
|
||||
total: 3,
|
||||
per_page: 10,
|
||||
data: [
|
||||
{
|
||||
id: '9e0cad00-31e7-11ec-b2d2-abfef52bb74d',
|
||||
consumer: 'uptime',
|
||||
tags: [],
|
||||
name: 'browser alerrt',
|
||||
enabled: true,
|
||||
throttle: null,
|
||||
schedule: { interval: '1m' },
|
||||
params: {
|
||||
search: '',
|
||||
numTimes: 5,
|
||||
timerangeUnit: 'm',
|
||||
timerangeCount: 15,
|
||||
shouldCheckStatus: true,
|
||||
shouldCheckAvailability: true,
|
||||
availability: { range: 30, rangeUnit: 'd', threshold: '99' },
|
||||
filters: { tags: [], 'url.port': [], 'observer.geo.name': [], 'monitor.type': ['browser'] },
|
||||
},
|
||||
rule_type_id: 'xpack.uptime.alerts.monitorStatus',
|
||||
created_by: null,
|
||||
updated_by: null,
|
||||
created_at: '2021-10-20T20:52:20.050Z',
|
||||
updated_at: '2021-10-20T20:52:20.050Z',
|
||||
api_key_owner: null,
|
||||
notify_when: 'onActionGroupChange',
|
||||
mute_all: false,
|
||||
muted_alert_ids: [],
|
||||
scheduled_task_id: '9e91bb80-31e7-11ec-b2d2-abfef52bb74d',
|
||||
execution_status: {
|
||||
status: 'active',
|
||||
last_execution_date: '2021-10-21T09:33:22.044Z',
|
||||
last_duration: 414,
|
||||
},
|
||||
actions: [],
|
||||
},
|
||||
{
|
||||
id: 'deb541f0-31e7-11ec-b2d2-abfef52bb74d',
|
||||
consumer: 'alerts',
|
||||
tags: [],
|
||||
name: 'http alert',
|
||||
enabled: true,
|
||||
throttle: null,
|
||||
schedule: { interval: '1m' },
|
||||
params: {
|
||||
search: '',
|
||||
numTimes: 5,
|
||||
timerangeUnit: 'm',
|
||||
timerangeCount: 15,
|
||||
shouldCheckStatus: true,
|
||||
shouldCheckAvailability: true,
|
||||
availability: { range: 30, rangeUnit: 'd', threshold: '99' },
|
||||
filters: { tags: [], 'url.port': [], 'observer.geo.name': [], 'monitor.type': ['http'] },
|
||||
},
|
||||
rule_type_id: 'xpack.uptime.alerts.monitorStatus',
|
||||
created_by: null,
|
||||
updated_by: null,
|
||||
created_at: '2021-10-20T20:54:08.529Z',
|
||||
updated_at: '2021-10-20T20:54:08.529Z',
|
||||
api_key_owner: null,
|
||||
notify_when: 'onActionGroupChange',
|
||||
mute_all: false,
|
||||
muted_alert_ids: [],
|
||||
scheduled_task_id: 'df3e2100-31e7-11ec-b2d2-abfef52bb74d',
|
||||
execution_status: {
|
||||
status: 'ok',
|
||||
last_execution_date: '2021-10-21T09:33:22.044Z',
|
||||
last_duration: 92,
|
||||
},
|
||||
actions: [],
|
||||
},
|
||||
{
|
||||
id: '5bd4f720-31e8-11ec-b2d2-abfef52bb74d',
|
||||
consumer: 'uptime',
|
||||
tags: [],
|
||||
name: 'http rule',
|
||||
enabled: true,
|
||||
throttle: null,
|
||||
schedule: { interval: '1m' },
|
||||
params: {
|
||||
search: 'url.domain : "www.cnn.com" ',
|
||||
numTimes: 5,
|
||||
timerangeUnit: 'm',
|
||||
timerangeCount: 15,
|
||||
shouldCheckStatus: true,
|
||||
shouldCheckAvailability: true,
|
||||
availability: { range: 30, rangeUnit: 'd', threshold: '99' },
|
||||
filters: { tags: [], 'url.port': [], 'observer.geo.name': [], 'monitor.type': ['http'] },
|
||||
},
|
||||
rule_type_id: 'xpack.uptime.alerts.monitorStatus',
|
||||
created_by: null,
|
||||
updated_by: null,
|
||||
created_at: '2021-10-20T20:57:38.451Z',
|
||||
updated_at: '2021-10-20T20:57:38.451Z',
|
||||
api_key_owner: null,
|
||||
notify_when: 'onActionGroupChange',
|
||||
mute_all: false,
|
||||
muted_alert_ids: [],
|
||||
scheduled_task_id: '5bf417e0-31e8-11ec-b2d2-abfef52bb74d',
|
||||
execution_status: {
|
||||
status: 'ok',
|
||||
last_execution_date: '2021-10-21T09:33:22.043Z',
|
||||
last_duration: 87,
|
||||
},
|
||||
actions: [],
|
||||
},
|
||||
],
|
||||
};
|
|
@ -5,10 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { UMElasticsearchQueryFn } from '../adapters';
|
||||
import { MonitorDetails, Ping } from '../../../common/runtime_types';
|
||||
import { formatFilterString } from '../alerts/status_check';
|
||||
import { UptimeESClient } from '../lib';
|
||||
import { createEsQuery } from '../../../common/utils/es_search';
|
||||
|
||||
export interface GetMonitorDetailsParams {
|
||||
monitorId: string;
|
||||
|
@ -17,7 +19,7 @@ export interface GetMonitorDetailsParams {
|
|||
rulesClient: any;
|
||||
}
|
||||
|
||||
const getMonitorAlerts = async ({
|
||||
export const getMonitorAlerts = async ({
|
||||
uptimeEsClient,
|
||||
rulesClient,
|
||||
monitorId,
|
||||
|
@ -43,39 +45,48 @@ const getMonitorAlerts = async ({
|
|||
monitorAlerts.push(currAlert);
|
||||
continue;
|
||||
}
|
||||
const esParams = {
|
||||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
term: {
|
||||
'monitor.id': monitorId,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
size: 0,
|
||||
aggs: {
|
||||
monitors: {
|
||||
terms: {
|
||||
field: 'monitor.id',
|
||||
size: 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const parsedFilters = await formatFilterString(
|
||||
const parsedFilters: QueryDslQueryContainer | undefined = await formatFilterString(
|
||||
uptimeEsClient,
|
||||
currAlert.params.filters,
|
||||
currAlert.params.search
|
||||
);
|
||||
esParams.query.bool = Object.assign({}, esParams.query.bool, parsedFilters?.bool);
|
||||
|
||||
const { body: result } = await uptimeEsClient.search({ body: esParams });
|
||||
const esParams = createEsQuery({
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
term: {
|
||||
'monitor.id': monitorId,
|
||||
},
|
||||
},
|
||||
] as QueryDslQueryContainer[],
|
||||
},
|
||||
},
|
||||
size: 0,
|
||||
aggs: {
|
||||
monitors: {
|
||||
terms: {
|
||||
field: 'monitor.id',
|
||||
size: 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (result.hits.total.value > 0) {
|
||||
if (parsedFilters) {
|
||||
esParams.body.query.bool.filter.push(parsedFilters);
|
||||
}
|
||||
|
||||
const { body: result } = await uptimeEsClient.search(
|
||||
esParams,
|
||||
`getMonitorsForAlert-${currAlert.name}`
|
||||
);
|
||||
|
||||
if (result?.hits.total.value > 0) {
|
||||
monitorAlerts.push(currAlert);
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +135,7 @@ export const getMonitorDetails: UMElasticsearchQueryFn<GetMonitorDetailsParams,
|
|||
],
|
||||
};
|
||||
|
||||
const { body: result } = await uptimeEsClient.search({ body: params });
|
||||
const { body: result } = await uptimeEsClient.search({ body: params }, 'getMonitorDetails');
|
||||
|
||||
const data = result.hits.hits[0]?._source as Ping & { '@timestamp': string };
|
||||
|
||||
|
|
|
@ -91,8 +91,7 @@ export function mockSearchResult(
|
|||
): UptimeESClient {
|
||||
const { esClient: mockEsClient, uptimeEsClient } = getUptimeESMockClient();
|
||||
|
||||
// @ts-expect-error incomplete search response
|
||||
mockEsClient.search.mockResolvedValue({
|
||||
mockEsClient.search = jest.fn().mockResolvedValue({
|
||||
body: {
|
||||
took: 18,
|
||||
timed_out: false,
|
||||
|
@ -113,5 +112,6 @@ export function mockSearchResult(
|
|||
aggregations,
|
||||
},
|
||||
});
|
||||
|
||||
return uptimeEsClient;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue