From 24301b1baaa973d6c40073007e29b62d50d8817c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 3 Oct 2023 11:08:23 +0200 Subject: [PATCH] AdhocFilters: Add docs for AdhocFilterSet and AdhocFiltersVariable (#377) Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com> Co-authored-by: Dominik Prokop --- docusaurus/docs/advanced-adhoc-fIlters.md | 121 +++++++++++++++++++++ docusaurus/docs/advanced-adhoc-fIlters.tsx | 83 ++++++++++++++ docusaurus/website/sidebars.js | 1 + 3 files changed, 205 insertions(+) create mode 100644 docusaurus/docs/advanced-adhoc-fIlters.md create mode 100644 docusaurus/docs/advanced-adhoc-fIlters.tsx diff --git a/docusaurus/docs/advanced-adhoc-fIlters.md b/docusaurus/docs/advanced-adhoc-fIlters.md new file mode 100644 index 000000000..62be83a67 --- /dev/null +++ b/docusaurus/docs/advanced-adhoc-fIlters.md @@ -0,0 +1,121 @@ +--- +id: advanced-adhoc-filters +title: Adhoc filters +--- + +Adhoc filters provide a very powerful way to dynamically change the scope or filtering of queries in your scene view. Unlike variables, which usually control a predefined label or dimension, with adhoc filters +the user can control which keys (labels) to filter on. + +## Automically applied to queries + +Adhoc filters are supported directly by many data sources. This means they handle automatically applying filters to all the queries that match the data source you specify on the `AdhocFilterSet`. + +### Step 1. Create the AdHocFilterSet + +Start by defining the `AdHocFilterSet`. + +```ts +const filterSet = new AdHocFilterSet({ + name: 'Filters', + datasource: { + type: 'prometheus', + uid: '', + }, + // You don't need to set baseFilters, but they're useful if you want to limit label suggestions to only those you deem relevant for the scene. + // These are not shown in the UI. + baseFilters: [{ key: '__name__', operator: '=', value: 'ALERTS', condition: '' }], + // If you want to have any default filters added by default, you can specify those here. + filters: [] +}); +``` + +Next, you add this `filterSet` to the controls array of your `EmbeddedScene` or `SceneAppPage` depending on where you want it. + + +### How automatic mode works + +The behavior of `AdHocFilterSet` is controlled by the `applyMode` option. When set to `same-datasource`, which is the default, any change to any filter will automatically re-trigger all +`SceneQueryRunners` in the scene that are configured with the same data source UID as the one of the `AdHocFilterSet`. The data source implementation will handle modifying all the queries +to include the current filters. + +## Customize the tag and value suggestions + +By default the tag (label) suggestions will come from the data source implementation of `getTagKeys`. You should take existing filters and `baseFilters` into account when fetching suggestions so that filters +can also impact the suggested tags and values of other filters. This behavior that other filters are taken into account is new and not all data sources support it yet. + +Values are fetched from the data source implementation of `getTagValues`. Both tag keys and tag values can be customized with the two state properties: `getTagKeysProvider` and `getTagValuesProvider`. + +Example: + +```ts +const filterSet = new AdHocFilterSet({ + name: 'Filters', + datasource: { + type: 'prometheus', + uid: '', + }, + getTagKeysProvider: () => { + return Promise.resolve({ + replace: true, + values: [ + { text: 'service_namespace', value: 'service_namespace' }, + { text: 'technology', value: 'technology' }, + ] + }); + }, + getTagValuesProvider: (set: AdHocFilterSet, filter: AdHocVariableFilter) => { + // Customize value look up + return Promise.resolve({ replace: false, values: [] }); + }, +}); +``` + +With these two functions, you can completely customize the key and value look up. With the `replace` property on the return object, you can control if the result should either replace the default implementation (results) or augment the default result with, for example, keys/labels from another data source. + +## Manual mode and using `AdHocFiltersVariable` + +If you don't want filters to be applied to all queries of the same data source as that of the `AdHocFilterSet` and want more control over which queries it's applied to, you can set `applyMode` to `manual` and +then use the filters however you want. You could, for example, subscribe to the `AdHocFilterSet` state and then use the filters to modify the scene in some interesting way. + +An alternative way to use the manual mode is `AdHocFiltersVariable`. This object is an alternative to `AdHocFilterSet`. With `AdHocFiltersVariable`, you +don't add it the controls array but instead add it to a `SceneVariableSet` as one of your variables. The UI is then rendered as part of `VariableValueSelectors`. + +Example: + +```ts +$variables: new SceneVariableSet({ + variables: [ + AdHocFiltersVariable.create({ + datasource: { uid: 'gdev-prometheus' }, + filters: [{ key: 'job', operator: '=', value: 'grafana', condition: '' }], + }), + ], +}), +``` + +As you can see, you shouldn't create `AdHocFiltersVariable` using the normal constructor but the static factory function `AdHocFiltersVariable.create`. This factory function helps create both the variable +and the inner `AdHocFilterSet` and makes sure the inner set has `applyMode` set to `manual`. + +With this variable, you can now use the filters easily in specific queries by using it as a normal variable. + +Example: + +```ts + new SceneQueryRunner({ + datasource: { uid: 'gdev-prometheus' }, + queries: [ + { + refId: 'A', + expr: 'ALERTS{$Filters}', + format: 'table', + instant: true, + }, + ], +}) +``` + +Such configured query contains the variable expression `$Filters`. You can change the name of the variable. By default, the `AdHocFiltersVariable` will render the filters to valid +Prometheus label filter expressions separated by a comma. + + + diff --git a/docusaurus/docs/advanced-adhoc-fIlters.tsx b/docusaurus/docs/advanced-adhoc-fIlters.tsx new file mode 100644 index 000000000..6828c1f4d --- /dev/null +++ b/docusaurus/docs/advanced-adhoc-fIlters.tsx @@ -0,0 +1,83 @@ +import { + AdHocFilterSet, + AdHocFiltersVariable, + EmbeddedScene, + PanelBuilders, + QueryVariable, + SceneFlexItem, + SceneFlexLayout, + SceneQueryRunner, + SceneVariableSet, + VariableValueSelectors, +} from '@grafana/scenes'; + +import { AdHocVariableFilter } from '@grafana/data'; + +export function adhocFiltersExamples() { + const filterSet1 = new AdHocFilterSet({ + name: 'Filters', + datasource: { + type: 'prometheus', + uid: '', + }, + // You don't need to set baseFilters, but they're useful if you want to limit label suggestions to only those you deem relevant for the scene. + // These are not shown in the UI. + baseFilters: [{ key: '__name__', operator: '=', value: 'ALERTS', condition: '' }], + // If you want to have any default filters added by default, you can specify those here. + filters: [], + }); + + const filterSet2 = new AdHocFilterSet({ + name: 'Filters', + datasource: { + type: 'prometheus', + uid: '', + }, + getTagKeysProvider: () => { + return Promise.resolve({ + replace: true, + values: [ + { text: 'service_namespace', value: 'service_namespace' }, + { text: 'technology', value: 'technology' }, + ], + }); + }, + getTagValuesProvider: (set: AdHocFilterSet, filter: AdHocVariableFilter) => { + // Customize value look up + return Promise.resolve({ replace: false, values: [] }); + }, + }); + + // This scene is only showing the variable use case scenario + const scene = new EmbeddedScene({ + $variables: new SceneVariableSet({ + variables: [ + AdHocFiltersVariable.create({ + datasource: { uid: 'gdev-prometheus' }, + filters: [{ key: 'job', operator: '=', value: 'grafana', condition: '' }], + }), + ], + }), + body: new SceneFlexLayout({ + children: [ + new SceneFlexItem({ + $data: new SceneQueryRunner({ + datasource: { uid: 'gdev-prometheus' }, + queries: [ + { + refId: 'A', + expr: 'ALERTS{$Filters}', + format: 'table', + instant: true, + }, + ], + }), + body: PanelBuilders.timeseries().build(), + }), + ], + }), + controls: [new VariableValueSelectors({})], + }); + + return scene; +} diff --git a/docusaurus/website/sidebars.js b/docusaurus/website/sidebars.js index a58c01a16..e8bd22abb 100644 --- a/docusaurus/website/sidebars.js +++ b/docusaurus/website/sidebars.js @@ -54,6 +54,7 @@ const sidebars = { 'advanced-activation-handlers', 'advanced-data', 'advanced-variables', + 'advanced-adhoc-filters', 'advanced-behaviors', 'advanced-custom-datasource', 'advanced-time-range-comparison',