[Uptime] Remove unused telemetry (#159044)

This commit is contained in:
Shahzad 2023-06-06 14:35:46 +02:00 committed by GitHub
parent 42e71121a6
commit e2a060d557
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 3 additions and 1364 deletions

View file

@ -22,7 +22,6 @@ export enum API_URLS {
JOURNEY_FAILED_STEPS = `/internal/uptime/journeys/failed_steps`,
JOURNEY_SCREENSHOT = `/internal/uptime/journey/screenshot/{checkGroup}/{stepIndex}`,
JOURNEY_SCREENSHOT_BLOCKS = `/internal/uptime/journey/screenshot/block`,
LOG_PAGE_VIEW = `/internal/uptime/log_page_view`,
ML_MODULE_JOBS = `/internal/ml/modules/jobs_exist/`,
ML_SETUP_MODULE = '/internal/ml/modules/setup/',

View file

@ -10,6 +10,5 @@ export * from './use_update_kuery_string';
export * from './use_monitor';
export * from './use_search_text';
export * from './use_cert_status';
export * from './use_telemetry';
export * from './use_url_params';
export { useUptimeDataView } from '../contexts/uptime_data_view_context';

View file

@ -1,45 +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 { useEffect } from 'react';
import { useGetUrlParams } from './use_url_params';
import { apiService } from '../state/api/utils';
import { API_URLS } from '../../../common/constants';
export enum UptimePage {
Overview = 'GettingStarted',
MappingError = 'MappingError',
Monitor = 'Monitor',
MonitorAdd = 'AddMonitor',
MonitorEdit = 'EditMonitor',
MonitorManagement = 'MonitorManagement',
Settings = 'Settings',
Certificates = 'Certificates',
StepDetail = 'StepDetail',
SyntheticCheckStepsPage = 'SyntheticCheckStepsPage',
NotFound = '__not-found__',
}
export const useUptimeTelemetry = (page?: UptimePage) => {
const { dateRangeStart, dateRangeEnd, autorefreshInterval, autorefreshIsPaused } =
useGetUrlParams();
useEffect(() => {
if (!apiService.http) throw new Error('Core http services are not defined');
const params = {
page,
autorefreshInterval: autorefreshInterval / 1000, // divide by 1000 to keep it in secs
dateStart: dateRangeStart,
dateEnd: dateRangeEnd,
autoRefreshEnabled: !autorefreshIsPaused,
};
setTimeout(() => {
apiService.post(API_URLS.LOG_PAGE_VIEW, params);
}, 100);
}, [autorefreshInterval, autorefreshIsPaused, dateRangeEnd, dateRangeStart, page]);
};

View file

@ -25,7 +25,6 @@ import {
} from '../../common/constants';
import { MappingErrorPage, MonitorPage, StepDetailPage, NotFoundPage, SettingsPage } from './pages';
import { CertificatesPage } from './pages/certificates';
import { UptimePage, useUptimeTelemetry } from './hooks';
import { OverviewPageComponent } from './pages/overview';
import {
SyntheticsCheckSteps,
@ -50,7 +49,6 @@ type RouteProps = LazyObservabilityPageTemplateProps & {
component: React.FC;
dataTestSubj: string;
title: string;
telemetryId: UptimePage;
};
const baseTitle = i18n.translate('xpack.synthetics.routes.legacyBaseTitle', {
@ -71,7 +69,6 @@ const getRoutes = (): RouteProps[] => {
path: MONITOR_ROUTE,
component: MonitorPage,
dataTestSubj: 'uptimeMonitorPage',
telemetryId: UptimePage.Monitor,
pageHeader: {
children: <MonitorPageTitleContent />,
pageTitle: <MonitorPageTitle />,
@ -86,7 +83,6 @@ const getRoutes = (): RouteProps[] => {
path: SETTINGS_ROUTE,
component: SettingsPage,
dataTestSubj: 'uptimeSettingsPage',
telemetryId: UptimePage.Settings,
pageHeader: {
pageTitle: (
<FormattedMessage
@ -106,7 +102,6 @@ const getRoutes = (): RouteProps[] => {
path: CERTIFICATES_ROUTE,
component: CertificatesPage,
dataTestSubj: 'uptimeCertificatesPage',
telemetryId: UptimePage.Certificates,
pageHeader: {
pageTitle: <CertificateTitle />,
rightSideItems: [<CertRefreshBtn />],
@ -120,7 +115,6 @@ const getRoutes = (): RouteProps[] => {
path: STEP_DETAIL_ROUTE,
component: StepDetailPage,
dataTestSubj: 'uptimeStepDetailPage',
telemetryId: UptimePage.StepDetail,
pageHeader: {
children: <StepDetailPageChildren />,
pageTitle: <StepDetailPageHeader />,
@ -132,7 +126,6 @@ const getRoutes = (): RouteProps[] => {
path: SYNTHETIC_CHECK_STEPS_ROUTE,
component: SyntheticsCheckSteps,
dataTestSubj: 'uptimeSyntheticCheckStepsPage',
telemetryId: UptimePage.SyntheticCheckStepsPage,
pageHeader: {
pageTitle: <SyntheticsCheckStepsPageHeader />,
rightSideItems: [<SyntheticsCheckStepsPageRightSideItem />],
@ -143,7 +136,6 @@ const getRoutes = (): RouteProps[] => {
path: OVERVIEW_ROUTE,
component: OverviewPageComponent,
dataTestSubj: 'uptimeOverviewPage',
telemetryId: UptimePage.Overview,
pageHeader: {
pageTitle: MONITORING_OVERVIEW_LABEL,
rightSideItems: [<UptimeDatePicker />],
@ -156,7 +148,6 @@ const getRoutes = (): RouteProps[] => {
path: MAPPING_ERROR_ROUTE,
component: MappingErrorPage,
dataTestSubj: 'uptimeMappingErrorPage',
telemetryId: UptimePage.MappingError,
pageHeader: {
pageTitle: (
<div>
@ -172,12 +163,7 @@ const getRoutes = (): RouteProps[] => {
];
};
const RouteInit: React.FC<Pick<RouteProps, 'path' | 'title' | 'telemetryId'>> = ({
path,
title,
telemetryId,
}) => {
useUptimeTelemetry(telemetryId);
const RouteInit: React.FC<Pick<RouteProps, 'path' | 'title'>> = ({ path, title }) => {
useEffect(() => {
document.title = title;
}, [path, title]);
@ -198,13 +184,12 @@ export const PageRouter: FC = () => {
path,
component: RouteComponent,
dataTestSubj,
telemetryId,
pageHeader,
...pageTemplateProps
}) => (
<Route path={path} key={telemetryId} exact={true}>
<Route path={path} key={dataTestSubj} exact={true}>
<div className={APP_WRAPPER_CLASS} data-test-subj={dataTestSubj}>
<RouteInit title={title} path={path} telemetryId={telemetryId} />
<RouteInit title={title} path={path} />
<UptimePageTemplateComponent
path={path}
pageHeader={pageHeader}

View file

@ -6,4 +6,3 @@
*/
export * from './framework';
export * from './telemetry';

View file

@ -1,85 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`KibanaTelemetryAdapter collects monitor and overview data 1`] = `
Object {
"last_24_hours": Object {
"hits": Object {
"autoRefreshEnabled": true,
"autorefreshInterval": Array [
30,
],
"dateRangeEnd": Array [
"now",
],
"dateRangeStart": Array [
"now-15",
],
"fleet_monitor_frequency": Array [],
"fleet_monitor_name_stats": Object {
"avg_length": 0,
"max_length": 0,
"min_length": 0,
},
"fleet_no_of_unique_monitors": 0,
"monitor_frequency": Array [],
"monitor_name_stats": Object {
"avg_length": 0,
"max_length": 0,
"min_length": 0,
},
"monitor_page": 1,
"no_of_unique_monitors": 0,
"no_of_unique_observer_locations": 0,
"observer_location_name_stats": Object {
"avg_length": 0,
"max_length": 0,
"min_length": 0,
},
"overview_page": 1,
"settings_page": 1,
},
},
}
`;
exports[`KibanaTelemetryAdapter drops old buckets and reduces current window 1`] = `
Object {
"last_24_hours": Object {
"hits": Object {
"autoRefreshEnabled": true,
"autorefreshInterval": Array [
30,
],
"dateRangeEnd": Array [
"now",
],
"dateRangeStart": Array [
"now-15",
],
"fleet_monitor_frequency": Array [],
"fleet_monitor_name_stats": Object {
"avg_length": 0,
"max_length": 0,
"min_length": 0,
},
"fleet_no_of_unique_monitors": 0,
"monitor_frequency": Array [],
"monitor_name_stats": Object {
"avg_length": 0,
"max_length": 0,
"min_length": 0,
},
"monitor_page": 2,
"no_of_unique_monitors": 0,
"no_of_unique_observer_locations": 0,
"observer_location_name_stats": Object {
"avg_length": 0,
"max_length": 0,
"min_length": 0,
},
"overview_page": 1,
"settings_page": 2,
},
},
}
`;

View file

@ -1,8 +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.
*/
export { KibanaTelemetryAdapter } from './kibana_telemetry_adapter';

View file

@ -1,107 +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 { KibanaTelemetryAdapter } from './kibana_telemetry_adapter';
import { createCollectorFetchContextMock } from '@kbn/usage-collection-plugin/server/mocks';
jest
.spyOn(KibanaTelemetryAdapter, 'countNoOfUniqueMonitorAndLocations')
.mockResolvedValue(undefined as any);
describe('KibanaTelemetryAdapter', () => {
let usageCollection: any;
let getSavedObjectsClient: any;
let collectorFetchContext: any;
let collector: {
type: string;
fetch: (collectorFetchParams: any) => Promise<any>;
isReady: () => boolean;
};
beforeEach(() => {
usageCollection = {
makeUsageCollector: (val: any) => {
collector = val;
},
};
getSavedObjectsClient = () => {
return {
get: () => {},
};
};
collectorFetchContext = createCollectorFetchContextMock();
});
it('collects monitor and overview data', async () => {
expect.assertions(1);
KibanaTelemetryAdapter.initUsageCollector(usageCollection, getSavedObjectsClient);
KibanaTelemetryAdapter.countPageView({
page: 'Overview',
dateStart: 'now-15',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
});
KibanaTelemetryAdapter.countPageView({
page: 'Monitor',
dateStart: 'now-15',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
});
KibanaTelemetryAdapter.countPageView({
page: 'Settings',
dateStart: 'now-15',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
});
const result = await collector.fetch(collectorFetchContext);
expect(result).toMatchSnapshot();
});
it('drops old buckets and reduces current window', async () => {
expect.assertions(1);
// give a time of > 24 hours ago
Date.now = jest.fn(() => 1559053560000);
KibanaTelemetryAdapter.initUsageCollector(usageCollection, getSavedObjectsClient);
KibanaTelemetryAdapter.countPageView({
page: 'Overview',
dateStart: 'now-20',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
});
KibanaTelemetryAdapter.countPageView({
page: 'Monitor',
dateStart: 'now-15',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
}); // give a time of now
Date.now = jest.fn(() => new Date().valueOf());
KibanaTelemetryAdapter.countPageView({
page: 'Monitor',
dateStart: 'now-15',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
});
KibanaTelemetryAdapter.countPageView({
page: 'Settings',
dateStart: 'now-15',
dateEnd: 'now',
autoRefreshEnabled: true,
autorefreshInterval: 30,
});
const result = await collector.fetch(collectorFetchContext);
expect(result).toMatchSnapshot();
});
it('defaults ready to `true`', async () => {
KibanaTelemetryAdapter.initUsageCollector(usageCollection, getSavedObjectsClient);
expect(collector.isReady()).toBe(true);
});
});

View file

@ -1,474 +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 moment from 'moment';
import { SavedObjectsClientContract } from '@kbn/core/server';
import { CollectorFetchContext, UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
import { PageViewParams, UptimeTelemetry, Usage } from './types';
import { savedObjectsAdapter } from '../../saved_objects/saved_objects';
import { UptimeEsClient } from '../../lib';
import { createEsQuery } from '../../../../../common/utils/es_search';
interface UptimeTelemetryCollector {
[key: number]: UptimeTelemetry;
}
// seconds in an hour
const BUCKET_SIZE = 3600;
// take buckets in the last day
const BUCKET_NUMBER = 24;
export class KibanaTelemetryAdapter {
public static registerUsageCollector = (
usageCollector: UsageCollectionSetup,
getSavedObjectsClient: () => SavedObjectsClientContract | undefined
) => {
if (!usageCollector) {
return;
}
const collector = KibanaTelemetryAdapter.initUsageCollector(
usageCollector,
getSavedObjectsClient
);
usageCollector.registerCollector(collector);
};
public static initUsageCollector(
usageCollector: UsageCollectionSetup,
getSavedObjectsClient: () => SavedObjectsClientContract | undefined
) {
return usageCollector.makeUsageCollector<Usage>({
type: 'uptime',
schema: {
last_24_hours: {
hits: {
autoRefreshEnabled: {
type: 'boolean',
},
autorefreshInterval: { type: 'array', items: { type: 'long' } },
dateRangeEnd: { type: 'array', items: { type: 'date' } },
dateRangeStart: { type: 'array', items: { type: 'date' } },
monitor_frequency: { type: 'array', items: { type: 'long' } },
monitor_name_stats: {
avg_length: {
type: 'float',
_meta: {
description: 'This field represents the average length of monitor names',
},
},
max_length: {
type: 'long',
_meta: {
description: 'This field represents the max length of monitor names',
},
},
min_length: {
type: 'long',
_meta: {
description: 'This field represents the min length of monitor names',
},
},
},
monitor_page: { type: 'long' },
no_of_unique_monitors: {
type: 'long',
_meta: {
description: 'This field represents the number of unique configured monitors',
},
},
no_of_unique_observer_locations: {
type: 'long',
_meta: {
description:
'This field represents the number of unique monitor observer locations',
},
},
observer_location_name_stats: {
avg_length: {
type: 'float',
_meta: {
description:
'This field represents the average length of monitor observer location names',
},
},
max_length: {
type: 'long',
_meta: {
description:
'This field represents the max length of monitor observer location names',
},
},
min_length: {
type: 'long',
_meta: {
description:
'This field represents the min length of monitor observer location names',
},
},
},
overview_page: { type: 'long' },
settings_page: { type: 'long' },
fleet_monitor_name_stats: {
avg_length: {
type: 'float',
_meta: {
description:
'This field represents the average length of fleet managed monitor names',
},
},
max_length: {
type: 'long',
_meta: {
description:
'This field represents the max length of fleet managed monitor names',
},
},
min_length: {
type: 'long',
_meta: {
description:
'This field represents the min length of fleet managed monitor names',
},
},
},
fleet_monitor_frequency: {
type: 'array',
items: {
type: 'long',
_meta: {
description:
'This field represents the average the monitor frequency of fleet managed monitors',
},
},
},
fleet_no_of_unique_monitors: {
type: 'long',
_meta: {
description:
'This field represents the number of unique configured fleet managed monitors',
},
},
},
},
},
fetch: async ({ esClient }: CollectorFetchContext) => {
const savedObjectsClient = getSavedObjectsClient()!;
if (savedObjectsClient) {
const uptimeEsClient = new UptimeEsClient(savedObjectsClient, esClient);
await this.countNoOfUniqueMonitorAndLocations(uptimeEsClient, savedObjectsClient);
await this.countNoOfUniqueFleetManagedMonitors(uptimeEsClient);
}
const report = this.getReport();
return { last_24_hours: { hits: { ...report } } };
},
isReady: () => typeof getSavedObjectsClient() !== 'undefined',
});
}
public static clearLocalTelemetry() {
this.collector = {};
}
public static countPageView(pageView: PageViewParams) {
const bucketId = this.getBucketToIncrement();
const bucket = this.collector[bucketId];
if (pageView.page === 'Overview') {
bucket.overview_page += 1;
}
if (pageView.page === 'Monitor') {
bucket.monitor_page += 1;
}
if (pageView.page === 'Settings') {
bucket.settings_page += 1;
}
this.updateDateData(pageView, bucket);
return bucket;
}
public static updateDateData(
{ dateStart, dateEnd, autoRefreshEnabled, autorefreshInterval }: PageViewParams,
bucket: UptimeTelemetry
) {
const prevDateStart = [...bucket.dateRangeStart].pop();
if (!prevDateStart || prevDateStart !== dateStart) {
bucket.dateRangeStart.push(dateStart);
bucket.dateRangeEnd.push(dateEnd);
} else {
const prevDateEnd = [...bucket.dateRangeEnd].pop();
if (!prevDateEnd || prevDateEnd !== dateEnd) {
bucket.dateRangeStart.push(dateStart);
bucket.dateRangeEnd.push(dateEnd);
}
}
const prevAutorefreshInterval = [...bucket.autorefreshInterval].pop();
if (!prevAutorefreshInterval || prevAutorefreshInterval !== autorefreshInterval) {
bucket.autorefreshInterval.push(autorefreshInterval);
}
bucket.autoRefreshEnabled = autoRefreshEnabled;
}
public static async countNoOfUniqueMonitorAndLocations(
callCluster: UptimeEsClient,
savedObjectsClient: SavedObjectsClientContract
) {
const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(savedObjectsClient);
const params = createEsQuery({
index: dynamicSettings.heartbeatIndices,
body: {
query: {
bool: {
must: [
{
range: {
'@timestamp': {
gte: 'now-1d/d',
lt: 'now',
},
},
},
{
exists: {
field: 'summary',
},
},
],
},
},
size: 0,
aggs: {
unique_monitors: {
cardinality: {
field: 'monitor.id',
},
},
unique_locations: {
cardinality: {
field: 'observer.geo.name',
missing: 'N/A',
},
},
monitor_name: {
string_stats: {
field: 'monitor.name',
},
},
observer_loc_name: {
string_stats: {
field: 'observer.geo.name',
},
},
monitors: {
terms: {
field: 'monitor.id',
size: 1000,
},
aggs: {
docs: {
top_hits: {
size: 1,
_source: ['monitor.timespan'],
},
},
},
},
},
},
});
const { body: result } = await callCluster.search(params, 'telemetryLog');
const numberOfUniqueMonitors: number = result?.aggregations?.unique_monitors?.value ?? 0;
const numberOfUniqueLocations: number = result?.aggregations?.unique_locations?.value ?? 0;
const monitorNameStats = result?.aggregations?.monitor_name;
const locationNameStats = result?.aggregations?.observer_loc_name;
const uniqueMonitors: any = result?.aggregations?.monitors.buckets;
const bucketId = this.getBucketToIncrement();
const bucket = this.collector[bucketId];
bucket.no_of_unique_monitors = numberOfUniqueMonitors;
bucket.no_of_unique_observer_locations = numberOfUniqueLocations;
bucket.no_of_unique_observer_locations = numberOfUniqueLocations;
bucket.monitor_name_stats = {
min_length: monitorNameStats?.min_length ?? 0,
max_length: monitorNameStats?.max_length ?? 0,
avg_length: +(monitorNameStats?.avg_length?.toFixed(2) ?? 0),
};
bucket.observer_location_name_stats = {
min_length: locationNameStats?.min_length ?? 0,
max_length: locationNameStats?.max_length ?? 0,
avg_length: +(locationNameStats?.avg_length?.toFixed(2) ?? 0),
};
bucket.monitor_frequency = this.getMonitorsFrequency(uniqueMonitors);
return bucket;
}
public static async countNoOfUniqueFleetManagedMonitors(callCluster: UptimeEsClient) {
const params = {
index: 'synthetics-*',
body: {
query: {
bool: {
must: [
{
range: {
'@timestamp': {
gte: 'now-1d/d',
lt: 'now',
},
},
},
{
exists: {
field: 'summary',
},
},
{
term: {
'monitor.fleet_managed': true,
},
},
],
},
},
size: 0,
aggs: {
unique_monitors: {
cardinality: {
field: 'monitor.id',
},
},
monitor_name: {
string_stats: {
field: 'monitor.name',
},
},
monitors: {
terms: {
field: 'monitor.id',
size: 1000,
},
aggs: {
docs: {
top_hits: {
size: 1,
_source: ['monitor.timespan'],
},
},
},
},
},
},
};
const { body: result } = await callCluster.search(params, 'telemetryLogFleet');
const numberOfUniqueMonitors: number = result?.aggregations?.unique_monitors?.value ?? 0;
const monitorNameStats = result?.aggregations?.monitor_name;
const uniqueMonitors: any = result?.aggregations?.monitors.buckets;
const bucketId = this.getBucketToIncrement();
const bucket = this.collector[bucketId];
bucket.fleet_no_of_unique_monitors = numberOfUniqueMonitors;
bucket.fleet_monitor_name_stats = {
min_length: monitorNameStats?.min_length ?? 0,
max_length: monitorNameStats?.max_length ?? 0,
avg_length: +(monitorNameStats?.avg_length?.toFixed(2) ?? 0),
};
bucket.fleet_monitor_frequency = this.getMonitorsFrequency(uniqueMonitors);
return bucket;
}
private static getMonitorsFrequency(uniqueMonitors = []) {
const frequencies: number[] = [];
uniqueMonitors
.map((item: any) => item!.docs.hits?.hits?.[0] ?? {})
.forEach((monitor) => {
const timespan = monitor?._source?.monitor?.timespan;
if (timespan) {
const timeDiffSec = moment
.duration(moment(timespan.lt).diff(moment(timespan.gte)))
.asSeconds();
frequencies.push(timeDiffSec);
}
});
return frequencies;
}
private static collector: UptimeTelemetryCollector = {};
private static getReport() {
const minBucket = this.getCollectorWindow();
Object.keys(this.collector)
.map((key) => parseInt(key, 10))
.filter((key) => key < minBucket)
.forEach((oldBucket) => {
delete this.collector[oldBucket];
});
return Object.values(this.collector).reduce(
(acc, cum) =>
Object.assign(cum, {
overview_page: acc.overview_page + cum.overview_page,
monitor_page: acc.monitor_page + cum.monitor_page,
settings_page: acc.settings_page + cum.settings_page,
}),
{ overview_page: 0, monitor_page: 0, settings_page: 0 }
);
}
private static getBucket() {
const nowInSeconds = Math.round(Date.now() / 1000);
return nowInSeconds - (nowInSeconds % BUCKET_SIZE);
}
private static getBucketToIncrement() {
const bucketId = this.getBucket();
if (!this.collector[bucketId]) {
this.collector[bucketId] = {
overview_page: 0,
monitor_page: 0,
no_of_unique_monitors: 0,
settings_page: 0,
monitor_frequency: [],
monitor_name_stats: {
min_length: 0,
max_length: 0,
avg_length: 0,
},
no_of_unique_observer_locations: 0,
observer_location_name_stats: {
min_length: 0,
max_length: 0,
avg_length: 0,
},
dateRangeStart: [],
dateRangeEnd: [],
autoRefreshEnabled: false,
autorefreshInterval: [],
fleet_no_of_unique_monitors: 0,
fleet_monitor_frequency: [],
fleet_monitor_name_stats: {
min_length: 0,
max_length: 0,
avg_length: 0,
},
};
}
return bucketId;
}
private static getCollectorWindow() {
return this.getBucket() - BUCKET_SIZE * (BUCKET_NUMBER - 1);
}
}

View file

@ -1,48 +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.
*/
export interface PageViewParams {
page: string;
dateStart: string;
dateEnd: string;
autoRefreshEnabled: boolean;
autorefreshInterval: number;
refreshTelemetryHistory?: boolean;
refreshEsData?: boolean;
}
export interface Stats {
min_length: number;
max_length: number;
avg_length: number;
}
export interface Usage {
last_24_hours: {
hits: UptimeTelemetry;
};
}
export interface UptimeTelemetry {
overview_page: number;
monitor_page: number;
settings_page: number;
no_of_unique_monitors: number;
monitor_frequency: number[];
no_of_unique_observer_locations: number;
monitor_name_stats: Stats;
observer_location_name_stats: Stats;
dateRangeStart: string[];
dateRangeEnd: string[];
autorefreshInterval: number[];
autoRefreshEnabled: boolean;
fleet_no_of_unique_monitors: number;
fleet_monitor_frequency: number[];
fleet_monitor_name_stats: Stats;
}

View file

@ -13,7 +13,6 @@ import {
createJourneyScreenshotBlocksRoute,
} from './pings';
import { createGetDynamicSettingsRoute, createPostDynamicSettingsRoute } from './dynamic_settings';
import { createLogPageViewRoute } from './telemetry';
import { createGetSnapshotCount } from './snapshot';
import { UMRestApiRouteFactory } from './types';
import {
@ -42,7 +41,6 @@ export const legacyUptimeRestApiRoutes: UMRestApiRouteFactory[] = [
createMonitorListRoute,
createGetStatusBarRoute,
createGetSnapshotCount,
createLogPageViewRoute,
createGetPingHistogramRoute,
createGetMonitorDurationRoute,
createJourneyRoute,

View file

@ -1,8 +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.
*/
export { createLogPageViewRoute } from './log_page_view';

View file

@ -1,46 +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 { schema } from '@kbn/config-schema';
import { KibanaTelemetryAdapter } from '../../lib/adapters/telemetry';
import { UMRestApiRouteFactory } from '../types';
import { PageViewParams } from '../../lib/adapters/telemetry/types';
import { API_URLS } from '../../../../common/constants';
export const createLogPageViewRoute: UMRestApiRouteFactory = () => ({
method: 'POST',
path: API_URLS.LOG_PAGE_VIEW,
validate: {
body: schema.object({
page: schema.string(),
dateStart: schema.string(),
dateEnd: schema.string(),
autoRefreshEnabled: schema.boolean(),
autorefreshInterval: schema.number(),
refreshEsData: schema.maybe(schema.boolean()),
refreshTelemetryHistory: schema.maybe(schema.boolean()),
}),
},
handler: async ({ savedObjectsClient, uptimeEsClient, request }): Promise<any> => {
const pageView = request.body as PageViewParams;
if (pageView.refreshTelemetryHistory) {
// this is primarily only used for API testing
KibanaTelemetryAdapter.clearLocalTelemetry();
}
if (pageView.refreshEsData) {
// this is primarily only used for API testing
await KibanaTelemetryAdapter.countNoOfUniqueMonitorAndLocations(
uptimeEsClient,
savedObjectsClient
);
}
await KibanaTelemetryAdapter.countNoOfUniqueFleetManagedMonitors(uptimeEsClient);
return KibanaTelemetryAdapter.countPageView(pageView as PageViewParams);
},
});

View file

@ -20,7 +20,6 @@ import { initSyntheticsServer } from './server';
import { initUptimeServer } from './legacy_uptime/uptime_server';
import { uptimeFeature } from './feature';
import {
KibanaTelemetryAdapter,
UptimeCorePluginsSetup,
UptimeCorePluginsStart,
UptimeServerSetup,
@ -101,11 +100,6 @@ export class Plugin implements PluginType {
registerUptimeSavedObjects(core.savedObjects, plugins.encryptedSavedObjects);
KibanaTelemetryAdapter.registerUsageCollector(
plugins.usageCollection,
() => this.savedObjectsClient
);
return {
ruleRegistry: ruleDataClient,
};

View file

@ -14416,147 +14416,6 @@
}
}
},
"uptime": {
"properties": {
"last_24_hours": {
"properties": {
"hits": {
"properties": {
"autoRefreshEnabled": {
"type": "boolean"
},
"autorefreshInterval": {
"type": "array",
"items": {
"type": "long"
}
},
"dateRangeEnd": {
"type": "array",
"items": {
"type": "date"
}
},
"dateRangeStart": {
"type": "array",
"items": {
"type": "date"
}
},
"monitor_frequency": {
"type": "array",
"items": {
"type": "long"
}
},
"monitor_name_stats": {
"properties": {
"avg_length": {
"type": "float",
"_meta": {
"description": "This field represents the average length of monitor names"
}
},
"max_length": {
"type": "long",
"_meta": {
"description": "This field represents the max length of monitor names"
}
},
"min_length": {
"type": "long",
"_meta": {
"description": "This field represents the min length of monitor names"
}
}
}
},
"monitor_page": {
"type": "long"
},
"no_of_unique_monitors": {
"type": "long",
"_meta": {
"description": "This field represents the number of unique configured monitors"
}
},
"no_of_unique_observer_locations": {
"type": "long",
"_meta": {
"description": "This field represents the number of unique monitor observer locations"
}
},
"observer_location_name_stats": {
"properties": {
"avg_length": {
"type": "float",
"_meta": {
"description": "This field represents the average length of monitor observer location names"
}
},
"max_length": {
"type": "long",
"_meta": {
"description": "This field represents the max length of monitor observer location names"
}
},
"min_length": {
"type": "long",
"_meta": {
"description": "This field represents the min length of monitor observer location names"
}
}
}
},
"overview_page": {
"type": "long"
},
"settings_page": {
"type": "long"
},
"fleet_monitor_name_stats": {
"properties": {
"avg_length": {
"type": "float",
"_meta": {
"description": "This field represents the average length of fleet managed monitor names"
}
},
"max_length": {
"type": "long",
"_meta": {
"description": "This field represents the max length of fleet managed monitor names"
}
},
"min_length": {
"type": "long",
"_meta": {
"description": "This field represents the min length of fleet managed monitor names"
}
}
}
},
"fleet_monitor_frequency": {
"type": "array",
"items": {
"type": "long",
"_meta": {
"description": "This field represents the average the monitor frequency of fleet managed monitors"
}
}
},
"fleet_no_of_unique_monitors": {
"type": "long",
"_meta": {
"description": "This field represents the number of unique configured fleet managed monitors"
}
}
}
}
}
}
}
},
"workplace_search": {
"properties": {
"ui_viewed": {

View file

@ -49,8 +49,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./dynamic_settings'));
loadTestFile(require.resolve('./snapshot'));
loadTestFile(require.resolve('./monitor_states_generated'));
loadTestFile(require.resolve('./telemetry_collectors'));
loadTestFile(require.resolve('./telemetry_collectors_fleet'));
});
describe('with real-world data', () => {

View file

@ -1,155 +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 expect from '@kbn/expect';
import { API_URLS } from '@kbn/synthetics-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { makeChecksWithStatus } from './helper/make_checks';
export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const es = getService('es');
describe('telemetry collectors heartbeat', () => {
before('generating data', async () => {
await getService('esArchiver').load('x-pack/test/functional/es_archives/uptime/blank');
const observer = {
geo: {
name: 'US-East',
location: '40.7128, -74.0060',
},
};
const observer2 = {
geo: {
name: 'US',
location: '40.7128, -74.0060',
},
};
await makeChecksWithStatus(
es,
'upMonitorId',
1,
1,
60 * 1000,
{
observer: {},
monitor: {
name: 'Elastic',
},
},
'up'
);
await makeChecksWithStatus(
es,
'downMonitorId',
1,
1,
120 * 1000,
{
observer,
monitor: {
name: 'Long Name with 22 Char',
},
},
'down'
);
await makeChecksWithStatus(es, 'noGeoNameMonitor', 1, 1, 60 * 1000, { observer: {} }, 'down');
await makeChecksWithStatus(
es,
'downMonitorId',
1,
1,
10 * 1000,
{
observer,
monitor: {
name: 'Elastic',
},
},
'down'
);
await makeChecksWithStatus(
es,
'mixMonitorId',
1,
1,
30 * 1000,
{ observer: observer2 },
'down'
);
await es.indices.refresh();
});
after('unload heartbeat index', () => {
getService('esArchiver').unload('x-pack/test/functional/es_archives/uptime/blank');
});
beforeEach(async () => {
await es.indices.refresh();
});
it('should receive expected results after calling monitor logging', async () => {
// call monitor page
const { body: result } = await supertest
.post(API_URLS.LOG_PAGE_VIEW)
.set('kbn-xsrf', 'true')
.send({
page: 'Monitor',
autorefreshInterval: 100,
dateStart: 'now/d',
dateEnd: 'now/d',
autoRefreshEnabled: true,
refreshTelemetryHistory: true,
refreshEsData: true,
})
.expect(200);
expect(result).to.eql({
overview_page: 0,
monitor_page: 1,
no_of_unique_monitors: 4,
settings_page: 0,
monitor_frequency: [10, 30, 60, 60],
monitor_name_stats: { min_length: 7, max_length: 22, avg_length: 12 },
no_of_unique_observer_locations: 3,
observer_location_name_stats: { min_length: 2, max_length: 7, avg_length: 4.8 },
dateRangeStart: ['now/d'],
dateRangeEnd: ['now/d'],
autoRefreshEnabled: true,
autorefreshInterval: [100],
fleet_monitor_frequency: [],
fleet_monitor_name_stats: {
avg_length: 0,
max_length: 0,
min_length: 0,
},
fleet_no_of_unique_monitors: 0,
});
});
it('should receive 200 status after overview logging', async () => {
// call overview page
await supertest
.post(API_URLS.LOG_PAGE_VIEW)
.set('kbn-xsrf', 'true')
.send({
page: 'Overview',
autorefreshInterval: 60,
dateStart: 'now/d',
dateEnd: 'now-30',
autoRefreshEnabled: true,
})
.expect(200);
});
});
}

View file

@ -1,216 +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 expect from '@kbn/expect';
import { API_URLS } from '@kbn/synthetics-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
import { makeChecksWithStatus } from './helper/make_checks';
export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const client = getService('es');
const testDataStreamName = 'synthetics-http-default';
describe('telemetry collectors fleet', () => {
const createDataStream = async (name: string) => {
// A data stream requires an index template before it can be created.
await client.indices.putIndexTemplate({
name,
body: {
// We need to match the names of backing indices with this template.
index_patterns: [name + '*'],
template: {
mappings: {
properties: {
'@timestamp': {
type: 'date',
},
},
},
},
data_stream: {},
},
});
await client.indices.createDataStream({ name });
};
const deleteComposableIndexTemplate = async (name: string) => {
await client.indices.deleteIndexTemplate({ name });
};
const deleteDataStream = async (name: string) => {
await client.indices.deleteDataStream({ name });
await deleteComposableIndexTemplate(name);
};
before('generating data', async () => {
await createDataStream(testDataStreamName);
const observer = {
geo: {
name: 'US-East',
location: '40.7128, -74.0060',
},
};
const observer2 = {
geo: {
name: 'US',
location: '40.7128, -74.0060',
},
};
await makeChecksWithStatus(
client,
'upMonitorId',
1,
1,
60 * 1000,
{
observer: {},
monitor: {
name: 'Elastic',
fleet_managed: true,
},
},
'up',
undefined,
undefined,
testDataStreamName
);
await makeChecksWithStatus(
client,
'downMonitorId',
1,
1,
120 * 1000,
{
observer,
monitor: {
name: 'Long Name with 22 Char',
fleet_managed: true,
},
},
'down',
undefined,
undefined,
testDataStreamName
);
await makeChecksWithStatus(
client,
'noGeoNameMonitor',
1,
1,
60 * 1000,
{
observer: {},
monitor: {
fleet_managed: true,
},
},
'down',
undefined,
undefined,
testDataStreamName
);
await makeChecksWithStatus(
client,
'downMonitorId',
1,
1,
1,
{
observer,
monitor: {
name: 'Elastic',
fleet_managed: true,
},
},
'down',
undefined,
undefined,
testDataStreamName
);
await makeChecksWithStatus(
client,
'mixMonitorId',
1,
1,
1,
{ observer: observer2, monitor: { fleet_managed: true } },
'down',
undefined,
undefined,
testDataStreamName
);
await client.indices.refresh();
});
after('unload heartbeat index', async () => {
await deleteDataStream(testDataStreamName);
});
beforeEach(async () => {
await client.indices.refresh();
});
it('should receive expected results for fleet managed monitors after calling monitor logging', async () => {
// call monitor page
const { body: result } = await supertest
.post(API_URLS.LOG_PAGE_VIEW)
.set('kbn-xsrf', 'true')
.send({
page: 'Monitor',
autorefreshInterval: 100,
dateStart: 'now/d',
dateEnd: 'now/d',
autoRefreshEnabled: true,
refreshTelemetryHistory: true,
refreshEsData: true,
})
.expect(200);
expect(result).to.eql({
overview_page: 0,
monitor_page: 1,
no_of_unique_monitors: 4,
settings_page: 0,
monitor_frequency: [0.001, 0.001, 60, 60],
monitor_name_stats: { min_length: 7, max_length: 22, avg_length: 12 },
no_of_unique_observer_locations: 3,
observer_location_name_stats: { min_length: 2, max_length: 7, avg_length: 4.8 },
dateRangeStart: ['now/d'],
dateRangeEnd: ['now/d'],
autoRefreshEnabled: true,
autorefreshInterval: [100],
fleet_monitor_frequency: [0.001, 0.001, 60, 60],
fleet_monitor_name_stats: { min_length: 7, max_length: 22, avg_length: 12 },
fleet_no_of_unique_monitors: 4,
});
});
it('should receive 200 status after overview logging', async () => {
// call overview page
await supertest
.post(API_URLS.LOG_PAGE_VIEW)
.set('kbn-xsrf', 'true')
.send({
page: 'Overview',
autorefreshInterval: 60,
dateStart: 'now/d',
dateEnd: 'now-30',
autoRefreshEnabled: true,
})
.expect(200);
});
});
}