diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts index c1382d455313f..f01448d9e37ac 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/get_supported_url_params.ts @@ -84,7 +84,8 @@ export const getSupportedUrlParams = (params: { ), absoluteDateRangeEnd: parseAbsoluteDate( dateRangeEnd || DATE_RANGE_END, - ABSOLUTE_DATE_RANGE_END + ABSOLUTE_DATE_RANGE_END, + { roundUp: true } ), autorefreshInterval: parseUrlInt(autorefreshInterval, AUTOREFRESH_INTERVAL), autorefreshIsPaused: parseIsPaused(autorefreshIsPaused, AUTOREFRESH_IS_PAUSED), diff --git a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts index eaf720a8d2f7e..2b0921f07abc9 100644 --- a/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts +++ b/x-pack/legacy/plugins/uptime/public/lib/helper/url_params/parse_absolute_date.ts @@ -6,8 +6,8 @@ import DateMath from '@elastic/datemath'; -export const parseAbsoluteDate = (date: string, defaultValue: number): number => { - const momentWrapper = DateMath.parse(date); +export const parseAbsoluteDate = (date: string, defaultValue: number, options = {}): number => { + const momentWrapper = DateMath.parse(date, options); if (momentWrapper) { return momentWrapper.valueOf(); } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts index e34bc6ab805c0..634d6369531d8 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/find_potential_matches.ts @@ -25,7 +25,6 @@ export const findPotentialMatches = async ( size: number ) => { const queryResult = await query(queryContext, searchAfter, size); - const checkGroups = new Set(); const monitorIds: string[] = []; get(queryResult, 'aggregations.monitors.buckets', []).forEach((b: any) => { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/query_context.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/query_context.ts index d97b7653402a3..961cc94dcea19 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/query_context.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/search/query_context.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import DateMath from '@elastic/datemath'; import { APICaller } from 'kibana/server'; import { CursorPagination } from '../adapter_types'; import { INDEX_NAMES } from '../../../../../common/constants'; +import { parseRelativeDate } from '../../../helper/get_histogram_interval'; export class QueryContext { callES: APICaller; @@ -95,8 +95,9 @@ export class QueryContext { // latencies and slowdowns that's dangerous. Making this value larger makes things // only slower, but only marginally so, and prevents people from seeing weird // behavior. - const tsStart = DateMath.parse(this.dateRangeEnd)!.subtract(5, 'minutes'); - const tsEnd = DateMath.parse(this.dateRangeEnd)!; + + const tsEnd = parseRelativeDate(this.dateRangeEnd, { roundUp: true })!; + const tsStart = tsEnd.subtract(5, 'minutes'); return { range: { diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts new file mode 100644 index 0000000000000..ec6e48c62c62e --- /dev/null +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/__test__/parse_relative_date.test.ts @@ -0,0 +1,23 @@ +/* + * 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 { parseRelativeDate } from '../get_histogram_interval'; +import { Moment } from 'moment'; + +describe('Parsing a relative end date properly', () => { + it('converts the upper range of relative end dates to now', async () => { + const thisWeekEndDate = 'now/w'; + + let endDate = parseRelativeDate(thisWeekEndDate, { roundUp: true }); + expect(Date.now() - (endDate as Moment).valueOf()).toBeLessThan(1000); + + const todayEndDate = 'now/d'; + + endDate = parseRelativeDate(todayEndDate, { roundUp: true }); + + expect(Date.now() - (endDate as Moment).valueOf()).toBeLessThan(1000); + }); +}); diff --git a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts b/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts index 0dedc3e456f51..26515fb4b4c63 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/helper/get_histogram_interval.ts @@ -7,18 +7,39 @@ import DateMath from '@elastic/datemath'; import { QUERY } from '../../../common/constants'; +export const parseRelativeDate = (dateStr: string, options = {}) => { + // We need this this parsing because if user selects This week or this date + // That represents end date in future, if week or day is still in the middle + // Uptime data can never be collected in future, so we will reset date to now + // in That case. Example case we select this week range will be to='now/w' and from = 'now/w'; + + const parsedDate = DateMath.parse(dateStr, options); + const dateTimestamp = parsedDate?.valueOf() ?? 0; + if (dateTimestamp > Date.now()) { + return DateMath.parse('now'); + } + return parsedDate; +}; + export const getHistogramInterval = ( dateRangeStart: string, dateRangeEnd: string, bucketCount?: number ): number => { - const from = DateMath.parse(dateRangeStart); - const to = DateMath.parse(dateRangeEnd); + const from = parseRelativeDate(dateRangeStart); + + // roundUp is required for relative date like now/w to get the end of the week + const to = parseRelativeDate(dateRangeEnd, { roundUp: true }); if (from === undefined) { throw Error('Invalid dateRangeStart value'); } if (to === undefined) { throw Error('Invalid dateRangeEnd value'); } - return Math.round((to.valueOf() - from.valueOf()) / (bucketCount || QUERY.DEFAULT_BUCKET_COUNT)); + const interval = Math.round( + (to.valueOf() - from.valueOf()) / (bucketCount || QUERY.DEFAULT_BUCKET_COUNT) + ); + + // Interval can never be zero, if it's 0 we return at least 1ms interval + return interval > 0 ? interval : 1; };