mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Infra UI] Disable infra logs UI in serverless (#168011)
closes https://github.com/elastic/kibana/issues/166977 ## Summary This PR creates a feature flag to disable logs UI features in serverless. _Serverless_ **Frontend routes** <img width="1466" alt="image" src="a856055b
-f78b-4d47-b27e-678e19bdfae4"> `/logs/stream` <img width="1714" alt="image" src="83d50be2
-ed3a-4441-b31c-1afe6f8fd0b9"> `/logs/log-categories` <img width="1714" alt="image" src="85cd369d
-55b2-46a2-a61a-135c5f18e299"> `/logs/anomalies` <img width="1714" alt="image" src="d68e6f91
-fe29-483f-931d-d05f4303effa"> **Server routes** These will return 404 ``` POST kbn://api/infra/log_analysis/results/log_entry_anomalies_datasets POST kbn://api/infra/log_analysis/results/log_entry_anomalies POST kbn://api/infra/log_analysis/results/log_entry_categories POST kbn://api/infra/log_analysis/results/latest_log_entry_category_datasets_stats POST kbn://api/infra/log_analysis/results/log_entry_category_datasets POST kbn://api/infra/log_analysis/results/log_entry_category_examples POST kbn://api/infra/log_analysis/results/log_entry_examples POST kbn://api/infra/log_analysis/results/log_entry_datasets POST kbn://api/infra/log_analysis/results/log_entry_rate_indices POST kbn://api/infra/log_alerts/chart_preview_data ``` _Stateful_ <img width="1716" alt="image" src="4406434f
-78e4-437f-b3b5-1b03dc23f3c0"> **Server routes** These will return 400 - currently there is no way to pass `version` via dev tools ``` POST kbn://api/infra/log_analysis/results/log_entry_anomalies_datasets POST kbn://api/infra/log_analysis/results/log_entry_anomalies POST kbn://api/infra/log_analysis/results/log_entry_categories POST kbn://api/infra/log_analysis/results/latest_log_entry_category_datasets_stats POST kbn://api/infra/log_analysis/results/log_entry_category_datasets POST kbn://api/infra/log_analysis/results/log_entry_category_examples POST kbn://api/infra/log_analysis/results/log_entry_examples POST kbn://api/infra/log_analysis/results/log_entry_datasets POST kbn://api/infra/log_analysis/results/log_entry_rate_indices POST kbn://api/infra/log_alerts/chart_preview_data ``` ### How to test ### How to test - Start a local es instance: `yarn es serverless --kill --clean --license trial --ssl` - Enable `infra` in the `serverless.oblt.dev.yml` file: - `xpack.infra.enabled: true` - Start a local kibana instance: `yarn serverless-oblt --ssl` - Verify the items listed above both on serverless and stateful
This commit is contained in:
parent
5d660f900f
commit
2f8ce938be
17 changed files with 149 additions and 93 deletions
|
@ -267,16 +267,21 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.index_management.enableLegacyTemplates (any)',
|
||||
'xpack.index_management.enableIndexStats (any)',
|
||||
'xpack.infra.sources.default.fields.message (array)',
|
||||
/**
|
||||
* xpack.infra.featureFlags.metricsExplorerEnabled is conditional based on traditional/serverless offering
|
||||
* and will resolve to (boolean)
|
||||
*/
|
||||
'xpack.infra.featureFlags.metricsExplorerEnabled (any)',
|
||||
/**
|
||||
* xpack.infra.featureFlags.customThresholdAlertsEnabled is conditional based on traditional/serverless offering
|
||||
* and will resolve to (boolean)
|
||||
*/
|
||||
'xpack.infra.featureFlags.customThresholdAlertsEnabled (any)',
|
||||
/**
|
||||
* xpack.infra.featureFlags.logsUIEnabled is conditional based on traditional/serverless offering
|
||||
* and will resolve to (boolean)
|
||||
*/
|
||||
'xpack.infra.featureFlags.logsUIEnabled (any)',
|
||||
/**
|
||||
* xpack.infra.featureFlags.metricsExplorerEnabled is conditional based on traditional/serverless offering
|
||||
* and will resolve to (boolean)
|
||||
*/
|
||||
'xpack.infra.featureFlags.metricsExplorerEnabled (any)',
|
||||
/**
|
||||
* xpack.infra.featureFlags.osqueryEnabled is conditional based on traditional/serverless offering
|
||||
* and will resolve to (boolean)
|
||||
|
|
|
@ -26,8 +26,9 @@ export interface InfraConfig {
|
|||
};
|
||||
};
|
||||
featureFlags: {
|
||||
metricsExplorerEnabled: boolean;
|
||||
customThresholdAlertsEnabled: boolean;
|
||||
logsUIEnabled: boolean;
|
||||
metricsExplorerEnabled: boolean;
|
||||
osqueryEnabled: boolean;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,9 +20,10 @@ describe('usePluginConfig()', () => {
|
|||
it('returns the plugin config what was set through the provider', () => {
|
||||
const config: Partial<InfraConfig> = {
|
||||
featureFlags: {
|
||||
customThresholdAlertsEnabled: true,
|
||||
logsUIEnabled: false,
|
||||
metricsExplorerEnabled: false,
|
||||
osqueryEnabled: false,
|
||||
customThresholdAlertsEnabled: true,
|
||||
},
|
||||
};
|
||||
const { result } = renderHook(() => usePluginConfig(), {
|
||||
|
|
|
@ -85,18 +85,21 @@ export class Plugin implements InfraClientPluginClass {
|
|||
pluginsSetup.observability.observabilityRuleTypeRegistry.register(
|
||||
createMetricThresholdRuleType()
|
||||
);
|
||||
pluginsSetup.observability.dashboard.register({
|
||||
appName: 'infra_logs',
|
||||
hasData: getLogsHasDataFetcher(core.getStartServices),
|
||||
fetchData: getLogsOverviewDataFetcher(core.getStartServices),
|
||||
});
|
||||
|
||||
if (this.config.featureFlags.logsUIEnabled) {
|
||||
// fetchData `appLink` redirects to logs/stream
|
||||
pluginsSetup.observability.dashboard.register({
|
||||
appName: 'infra_logs',
|
||||
hasData: getLogsHasDataFetcher(core.getStartServices),
|
||||
fetchData: getLogsOverviewDataFetcher(core.getStartServices),
|
||||
});
|
||||
}
|
||||
|
||||
pluginsSetup.observability.dashboard.register({
|
||||
appName: 'infra_metrics',
|
||||
hasData: createMetricsHasData(core.getStartServices),
|
||||
fetchData: createMetricsFetchData(core.getStartServices),
|
||||
});
|
||||
|
||||
pluginsSetup.logsShared.logViews.setLogViewsStaticConfig({
|
||||
messageFields: this.config.sources?.default?.fields?.message,
|
||||
});
|
||||
|
@ -107,13 +110,6 @@ export class Plugin implements InfraClientPluginClass {
|
|||
]);
|
||||
|
||||
/** !! Need to be kept in sync with the deepLinks in x-pack/plugins/infra/public/plugin.ts */
|
||||
const infraEntries = [
|
||||
{ label: 'Inventory', app: 'metrics', path: '/inventory' },
|
||||
...(this.config.featureFlags.metricsExplorerEnabled
|
||||
? [{ label: 'Metrics Explorer', app: 'metrics', path: '/explorer' }]
|
||||
: []),
|
||||
{ label: 'Hosts', isBetaFeature: true, app: 'metrics', path: '/hosts' },
|
||||
];
|
||||
pluginsSetup.observabilityShared.navigation.registerSections(
|
||||
startDep$AndHostViewFlag$.pipe(
|
||||
map(
|
||||
|
@ -136,9 +132,13 @@ export class Plugin implements InfraClientPluginClass {
|
|||
path: '/',
|
||||
isBetaFeature: true,
|
||||
},
|
||||
{ label: 'Stream', app: 'logs', path: '/stream' },
|
||||
{ label: 'Anomalies', app: 'logs', path: '/anomalies' },
|
||||
{ label: 'Categories', app: 'logs', path: '/log-categories' },
|
||||
...(this.config.featureFlags.logsUIEnabled
|
||||
? [
|
||||
{ label: 'Stream', app: 'logs', path: '/stream' },
|
||||
{ label: 'Anomalies', app: 'logs', path: '/anomalies' },
|
||||
{ label: 'Categories', app: 'logs', path: '/log-categories' },
|
||||
]
|
||||
: []),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
@ -148,7 +148,13 @@ export class Plugin implements InfraClientPluginClass {
|
|||
{
|
||||
label: 'Infrastructure',
|
||||
sortKey: 300,
|
||||
entries: infraEntries,
|
||||
entries: [
|
||||
{ label: 'Inventory', app: 'metrics', path: '/inventory' },
|
||||
...(this.config.featureFlags.metricsExplorerEnabled
|
||||
? [{ label: 'Metrics Explorer', app: 'metrics', path: '/explorer' }]
|
||||
: []),
|
||||
{ label: 'Hosts', isBetaFeature: true, app: 'metrics', path: '/hosts' },
|
||||
],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
|
@ -172,54 +178,56 @@ export class Plugin implements InfraClientPluginClass {
|
|||
createLogThresholdRuleType(core, logsLocator)
|
||||
);
|
||||
|
||||
core.application.register({
|
||||
id: 'logs',
|
||||
title: i18n.translate('xpack.infra.logs.pluginTitle', {
|
||||
defaultMessage: 'Logs',
|
||||
}),
|
||||
euiIconType: 'logoObservability',
|
||||
order: 8100,
|
||||
appRoute: '/app/logs',
|
||||
// !! Need to be kept in sync with the routes in x-pack/plugins/infra/public/pages/logs/page_content.tsx
|
||||
deepLinks: [
|
||||
{
|
||||
id: 'stream',
|
||||
title: i18n.translate('xpack.infra.logs.index.streamTabTitle', {
|
||||
defaultMessage: 'Stream',
|
||||
}),
|
||||
path: '/stream',
|
||||
},
|
||||
{
|
||||
id: 'anomalies',
|
||||
title: i18n.translate('xpack.infra.logs.index.anomaliesTabTitle', {
|
||||
defaultMessage: 'Anomalies',
|
||||
}),
|
||||
path: '/anomalies',
|
||||
},
|
||||
{
|
||||
id: 'log-categories',
|
||||
title: i18n.translate('xpack.infra.logs.index.logCategoriesBetaBadgeTitle', {
|
||||
defaultMessage: 'Categories',
|
||||
}),
|
||||
path: '/log-categories',
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
title: i18n.translate('xpack.infra.logs.index.settingsTabTitle', {
|
||||
defaultMessage: 'Settings',
|
||||
}),
|
||||
path: '/settings',
|
||||
},
|
||||
],
|
||||
category: DEFAULT_APP_CATEGORIES.observability,
|
||||
mount: async (params: AppMountParameters) => {
|
||||
// mount callback should not use setup dependencies, get start dependencies instead
|
||||
const [coreStart, plugins, pluginStart] = await core.getStartServices();
|
||||
if (this.config.featureFlags.logsUIEnabled) {
|
||||
core.application.register({
|
||||
id: 'logs',
|
||||
title: i18n.translate('xpack.infra.logs.pluginTitle', {
|
||||
defaultMessage: 'Logs',
|
||||
}),
|
||||
euiIconType: 'logoObservability',
|
||||
order: 8100,
|
||||
appRoute: '/app/logs',
|
||||
// !! Need to be kept in sync with the routes in x-pack/plugins/infra/public/pages/logs/page_content.tsx
|
||||
deepLinks: [
|
||||
{
|
||||
id: 'stream',
|
||||
title: i18n.translate('xpack.infra.logs.index.streamTabTitle', {
|
||||
defaultMessage: 'Stream',
|
||||
}),
|
||||
path: '/stream',
|
||||
},
|
||||
{
|
||||
id: 'anomalies',
|
||||
title: i18n.translate('xpack.infra.logs.index.anomaliesTabTitle', {
|
||||
defaultMessage: 'Anomalies',
|
||||
}),
|
||||
path: '/anomalies',
|
||||
},
|
||||
{
|
||||
id: 'log-categories',
|
||||
title: i18n.translate('xpack.infra.logs.index.logCategoriesBetaBadgeTitle', {
|
||||
defaultMessage: 'Categories',
|
||||
}),
|
||||
path: '/log-categories',
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
title: i18n.translate('xpack.infra.logs.index.settingsTabTitle', {
|
||||
defaultMessage: 'Settings',
|
||||
}),
|
||||
path: '/settings',
|
||||
},
|
||||
],
|
||||
category: DEFAULT_APP_CATEGORIES.observability,
|
||||
mount: async (params: AppMountParameters) => {
|
||||
// mount callback should not use setup dependencies, get start dependencies instead
|
||||
const [coreStart, plugins, pluginStart] = await core.getStartServices();
|
||||
|
||||
const { renderApp } = await import('./apps/logs_app');
|
||||
return renderApp(coreStart, plugins, pluginStart, params);
|
||||
},
|
||||
});
|
||||
const { renderApp } = await import('./apps/logs_app');
|
||||
return renderApp(coreStart, plugins, pluginStart, params);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// !! Need to be kept in sync with the routes in x-pack/plugins/infra/public/pages/metrics/index.tsx
|
||||
const infraDeepLinks: AppDeepLink[] = [
|
||||
|
@ -285,14 +293,6 @@ export class Plugin implements InfraClientPluginClass {
|
|||
},
|
||||
});
|
||||
|
||||
startDep$AndHostViewFlag$.subscribe(
|
||||
([_startServices]: [[CoreStart, InfraClientStartDeps, InfraClientStartExports], boolean]) => {
|
||||
this.appUpdater$.next(() => ({
|
||||
deepLinks: infraDeepLinks,
|
||||
}));
|
||||
}
|
||||
);
|
||||
|
||||
/* This exists purely to facilitate URL redirects from the old App ID ("infra"),
|
||||
to our new App IDs ("metrics" and "logs"). With version 8.0.0 we can remove this. */
|
||||
core.application.register({
|
||||
|
@ -307,6 +307,14 @@ export class Plugin implements InfraClientPluginClass {
|
|||
},
|
||||
});
|
||||
|
||||
startDep$AndHostViewFlag$.subscribe(
|
||||
([_startServices]: [[CoreStart, InfraClientStartDeps, InfraClientStartExports], boolean]) => {
|
||||
this.appUpdater$.next(() => ({
|
||||
deepLinks: infraDeepLinks,
|
||||
}));
|
||||
}
|
||||
);
|
||||
|
||||
// Setup telemetry events
|
||||
this.telemetry.setup({ analytics: core.analytics });
|
||||
|
||||
|
|
|
@ -1899,8 +1899,9 @@ const createMockStaticConfiguration = (sources: any): InfraConfig => ({
|
|||
compositeSize: 2000,
|
||||
},
|
||||
featureFlags: {
|
||||
metricsExplorerEnabled: true,
|
||||
customThresholdAlertsEnabled: false,
|
||||
logsUIEnabled: true,
|
||||
metricsExplorerEnabled: true,
|
||||
osqueryEnabled: true,
|
||||
},
|
||||
enabled: true,
|
||||
|
|
|
@ -126,8 +126,9 @@ const createMockStaticConfiguration = (sources: any): InfraConfig => ({
|
|||
compositeSize: 2000,
|
||||
},
|
||||
featureFlags: {
|
||||
metricsExplorerEnabled: true,
|
||||
customThresholdAlertsEnabled: false,
|
||||
logsUIEnabled: true,
|
||||
metricsExplorerEnabled: true,
|
||||
osqueryEnabled: true,
|
||||
},
|
||||
sources,
|
||||
|
|
|
@ -81,14 +81,18 @@ export const config: PluginConfigDescriptor<InfraConfig> = {
|
|||
})
|
||||
),
|
||||
featureFlags: schema.object({
|
||||
metricsExplorerEnabled: offeringBasedSchema({
|
||||
traditional: schema.boolean({ defaultValue: true }),
|
||||
serverless: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
customThresholdAlertsEnabled: offeringBasedSchema({
|
||||
traditional: schema.boolean({ defaultValue: false }),
|
||||
serverless: schema.boolean({ defaultValue: true }),
|
||||
}),
|
||||
logsUIEnabled: offeringBasedSchema({
|
||||
traditional: schema.boolean({ defaultValue: true }),
|
||||
serverless: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
metricsExplorerEnabled: offeringBasedSchema({
|
||||
traditional: schema.boolean({ defaultValue: true }),
|
||||
serverless: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
osqueryEnabled: offeringBasedSchema({
|
||||
traditional: schema.boolean({ defaultValue: true }),
|
||||
serverless: schema.boolean({ defaultValue: false }),
|
||||
|
@ -222,14 +226,16 @@ export class InfraServerPlugin
|
|||
countLogs: () => UsageCollector.countLogs(),
|
||||
});
|
||||
|
||||
plugins.home.sampleData.addAppLinksToSampleDataset('logs', [
|
||||
{
|
||||
sampleObject: null, // indicates that there is no sample object associated with this app link's path
|
||||
getPath: () => `/app/logs`,
|
||||
label: logsSampleDataLinkLabel,
|
||||
icon: 'logsApp',
|
||||
},
|
||||
]);
|
||||
if (this.config.featureFlags.logsUIEnabled) {
|
||||
plugins.home.sampleData.addAppLinksToSampleDataset('logs', [
|
||||
{
|
||||
sampleObject: null, // indicates that there is no sample object associated with this app link's path
|
||||
getPath: () => `/app/logs`,
|
||||
label: logsSampleDataLinkLabel,
|
||||
icon: 'logsApp',
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
initInfraServer(this.libs);
|
||||
registerRuleTypes(plugins.alerting, this.libs, plugins.ml);
|
||||
|
|
|
@ -16,6 +16,11 @@ export const initGetLogAlertsChartPreviewDataRoute = ({
|
|||
framework,
|
||||
getStartServices,
|
||||
}: Pick<InfraBackendLibs, 'framework' | 'getStartServices'>) => {
|
||||
// Replace with the corresponding logs alert rule feature flag
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -16,6 +16,9 @@ import { getLogEntryAnomalies } from '../../../lib/log_analysis';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryAnomaliesRoute = ({ framework }: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -15,6 +15,9 @@ import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryAnomaliesDatasetsRoute = ({ framework }: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -15,6 +15,9 @@ import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryCategoriesRoute = ({ framework }: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -15,6 +15,9 @@ import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
|||
import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
||||
|
||||
export const initGetLogEntryCategoryDatasetsRoute = ({ framework }: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -15,6 +15,9 @@ import { isMlPrivilegesError } from '../../../lib/log_analysis/errors';
|
|||
import { assertHasInfraMlPlugins } from '../../../utils/request_context';
|
||||
|
||||
export const initGetLogEntryCategoryDatasetsStatsRoute = ({ framework }: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -18,6 +18,9 @@ export const initGetLogEntryCategoryExamplesRoute = ({
|
|||
framework,
|
||||
getStartServices,
|
||||
}: Pick<InfraBackendLibs, 'framework' | 'getStartServices'>) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -18,6 +18,9 @@ export const initGetLogEntryExamplesRoute = ({
|
|||
framework,
|
||||
getStartServices,
|
||||
}: Pick<InfraBackendLibs, 'framework' | 'getStartServices'>) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -17,6 +17,9 @@ export const initValidateLogAnalysisDatasetsRoute = ({
|
|||
framework,
|
||||
logEntries,
|
||||
}: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
|
@ -19,6 +19,10 @@ import { logAnalysisValidationV1 } from '../../../../common/http_api';
|
|||
const escapeHatch = schema.object({}, { unknowns: 'allow' });
|
||||
|
||||
export const initValidateLogAnalysisIndicesRoute = ({ framework }: InfraBackendLibs) => {
|
||||
if (!framework.config.featureFlags.logsUIEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
framework
|
||||
.registerVersionedRoute({
|
||||
access: 'internal',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue