dev_docs/tutorials/advanced_settings.mdx
Note: Advanced settings, uiSettings, settings, and config are often used to describe the same concept. While we work toward unifying naming, there will be some inconsistencies until unification is complete.
Advanced Settings control the behavior of Kibana. To configure the UI settings, open the main menu, then click Stack Management > Advanced Settings. When settings are changed from their default, the new value is persisted as a key/value pair in the config saved object registered by core.
There are several ways to configure an advanced setting:
uiSettings are registered synchronously during core's setup lifecycle phase. This means that once you add a new advanced setting, you cannot change or remove it without <DocLink id="kibDevTutorialAdvancedSettings" section="registering-migrations" text="registering a migration in core"/>.
The uiSettings service is the programmatic interface to Kibana's Advanced Settings UI. Kibana plugins use the service to extend Kibana UI Settings Management with custom settings for a plugin.
Configuration through the Advanced Settings UI is restricted to users authorised to access the Advanced Settings page. Users who don't have permissions to change these values default to using the csettings configuration defined for the space that they are in. The config saved object can be shared between spaces.
When a setting is configured as an override in kibana.yml, it overrides any other value store in the config saved object. The override applies to Kibana as a whole for all spaces and users, and the option is disabled on the Advanced Settings page. We refer to these as "global" overrides.
Note: If an override is misconfigured, it fails config validation and prevents Kibana from starting up. Validation is, however, limited to value type and not to key (name). For example, when a plugin registers the my_plugin_foo: 42 setting , then declares the following override, the config validation fails:
uiSettings.overrides:
my_plugin_foo: "42"
The following override results in a successful config validation:
uiSettings.overrides:
my_pluginFoo: 42
On the client, the uiSettings service is accessible directly from core and the client provides plugins access to the config entries stored in Elasticsearch.
The following is a basic example for using the uiSettings service:
src/plugins/charts/public/plugin.ts
import { Plugin, CoreSetup } from '@kbn/core/public';
import { ExpressionsSetup } from '@kbn/expressions-plugin/public';
import { palette, systemPalette } from '../common';
import { ThemeService } from './services';
import { PaletteService } from './services/palettes/service';
import { ActiveCursor } from './services/active_cursor';
interface SetupDependencies {
expressions: ExpressionsSetup;
}
/** @public */
export interface ChartsPluginSetup {
theme: Omit<ThemeService, 'init'>;
palettes: ReturnType<PaletteService['setup']>;
}
/** @public */
export type ChartsPluginStart = ChartsPluginSetup & {
activeCursor: ActiveCursor;
};
/** @public */
export class ChartsPlugin implements Plugin<ChartsPluginSetup, ChartsPluginStart> {
private readonly themeService = new ThemeService();
private readonly paletteService = new PaletteService();
private readonly activeCursor = new ActiveCursor();
private palettes: undefined | ReturnType<PaletteService['setup']>;
public setup(core: CoreSetup, dependencies: SetupDependencies): ChartsPluginSetup {
dependencies.expressions.registerFunction(palette);
dependencies.expressions.registerFunction(systemPalette);
this.themeService.init(core.theme);
this.palettes = this.paletteService.setup();
this.activeCursor.setup();
return {
theme: this.themeService,
palettes: this.palettes,
};
}
public start(): ChartsPluginStart {
return {
theme: this.themeService,
palettes: this.palettes!,
activeCursor: this.activeCursor,
};
}
}
On the server side, uiSettings are accessible directly from core. The following example shows how to register a new setting with the minimum required schema parameter against which validations are performed on read and write.
The example also shows how plugins can leverage the optional deprecation parameter on registration for handling deprecation notices and renames. The deprecation warnings are rendered in the Advanced Settings UI and should also be added to the Configure Kibana guide.
src/plugins/dev_tools/server/plugin.ts
import { PluginInitializerContext, Plugin, CoreSetup } from '@kbn/core/server';
import { uiSettings } from './ui_settings';
export class DevToolsServerPlugin implements Plugin<object, object> {
constructor(initializerContext: PluginInitializerContext) {}
public setup(core: CoreSetup<object>) {
/**
* Register Dev Tools UI Settings
*/
core.uiSettings.register({
[ENABLE_PERSISTENT_CONSOLE_UI_SETTING_ID]: {
category: [DEV_TOOLS_FEATURE_ID],
description: i18n.translate('devTools.uiSettings.persistentConsole.description', {
defaultMessage:
'Enables a persistent console in the Kibana UI. This setting does not affect the standard Console in Dev Tools.',
}),
name: i18n.translate('devTools.uiSettings.persistentConsole.name', {
defaultMessage: 'Persistent Console',
}),
requiresPageReload: true,
schema: schema.boolean(),
value: true,
},
});
return {};
}
public start() {
return {};
}
public stop() {}
}
For optimal Kibana performance, uiSettings are cached. Any changes that require a cache refresh should use the requiresPageReload parameter on registration.
For example, changing the time filter refresh interval triggers a prompt in the UI that the page needs to be refreshed to save the new value:
src/plugins/data/server/ui_settings.ts
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import type { DocLinksServiceSetup, UiSettingsParams } from '@kbn/core/server';
import { DEFAULT_QUERY_LANGUAGE, UI_SETTINGS } from '../common';
export function getUiSettings(
docLinks: DocLinksServiceSetup
): Record<string, UiSettingsParams<unknown>> {
return {
...
[UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS]: {
name: i18n.translate('data.advancedSettings.timepicker.refreshIntervalDefaultsTitle', {
defaultMessage: 'Time filter refresh interval',
}),
value: `{
"pause": false,
"value": 0
}`,
type: 'json',
description: i18n.translate('data.advancedSettings.timepicker.refreshIntervalDefaultsText', {
defaultMessage: `The timefilter's default refresh interval. The "value" needs to be specified in milliseconds.`,
}),
requiresPageReload: true,
schema: schema.object({
pause: schema.boolean(),
value: schema.number(),
}),
},
...
}
}
To change or remove a uiSetting, you must migrate the whole config Saved Object. uiSettings migrations are declared directly in the service.
For example, in 7.9.0, siem as renamed to securitySolution, and in 8.0.0, theme:version was removed:
As of 8.17, the advanced settings migrations are defined in src/core/packages/ui-settings/server-internal/src/saved_objects/migrations.ts.
If you have need to make a change that isn't possible in a saved object migration function (for example, you need to find other saved
objects), you can create a transform function instead. This will be applied when a config saved object is first created, and/or when it is
first upgraded. Note that you might need to add an extra attribute to verify that this transform has already been applied so it doesn't get
applied again in the future.
For example, we needed to transform the defaultIndex attribute, and we added an extra isDefaultIndexMigrated attribute for this purpose.
Refer to src/core/packages/ui-settings/server-internal/src/saved_objects/transforms.ts and #13339 for an example.