Skip to content

Commit

Permalink
[Uptime] Hide app if no data is available (#159118)
Browse files Browse the repository at this point in the history
Co-authored-by: florent-leborgne <[email protected]>
  • Loading branch information
shahzad31 and florent-leborgne authored Jun 13, 2023
1 parent e893133 commit ea77b0d
Show file tree
Hide file tree
Showing 15 changed files with 146 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -561,4 +561,8 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'observability:enableLegacyUptimeApp': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export interface UsageStats {
isDefaultIndexMigrated: boolean;
'metrics:allowCheckingForFailedShards': boolean;
'observability:syntheticsThrottlingEnabled': boolean;
'observability:enableLegacyUptimeApp': boolean;
'observability:apmLabsButton': boolean;
'observability:enableAwsLambdaMetrics': boolean;
'observability:apmProgressiveLoading': string;
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/telemetry/schema/oss_plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -9494,6 +9494,12 @@
"_meta": {
"description": "Non-default value of setting."
}
},
"observability:enableLegacyUptimeApp": {
"type": "boolean",
"_meta": {
"description": "Non-default value of setting."
}
}
}
},
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/observability/common/ui_settings_keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export const enableCriticalPath = 'observability:apmEnableCriticalPath';
export const apmEnableServiceMetrics = 'observability:apmEnableServiceMetrics';
export const apmEnableContinuousRollups = 'observability:apmEnableContinuousRollups';
export const syntheticsThrottlingEnabled = 'observability:syntheticsThrottlingEnabled';
export const enableLegacyUptimeApp = 'observability:enableLegacyUptimeApp';
1 change: 1 addition & 0 deletions x-pack/plugins/observability/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const plugin: PluginInitializer<
};

export {
enableLegacyUptimeApp,
syntheticsThrottlingEnabled,
enableInspectEsQueries,
enableComparisonByDefault,
Expand Down
14 changes: 14 additions & 0 deletions x-pack/plugins/observability/server/ui_settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
enableCriticalPath,
enableInfrastructureHostsView,
syntheticsThrottlingEnabled,
enableLegacyUptimeApp,
} from '../common/ui_settings_keys';

