mirror of
https://github.com/elastic/kibana.git
synced 2025-04-26 02:37:44 -04:00
## Summary Start relocating Kibana modules (packages and plugins) to the new folder structure, according to the _Kibana Sustainable Architecture_ initiative. #### 16 plugin(s) are going to be relocated: | Id | Target folder | | -- | ------------- | | `@kbn/cloud-chat-plugin` | `x-pack/platform/plugins/private/cloud_integrations/cloud_chat` | | `@kbn/cloud-experiments-plugin` | `x-pack/platform/plugins/shared/cloud_integrations/cloud_experiments` | | `@kbn/cloud-full-story-plugin` | `x-pack/platform/plugins/private/cloud_integrations/cloud_full_story` | | `@kbn/cloud-links-plugin` | `x-pack/platform/plugins/private/cloud_integrations/cloud_links` | | `@kbn/cloud-plugin` | `x-pack/platform/plugins/shared/cloud` | | `@kbn/features-plugin` | `x-pack/platform/plugins/shared/features` | | `@kbn/ftr-apis-plugin` | `src/platform/plugins/private/ftr_apis` | | `@kbn/kibana-usage-collection-plugin` | `src/platform/plugins/private/kibana_usage_collection` | | `@kbn/licensing-plugin` | `x-pack/platform/plugins/shared/licensing` | | `@kbn/newsfeed-plugin` | `src/platform/plugins/shared/newsfeed` | | `@kbn/saved-objects-management-plugin` | `src/platform/plugins/shared/saved_objects_management` | | `@kbn/telemetry-collection-manager-plugin` | `src/platform/plugins/shared/telemetry_collection_manager` | | `@kbn/telemetry-collection-xpack-plugin` | `x-pack/platform/plugins/private/telemetry_collection_xpack` | | `@kbn/telemetry-management-section-plugin` | `src/platform/plugins/shared/telemetry_management_section` | | `@kbn/telemetry-plugin` | `src/platform/plugins/shared/telemetry` | | `@kbn/usage-collection-plugin` | `src/platform/plugins/shared/usage_collection` | #### 22 package(s) are going to be relocated: | Id | Target folder | | -- | ------------- | | `@kbn/analytics` | `src/platform/packages/shared/kbn-analytics` | | `@kbn/analytics-collection-utils` | `src/platform/packages/private/analytics/utils/analytics_collection_utils` | | `@kbn/apm-config-loader` | `src/platform/packages/private/kbn-apm-config-loader` | | `@kbn/cloud` | `src/platform/packages/shared/cloud` | | `@kbn/config` | `src/platform/packages/shared/kbn-config` | | `@kbn/config-mocks` | `src/platform/packages/private/kbn-config-mocks` | | `@kbn/config-schema` | `src/platform/packages/shared/kbn-config-schema` | | `@kbn/crypto-browser` | `src/platform/packages/shared/kbn-crypto-browser` | | `@kbn/ebt-tools` | `src/platform/packages/shared/kbn-ebt-tools` | | `@kbn/es-errors` | `src/platform/packages/shared/kbn-es-errors` | | `@kbn/es-types` | `src/platform/packages/shared/kbn-es-types` | | `@kbn/hapi-mocks` | `src/platform/packages/private/kbn-hapi-mocks` | | `@kbn/health-gateway-server` | `src/platform/packages/private/kbn-health-gateway-server` | | `@kbn/i18n` | `src/platform/packages/shared/kbn-i18n` | | `@kbn/i18n-react` | `src/platform/packages/shared/kbn-i18n-react` | | `@kbn/logging` | `src/platform/packages/shared/kbn-logging` | | `@kbn/logging-mocks` | `src/platform/packages/shared/kbn-logging-mocks` | | `@kbn/router-to-openapispec` | `src/platform/packages/shared/kbn-router-to-openapispec` | | `@kbn/server-http-tools` | `src/platform/packages/shared/kbn-server-http-tools` | | `@kbn/std` | `src/platform/packages/shared/kbn-std` | | `@kbn/utility-types` | `src/platform/packages/shared/kbn-utility-types` | | `@kbn/zod` | `src/platform/packages/shared/kbn-zod` | --------- Co-authored-by: Alejandro Fernández Haro <alejandro.haro@elastic.co> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> |
||
---|---|---|
.. | ||
README.mdx |
---
id: kibFeatureFlagsService
slug: /kibana-dev-docs/tutorials/feature-flags-service
title: Feature Flags service
description: The Feature Flags service provides the necessary APIs to evaluate dynamic feature flags.
date: 2024-10-16
tags: ['kibana', 'dev', 'contributor', 'api docs', 'a/b testing', 'feature flags', 'flags']
---
# Feature Flags Service
The Feature Flags service provides the necessary APIs to evaluate dynamic feature flags.
The service is always enabled, however, it will return the fallback value if a feature flags provider hasn't been attached.
Kibana only registers a provider when running on Elastic Cloud Hosted/Serverless. And even in those scenarios, we expect that some customers might
have network restrictions that might not allow the flags to evaluate. The fallback value must provide a non-broken experience to users.
⚠️Feature Flags are considered dynamic configuration and cannot be used for settings that require restarting Kibana.
One example of invalid use cases are settings used during the `setup` lifecycle of the plugin, such as settings that define
if an HTTP route is registered or not. Instead, you should always register the route, and return `404 - Not found` in the route
handler if the feature flag returns a _disabled_ state.
In summary, Feature flagging is best suited for
- Phased rollout of the features (either to a specific customer, a subset of customers, or a % of overall users)
- Feature experimentation
Feature flagging is NOT suitable for
- Applying feature availability for licensing and/or tiers
- Restricting or applying customer entitlement to specific GA features
For a code example, refer to the [Feature Flags Example plugin](https://github.com/elastic/kibana/blob/main/examples/feature_flags_example/README.md)
## Key concepts
### Feature Flag
A config key that defines a set of [variations](#variations) that will be resolved at runtime when the app calls [the evaluation APIs](https://docs.elastic.dev/kibana-dev-docs/tutorials/feature-flags-service#evaluating-feature-flags). The variation is decided at runtime based on static binary state (ON -> `variationA` vs. OFF -> `variationB`), or via [evaluation/segmentation rules](#evaluationsegmentation-rules).
### Variations
All the potential values that a feature flag can return based on the [evaluation rules](#evaluationsegmentation-rules). A feature flag should define at least 2 variations: the ON and the OFF states. The typical use case sets the OFF state to match the `fallback` value provided to [the evaluation APIs](https://docs.elastic.dev/kibana-dev-docs/tutorials/feature-flags-service#evaluating-feature-flags), although it's not a hard requirement and Kibana contributors might require special configurations.
### Evaluation/Segmentation rules
Set of rules used to evaluate the variation to resolve, based on the [evaluation context](#evaluation-context) provided by the app.
The rules can vary from a percentage rollout per evaluation context, or more complex IF...THEN filters and clauses.
Refer to the [Evaluation Context guide's examples](https://github.com/elastic/kibana-feature-flags/blob/main/docs/evaluation-context.md#examples) for some typical scenarios.
### Evaluation Context
Kibana reports a set of properties specific to each ECH deployment/Serverless project to help define the [segmentation rules](#evaluationsegmentation-rules). A list of the currently reported context properties can be found in the [Evaluation Context guide](https://github.com/elastic/kibana-feature-flags/blob/main/docs/evaluation-context.md).
### Feature Flag Code References
In the Kibana repo we run a [GH Action](https://github.com/elastic/kibana/actions/workflows/launchdarkly-code-references.yml) that links existing Feature Flags to their code references. This helps us figure out which flags have been removed from the code and, which ones are still being used.
> :information_source: New flags might take a few moments to be updated with their code references.
> The job runs on every commit to the `main` branch of the [Kibana repository](https://github.com/elastic/kibana), so the wait can take from a few minutes to a few hours, depending on the Kibana repo's activity.
## Registering a feature flag
At the moment, we follow a manual process to manage our feature flags. Refer to [this repo](https://github.com/elastic/kibana-feature-flags) to learn more about our current internal process.
Our goal is to achieve a _gitops_ approach eventually. But, at the moment, it's not available.
### Deprecation/removal strategy
When your code doesn't use the feature flag anymore, it is recommended to clean up the feature flags.
There are a few considerations to take into account when performing this clean-up:
1. Always deprecate first, remove after
2. When to remove?
#### Always deprecate first, remove after
Just because the CI syncs the state of `main` to our feature flag provider, there is a high probability that the
previous version of the code that still relied on the feature flag is still running out there.
For that reason, the recommendation is to always deprecate before removing the flags. This will keep evaluating the flags,
according to the segmentation rules configured for the flag.
#### When to remove?
After deprecation, we need to consider when it's safe to remove the flag. There are different scenarios that come with
different recommendations:
* The segmentation rules of my flag are set up to return the fallback value 100% of the time: it should be safe to
remove the flag at any time.
* My flag only made it to Serverless (it never made it to Elastic Cloud Hosted): it should be safe to remove the flag
after 2 releases have been rolled out (roughly 2-3 weeks later). This is to ensure that all Serverless projects have
been upgraded and that we won't need to rollback to the previous version.
* My flag made it to Elastic Cloud Hosted: if we want to remove the flag, we should approach the affected customers to
fix the expected values via [config overrides](#config-overrides).
In general, the recommendation is to check our telemetry to validate the usage of our flags.
## Evaluating feature flags
This service provides 2 ways to evaluate your feature flags, depending on the use case:
1. **Single evaluation**: performs the evaluation once, and doesn't react to updates. These APIs are synchronous in the
browser, and asynchronous in the server.
2. **Observed evaluation**: observes the flag for any changes so that the code can adapt. These APIs return an RxJS observable.
Also, the APIs are typed, so you need to use the appropriate API depending on the `variationType` you defined your flag:
| Type | Single evaluation | Observed evaluation |
|:-------:|:--------------------------------------------------------|:---------------------------------------------------------|
| Boolean | `core.featureFlags.getBooleanValue(flagName, fallback)` | `core.featureFlags.getBooleanValue$(flagName, fallback)` |
| String | `core.featureFlags.getStringValue(flagName, fallback)` | `core.featureFlags.getStringValue$(flagName, fallback)` |
| Number | `core.featureFlags.getNumberValue(flagName, fallback)` | `core.featureFlags.getNumberValue$(flagName, fallback)` |
### Request handler context
Additionally, to make things easier in our HTTP handlers, the _Single evaluation_ APIs are available as part of the core
context provided to the handlers:
```typescript
async (context, request, response) => {
const { featureFlags } = await context.core;
return response.ok({
body: {
number: await featureFlags.getNumberValue('myPlugin.exampleNumber', 1),
},
});
}
```
## Extending the evaluation context
The <DocLink id="kibCloudExperimentsPlugin" section="evaluation-context" text="current evaluation context"/> should have
enough information to declare the segmentation rules for your feature flags. However, if your use case requires additional
context, feel free to call the API `core.featureFlags.setContext()` from your plugin.
At the moment, we use 2 levels of context: `kibana` and `organization` that we can use for segmentation purposes at
different levels. By default, the API appends the context to the `kibana` scope. If you need to extend the `organization`
scope, make sure to add `kind: 'organization'` to the object provided to the `setContext` API.
## Config overrides
To help with testing, and to provide an escape hatch in cases where the flag evaluation is not behaving as intended,
the Feature Flags Service provides a way to force the values of a feature flag without attempting to resolve it via the
provider. In the `kibana.yml`, the following config sets the overrides:
```yaml
feature_flags.overrides:
myPlugin.myFeatureFlag: 'my-forced-value'
```
> [!WARNING]
> There is no validation regarding the variations nor the type of the flags. Use these overrides with caution.
### Dynamic config
When running in our test environments, the overrides can be updated without restarting Kibana via the HTTP `PUT /internal/core/_settings`:
```
PUT /internal/core/_settings
{
"feature_flags.overrides": {
"my-feature-flag": "my-forced-value"
}
}
```