diff --git a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts index 5e2ed3e4d035bf..9851d36b5ca6d4 100644 --- a/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts +++ b/x-pack/legacy/plugins/uptime/server/graphql/monitors/resolvers.ts @@ -109,7 +109,7 @@ export const createMonitorsResolvers: CreateUMGraphQLResolvers = ( { dateRangeStart, dateRangeEnd, filters }, { req } ): Promise { - const counts = await libs.monitorStates.getSummaryCount( + const counts = await libs.monitors.getSnapshotCount( req, dateRangeStart, dateRangeEnd, diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts index caf4c7316b0632..508d667df08e71 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/adapter_types.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { MonitorSummary, SnapshotCount, StatesIndexStatus } from '../../../../common/graphql/types'; +import { MonitorSummary, StatesIndexStatus } from '../../../../common/graphql/types'; export interface UMMonitorStatesAdapter { getMonitorStates( @@ -20,11 +20,5 @@ export interface UMMonitorStatesAdapter { dateRangeEnd: string, filters?: string | null ): Promise; - getSummaryCount( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string | null - ): Promise; statesIndexExists(request: any): Promise; } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts index 2216dd96e0d29b..8dbc03430283b9 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/elasticsearch_monitor_states_adapter.ts @@ -11,7 +11,6 @@ import { MonitorSummary, SummaryHistogram, Check, - SnapshotCount, StatesIndexStatus, } from '../../../../common/graphql/types'; import { INDEX_NAMES, LEGACY_STATES_QUERY_SIZE } from '../../../../common/constants'; @@ -581,49 +580,6 @@ export class ElasticsearchMonitorStatesAdapter implements UMMonitorStatesAdapter }, {}); } - public async getSummaryCount( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string | null - ): Promise { - // TODO: adapt this to the states index in future release - // const { count } = await this.database.count(request, { index: 'heartbeat-states-8.0.0' }); - // return { count }; - - const count: SnapshotCount = { - up: 0, - down: 0, - mixed: 0, - total: 0, - }; - - let searchAfter: any | null = null; - do { - const { afterKey, result, statusFilter } = await this.runLegacyMonitorStatesQuery( - request, - dateRangeStart, - dateRangeEnd, - filters, - searchAfter - ); - searchAfter = afterKey; - this.getMonitorBuckets(result, statusFilter).reduce((acc: SnapshotCount, monitor: any) => { - const status = get(monitor, 'state.value.monitor.status', undefined); - if (status === 'up') { - acc.up++; - } else if (status === 'down') { - acc.down++; - } else if (status === 'mixed') { - acc.mixed++; - } - acc.total++; - return acc; - }, count); - } while (searchAfter !== null); - return count; - } - public async statesIndexExists(request: any): Promise { // TODO: adapt this to the states index in future release const { diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/memory_monitor_states_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/memory_monitor_states_adapter.ts index c75ed43643afce..af2495a181cbb4 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/memory_monitor_states_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitor_states/memory_monitor_states_adapter.ts @@ -5,7 +5,7 @@ */ import { UMMonitorStatesAdapter } from './adapter_types'; -import { MonitorSummary, SnapshotCount, StatesIndexStatus } from '../../../../common/graphql/types'; +import { MonitorSummary, StatesIndexStatus } from '../../../../common/graphql/types'; /** * This class will be implemented for server-side tests. @@ -28,14 +28,6 @@ export class UMMemoryMonitorStatesAdapter implements UMMonitorStatesAdapter { ): Promise { throw new Error('Method not implemented.'); } - public async getSummaryCount( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string | null | undefined - ): Promise { - throw new Error('Method not implemented.'); - } public async statesIndexExists(request: any): Promise { throw new Error('Method not implemented.'); } diff --git a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts index 883211dd4d7961..65435f4e03472a 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/adapters/monitors/elasticsearch_monitors_adapter.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, set } from 'lodash'; +import { get, set, reduce } from 'lodash'; import { INDEX_NAMES } from '../../../../common/constants'; import { ErrorListItem, @@ -197,11 +197,10 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { aggs: { latest: { top_hits: { - sort: [ - { - '@timestamp': { order: 'desc' }, - }, - ], + sort: [{ '@timestamp': { order: 'desc' } }], + _source: { + includes: ['summary.*', 'monitor.id', '@timestamp', 'observer.geo.name'], + }, size: 1, }, }, @@ -211,10 +210,16 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { }, }; - let up: number = 0; - let down: number = 0; let searchAfter: any = null; + const summaryByIdLocation: { + // ID + [key: string]: { + // Location + [key: string]: { up: number; down: number; timestamp: number }; + }; + } = {}; + do { if (searchAfter) { set(params, 'body.aggs.ids.composite.after', searchAfter); @@ -225,20 +230,66 @@ export class ElasticsearchMonitorsAdapter implements UMMonitorsAdapter { idBuckets.forEach(bucket => { // We only get the latest doc - const status = get(bucket, 'latest.hits.hits[0]._source.monitor.status', null); - if (!statusFilter || (statusFilter && statusFilter === status)) { - if (status === 'up') { - up++; - } else { - down++; - } + const source: any = get(bucket, 'latest.hits.hits[0]._source'); + const { + summary: { up, down }, + monitor: { id }, + } = source; + const timestamp = get(source, '@timestamp', 0); + const location = get(source, 'observer.geo.name', ''); + + let idSummary = summaryByIdLocation[id]; + if (!idSummary) { + idSummary = {}; + summaryByIdLocation[id] = idSummary; + } + const locationSummary = idSummary[location]; + if (!locationSummary || locationSummary.timestamp < timestamp) { + idSummary[location] = { timestamp, up, down }; } }); searchAfter = get(queryResult, 'aggregations.ids.after_key'); } while (searchAfter); - return { up, down, total: up + down }; + let up: number = 0; + let mixed: number = 0; + let down: number = 0; + + for (const id in summaryByIdLocation) { + if (!summaryByIdLocation.hasOwnProperty(id)) { + continue; + } + const locationInfo = summaryByIdLocation[id]; + const { up: locationUp, down: locationDown } = reduce( + locationInfo, + (acc, value, key) => { + acc.up += value.up; + acc.down += value.down; + return acc; + }, + { up: 0, down: 0 } + ); + + if (locationDown === 0) { + up++; + } else if (locationUp > 0) { + mixed++; + } else { + down++; + } + } + + const result: any = { up, down, mixed, total: up + down + mixed }; + if (statusFilter) { + for (const status in result) { + if (status !== 'total' && status !== statusFilter) { + result[status] = 0; + } + } + } + + return result; } /** diff --git a/x-pack/legacy/plugins/uptime/server/lib/domains/monitor_states.ts b/x-pack/legacy/plugins/uptime/server/lib/domains/monitor_states.ts index 5b35cb005749d4..c394f2a27f0044 100644 --- a/x-pack/legacy/plugins/uptime/server/lib/domains/monitor_states.ts +++ b/x-pack/legacy/plugins/uptime/server/lib/domains/monitor_states.ts @@ -5,7 +5,7 @@ */ import { UMMonitorStatesAdapter } from '../adapters/monitor_states'; -import { MonitorSummary, SnapshotCount, StatesIndexStatus } from '../../../common/graphql/types'; +import { MonitorSummary, StatesIndexStatus } from '../../../common/graphql/types'; export class UMMonitorStatesDomain { constructor(private readonly adapter: UMMonitorStatesAdapter, libs: {}) { @@ -22,15 +22,6 @@ export class UMMonitorStatesDomain { return this.adapter.getMonitorStates(request, pageIndex, pageSize, sortField, sortDirection); } - public async getSummaryCount( - request: any, - dateRangeStart: string, - dateRangeEnd: string, - filters?: string | null - ): Promise { - return this.adapter.getSummaryCount(request, dateRangeStart, dateRangeEnd, filters); - } - public async statesIndexExists(request: any): Promise { return this.adapter.statesIndexExists(request); } diff --git a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_down.json b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_down.json index 26e44876ec0366..af998c19206bd4 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_down.json +++ b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_down.json @@ -1,5 +1,5 @@ { "snapshot": { - "counts": { "down": 2, "mixed": 0, "up": 0, "total": 2 } + "counts": { "down": 2, "mixed": 0, "up": 0, "total": 10 } } } diff --git a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_up.json b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_up.json index 7037e6d4453104..6460999a8bbbfd 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_up.json +++ b/x-pack/test/api_integration/apis/uptime/graphql/fixtures/snapshot_filtered_by_up.json @@ -1,5 +1,5 @@ { "snapshot": { - "counts": { "down": 0, "mixed": 0, "up": 8, "total": 8 } + "counts": { "down": 0, "mixed": 0, "up": 8, "total": 10 } } }