const betaLabel = i18n.translate('xpack.observability.uiSettings.betaLabel', {
Expand Down Expand Up @@ -346,6 +347,19 @@ export const uiSettings: Record<string, UiSettings> = {
schema: schema.boolean(),
requiresPageReload: true,
},
[enableLegacyUptimeApp]: {
category: [observabilityFeatureId],
name: i18n.translate('xpack.observability.enableLegacyUptimeApp', {
defaultMessage: 'Always show legacy Uptime app',
}),
value: false,
description: i18n.translate('xpack.observability.enableLegacyUptimeAppDescription', {
defaultMessage:
"By default, the legacy Uptime app is hidden from the interface when it doesn't have any data for more than a week. Enable this option to always show it.",
}),
schema: schema.boolean(),
requiresPageReload: true,
},
};

function throttlingDocsLink({ href }: { href: string }) {
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/observability_shared/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class ObservabilitySharedPlugin implements Plugin {
return {
navigation: {
PageTemplate,
registerSections: this.navigationRegistry.registerSections,
},
updateGlobalNavigation,
setIsSidebarEnabled: (isEnabled: boolean) => this.isSidebarEnabled$.next(isEnabled),
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/synthetics/e2e/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ async function config({ readConfigFile }: FtrConfigProviderContext) {
}`,
`--xpack.uptime.service.password=${servicePassword}`,
`--xpack.uptime.service.showExperimentalLocations=${true}`,
'--uiSettings.overrides.observability:enableLegacyUptimeApp=true',
],
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { apiService } from './utils';

let indexStatusPromise: Promise<{ indexExists: boolean; indices: string }> | null = null;

export const fetchIndexStatus = async (): Promise<StatesIndexStatus> => {
export const fetchIndexStatus = async (from?: string, to?: string): Promise<StatesIndexStatus> => {
if (indexStatusPromise) {
return indexStatusPromise;
}
indexStatusPromise = apiService.get(API_URLS.INDEX_STATUS, undefined, StatesIndexStatusType);
indexStatusPromise = apiService.get(API_URLS.INDEX_STATUS, { from, to }, StatesIndexStatusType);
indexStatusPromise.then(
() => {
indexStatusPromise = null;
Expand Down
102 changes: 63 additions & 39 deletions x-pack/plugins/synthetics/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
PluginInitializerContext,
AppMountParameters,
} from '@kbn/core/public';
import { from } from 'rxjs';
import { BehaviorSubject, from } from 'rxjs';
import { map } from 'rxjs/operators';
import { i18n } from '@kbn/i18n';
import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public';
Expand All @@ -34,6 +34,7 @@ import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/p

import { FleetStart } from '@kbn/fleet-plugin/public';
import {
enableLegacyUptimeApp,
FetchDataParams,
ObservabilityPublicSetup,
ObservabilityPublicStart,
Expand All @@ -50,6 +51,7 @@ import type {
ObservabilitySharedPluginSetup,
ObservabilitySharedPluginStart,
} from '@kbn/observability-shared-plugin/public';
import { AppStatus, AppUpdater } from '@kbn/core-application-browser';
import { PLUGIN } from '../common/constants/plugin';
import { OVERVIEW_ROUTE } from '../common/constants/ui';
import {
Expand Down Expand Up @@ -118,6 +120,8 @@ export class UptimePlugin
{
constructor(private readonly initContext: PluginInitializerContext) {}

private uptimeAppUpdater = new BehaviorSubject<AppUpdater>(() => ({}));

public setup(core: CoreSetup<ClientPluginsStart, unknown>, plugins: ClientPluginsSetup): void {
if (plugins.home) {
plugins.home.featureCatalogue.register({
Expand Down Expand Up @@ -167,7 +171,6 @@ export class UptimePlugin
},
});

registerUptimeRoutesWithNavigation(core, plugins);
registerSyntheticsRoutesWithNavigation(core, plugins);

core.getStartServices().then(([coreStart, clientPluginsStart]) => {});
Expand All @@ -193,6 +196,7 @@ export class UptimePlugin
core.application.register({
id: PLUGIN.ID,
euiIconType: 'logoObservability',

order: 8400,
title: PLUGIN.TITLE,
category: DEFAULT_APP_CATEGORIES.observability,
Expand All @@ -207,6 +211,7 @@ export class UptimePlugin
const { renderApp } = await import('./legacy_uptime/app/render_app');
return renderApp(coreStart, plugins, corePlugins, params, this.initContext.env.mode.dev);
},
updater$: this.uptimeAppUpdater,
});

// Register the Synthetics UI plugin
Expand Down Expand Up @@ -267,50 +272,45 @@ export class UptimePlugin
triggersActionsUi.ruleTypeRegistry.register(alertInitializer);
}
});

setUptimeAppStatus(coreStart, pluginsStart, this.uptimeAppUpdater);
}

public stop(): void {}
}

function registerUptimeRoutesWithNavigation(
core: CoreSetup<ClientPluginsStart, unknown>,
plugins: ClientPluginsSetup
) {
plugins.observabilityShared.navigation.registerSections(
from(core.getStartServices()).pipe(
map(([coreStart]) => {
if (coreStart.application.capabilities.uptime.show) {
return [
function registerUptimeRoutesWithNavigation(coreStart: CoreStart, plugins: ClientPluginsStart) {
async function getUptimeSections() {
if (coreStart.application.capabilities.uptime.show) {
return [
{
label: 'Uptime',
sortKey: 500,
entries: [
{
label: 'Uptime',
sortKey: 500,
entries: [
{
label: i18n.translate('xpack.synthetics.overview.uptimeHeading', {
defaultMessage: 'Uptime Monitors',
}),
app: 'uptime',
path: '/',
matchFullPath: true,
ignoreTrailingSlash: true,
},
{
label: i18n.translate('xpack.synthetics.certificatesPage.heading', {
defaultMessage: 'TLS Certificates',
}),
app: 'uptime',
path: '/certificates',
matchFullPath: true,
},
],
label: i18n.translate('xpack.synthetics.overview.uptimeHeading', {
defaultMessage: 'Uptime Monitors',
}),
app: 'uptime',
path: '/',
matchFullPath: true,
ignoreTrailingSlash: true,
},
];
}

return [];
})
)
);
{
label: i18n.translate('xpack.synthetics.certificatesPage.heading', {
defaultMessage: 'TLS Certificates',
}),
app: 'uptime',
path: '/certificates',
matchFullPath: true,
},
],
},
];
}
return [];
}
plugins.observabilityShared.navigation.registerSections(from(getUptimeSections()));
}

function registerSyntheticsRoutesWithNavigation(
Expand Down Expand Up @@ -367,3 +367,27 @@ function registerUptimeFleetExtensions(registerExtension: FleetStart['registerEx
Component: LazySyntheticsCustomAssetsExtension,
});
}

function setUptimeAppStatus(
coreStart: CoreStart,
pluginsStart: ClientPluginsStart,
updater: BehaviorSubject<AppUpdater>
) {
import('./legacy_uptime/app/uptime_overview_fetcher').then(({ UptimeDataHelper }) => {
const isEnabled = coreStart.uiSettings.get<boolean>(enableLegacyUptimeApp);
if (isEnabled) {
registerUptimeRoutesWithNavigation(coreStart, pluginsStart);
updater.next(() => ({ status: AppStatus.accessible }));
} else {
const indexStatusPromise = UptimeDataHelper(coreStart).indexStatus('now-7d', 'now');
indexStatusPromise.then((indexStatus) => {
if (indexStatus.indexExists) {
registerUptimeRoutesWithNavigation(coreStart, pluginsStart);
updater.next(() => ({ status: AppStatus.accessible }));
} else {
updater.next(() => ({ status: AppStatus.inaccessible }));
}
});
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,41 @@
* 2.0.
*/

import { UMElasticsearchQueryFn } from '../adapters';
import { UptimeEsClient } from '../lib';
import { StatesIndexStatus } from '../../../../common/runtime_types';

export const getIndexStatus: UMElasticsearchQueryFn<{}, StatesIndexStatus> = async ({
export const getIndexStatus = async ({
uptimeEsClient,
}) => {
range,
}: {
uptimeEsClient: UptimeEsClient;
range?: { to: string; from: string };
}): Promise<StatesIndexStatus> => {
const { to, from } = range || {};
try {
const {
indices,
result: {
body: {
_shards: { total },
},
body: { count },
},
} = await uptimeEsClient.count({ terminate_after: 1 });
} = await uptimeEsClient.count({
terminate_after: 1,
...(to && from
? {
query: {
range: {
'@timestamp': {
gte: from,
lte: to,
},
},
},
}
: {}),
});
return {
indices,
indexExists: total > 0,
indexExists: count > 0,
};
} catch (e) {
if (e.meta?.statusCode === 404) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@
* 2.0.
*/

import { schema } from '@kbn/config-schema';
import { UMServerLibs } from '../../lib/lib';
import { UMRestApiRouteFactory } from '../types';
import { API_URLS } from '../../../../common/constants';

export const createGetIndexStatusRoute: UMRestApiRouteFactory = (libs: UMServerLibs) => ({
method: 'GET',
path: API_URLS.INDEX_STATUS,
validate: {},
handler: async ({ uptimeEsClient }): Promise<any> => {
return await libs.requests.getIndexStatus({ uptimeEsClient });
validate: {
query: schema.object({
from: schema.maybe(schema.string()),
to: schema.maybe(schema.string()),
}),
},
handler: async ({ uptimeEsClient, request }): Promise<any> => {
const { from, to } = request.query;
return await libs.requests.getIndexStatus({ uptimeEsClient, range: { from, to } });
},
});
1 change: 1 addition & 0 deletions x-pack/plugins/synthetics/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"@kbn/observability-shared-plugin",
"@kbn/ml-error-utils",
"@kbn/ml-anomaly-utils",
"@kbn/core-application-browser",
"@kbn/std",
],
"exclude": [
Expand Down
11 changes: 9 additions & 2 deletions x-pack/test/functional/apps/uptime/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@
import { FtrConfigProviderContext } from '@kbn/test';

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const functionalConfig = await readConfigFile(require.resolve('../../config.base.js'));
const baseIntegrationTestsConfig = await readConfigFile(require.resolve('../../config.base.js'));

return {
...functionalConfig.getAll(),
...baseIntegrationTestsConfig.getAll(),
kbnTestServer: {
...baseIntegrationTestsConfig.get('kbnTestServer'),
serverArgs: [
...baseIntegrationTestsConfig.get('kbnTestServer.serverArgs'),
'--uiSettings.overrides.observability:enableLegacyUptimeApp=true',
],
},
testFiles: [require.resolve('.')],
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {

return {
...baseConfig.getAll(),
kbnTestServer: {
...baseConfig.get('kbnTestServer'),
serverArgs: [
...baseConfig.get('kbnTestServer.serverArgs'),
'--uiSettings.overrides.observability:enableLegacyUptimeApp=true',
],
},
testFiles: [
resolve(__dirname, './discover'),
resolve(__dirname, './uptime'),
Expand Down

0 comments on commit ea77b0d

Please sign in to comment.