Improve insights (#3896)
# What this PR does Redesign panels, update queries, handle no data scenario better ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/3763 ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required)
This commit is contained in:
parent
445ac74088
commit
caef9e2eb0
22 changed files with 174 additions and 539 deletions
|
|
@ -43,14 +43,13 @@ test.describe('Insights', () => {
|
|||
test('Viewer can see all the panels in OnCall insights', async ({ viewerRolePage: { page } }) => {
|
||||
await goToOnCallPage(page, 'insights');
|
||||
[
|
||||
'Total alert groups',
|
||||
'Total alert groups by state',
|
||||
'New alert groups for selected period',
|
||||
'Mean time to respond \\(MTTR\\)',
|
||||
'MTTR changed for period',
|
||||
'New alert groups during time period',
|
||||
'New alert groups',
|
||||
'Mean time to respond \\(MTTR\\) average',
|
||||
'Alert groups by Integration',
|
||||
'Mean time to respond \\(MTTR\\) by Integration',
|
||||
'Alert groups by Team',
|
||||
'Mean time to respond \\(MTTR\\) by Team',
|
||||
'New alert groups notifications',
|
||||
].forEach(async (panelTitle) => {
|
||||
await expect(page.getByRole('heading', { name: new RegExp(`^${panelTitle}$`) }).first()).toBeVisible();
|
||||
});
|
||||
|
|
@ -58,7 +57,7 @@ test.describe('Insights', () => {
|
|||
|
||||
test('There is no panel that misses data', async ({ adminRolePage: { page } }) => {
|
||||
await goToOnCallPage(page, 'insights');
|
||||
await page.getByText('Last 7 days').click();
|
||||
await page.getByText('Last 24 hours').click();
|
||||
await page.getByText('Last 1 hour').click();
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(page.getByText('No data')).toBeHidden();
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ export class AlertGroupStore extends BaseStore {
|
|||
this.updateAlertGroups();
|
||||
}
|
||||
|
||||
@action
|
||||
@action.bound
|
||||
async updateAlertGroups() {
|
||||
this.alertGroupsLoading = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ class LoaderStoreClass {
|
|||
makeObservable(this);
|
||||
}
|
||||
|
||||
@action
|
||||
@action.bound
|
||||
setLoadingAction(actionKey: string, isLoading: boolean) {
|
||||
this.items[actionKey] = isLoading;
|
||||
}
|
||||
|
||||
isLoading(actionKey: string): boolean {
|
||||
isLoading = (actionKey: string): boolean => {
|
||||
return !!this.items[actionKey];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const LoaderStore = new LoaderStoreClass();
|
||||
|
|
|
|||
35
grafana-plugin/src/pages/insights/Insights.hooks.ts
Normal file
35
grafana-plugin/src/pages/insights/Insights.hooks.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useStore } from 'state/useStore';
|
||||
|
||||
const TWENTY_SECS = 20_000;
|
||||
const FIVE_SECS = 5_000;
|
||||
|
||||
export const useAlertCreationChecker = () => {
|
||||
const {
|
||||
alertGroupStore: { updateAlertGroups, alerts },
|
||||
} = useStore();
|
||||
const [isFirstAlertCheckDone, setIsFirstAlertCheckDone] = useState(false);
|
||||
|
||||
const isAnyAlertCreatedMoreThan20SecsAgo = Array.from(alerts).some(([_key, alert]) => {
|
||||
const alertTime = new Date(alert.started_at).getTime();
|
||||
const nowTime = new Date().getTime();
|
||||
return nowTime - alertTime > TWENTY_SECS;
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const fetch = async () => {
|
||||
if (!isAnyAlertCreatedMoreThan20SecsAgo) {
|
||||
await updateAlertGroups();
|
||||
}
|
||||
setIsFirstAlertCheckDone(true);
|
||||
};
|
||||
fetch();
|
||||
const interval = setInterval(() => {
|
||||
fetch();
|
||||
}, FIVE_SECS);
|
||||
return () => clearInterval(interval);
|
||||
}, [isAnyAlertCreatedMoreThan20SecsAgo]);
|
||||
|
||||
return { isAnyAlertCreatedMoreThan20SecsAgo, isFirstAlertCheckDone };
|
||||
};
|
||||
|
|
@ -6,6 +6,6 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.alertBox {
|
||||
.spaceTop {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,29 +14,28 @@ import {
|
|||
SceneAppPage,
|
||||
useSceneApp,
|
||||
} from '@grafana/scenes';
|
||||
import { Alert } from '@grafana/ui';
|
||||
import { Alert, LoadingPlaceholder, VerticalGroup } from '@grafana/ui';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import { Text } from 'components/Text/Text';
|
||||
import { Tutorial } from 'components/Tutorial/Tutorial';
|
||||
import { TutorialStep } from 'components/Tutorial/Tutorial.types';
|
||||
import { useStore } from 'state/useStore';
|
||||
import { DOCS_ROOT } from 'utils/consts';
|
||||
import { DOCS_ROOT, PLUGIN_ROOT } from 'utils/consts';
|
||||
|
||||
import { useAlertCreationChecker } from './Insights.hooks';
|
||||
import styles from './Insights.module.scss';
|
||||
import { InsightsConfig } from './Insights.types';
|
||||
import getAlertGroupsByIntegrationScene from './scenes/AlertGroupsByIntegration';
|
||||
import getAlertGroupsByTeamScene from './scenes/AlertGroupsByTeam';
|
||||
import getMTTRScene from './scenes/MTTR';
|
||||
import getMTTRByIntegrationScene from './scenes/MTTRByIntegration';
|
||||
import getMTTRByTeamScene from './scenes/MTTRByTeam';
|
||||
import getMTTRChangedForPeriodStatScene from './scenes/MTTRChangedForPeriodStat';
|
||||
import getMTTRChangedForPeriodTimeseriesScene from './scenes/MTTRChangedForPeriodTimeseries';
|
||||
import getNewAlertGroupsDuringTimePeriodScene from './scenes/NewAlertGroupsDuringTimePeriod';
|
||||
import getNewAlertGroupsForSelectedPeriodScene from './scenes/NewAlertGroupsForSelectedPeriod';
|
||||
import getNewAlertGroupsNotificationsDuringTimePeriodScene from './scenes/NewAlertGroupsNotificationsDuringTimePeriod';
|
||||
import getNewAlertGroupsNotificationsForPeriodTableScene from './scenes/NewAlertGroupsNotificationsForPeriodTable';
|
||||
import getNewAlertGroupsNotificationsInTotalScene from './scenes/NewAlertGroupsNotificationsInTotal';
|
||||
import getTotalAlertGroupsScene from './scenes/TotalAlertGroups';
|
||||
import getTotalAlertGroupsByStateScene from './scenes/TotalAlertGroupsByState';
|
||||
import { getAlertGroupsByIntegrationScene } from './scenes/AlertGroupsByIntegration';
|
||||
import { getAlertGroupsByTeamScene } from './scenes/AlertGroupsByTeam';
|
||||
import { getMTTRAverage } from './scenes/MTTRAverageStat';
|
||||
import { getMTTRByIntegrationScene } from './scenes/MTTRByIntegration';
|
||||
import { getMTTRByTeamScene } from './scenes/MTTRByTeam';
|
||||
import { getMTTRChangedTimeseriesScene } from './scenes/MTTRChangedTimeseries';
|
||||
import { getNewAlertGroupsScene } from './scenes/NewAlertGroups';
|
||||
import { getNewAlertGroupsNotificationsTableScene } from './scenes/NewAlertGroupsNotificationsTable';
|
||||
import { getNewAlertGroupsNotificationsTimeseriesScene } from './scenes/NewAlertGroupsNotificationsTimeseries';
|
||||
import { getNewAlertGroupsTimeseriesScene } from './scenes/NewAlertGroupsTimeseries';
|
||||
import getVariables from './variables';
|
||||
|
||||
export const Insights = observer(() => {
|
||||
|
|
@ -45,8 +44,8 @@ export const Insights = observer(() => {
|
|||
insightsDatasource,
|
||||
organizationStore: { currentOrganization },
|
||||
} = useStore();
|
||||
const [showAllStackInfo, setShowAllStackInfo] = useState(false);
|
||||
const [datasource, setDatasource] = useState<string>();
|
||||
const { isAnyAlertCreatedMoreThan20SecsAgo, isFirstAlertCheckDone } = useAlertCreationChecker();
|
||||
|
||||
const config = useMemo(
|
||||
() => ({
|
||||
|
|
@ -54,7 +53,7 @@ export const Insights = observer(() => {
|
|||
datasource: { uid: isOpenSource ? '$datasource' : insightsDatasource },
|
||||
stack: currentOrganization?.stack_slug,
|
||||
}),
|
||||
[]
|
||||
[isOpenSource, currentOrganization?.stack_slug]
|
||||
);
|
||||
|
||||
const variables = useMemo(() => getVariables(config), [config]);
|
||||
|
|
@ -64,26 +63,33 @@ export const Insights = observer(() => {
|
|||
const appScene = useSceneApp(getAppScene);
|
||||
|
||||
useEffect(() => {
|
||||
const stackListener = variables.stack.subscribeToState(({ text }) => {
|
||||
setShowAllStackInfo((text as string[]).includes('All'));
|
||||
});
|
||||
if (!isAnyAlertCreatedMoreThan20SecsAgo) {
|
||||
return undefined;
|
||||
}
|
||||
const dataSourceListener =
|
||||
isOpenSource &&
|
||||
variables.datasource.subscribeToState(({ text }) => {
|
||||
setDatasource(`${text}`);
|
||||
});
|
||||
return () => {
|
||||
stackListener?.unsubscribe?.();
|
||||
dataSourceListener?.unsubscribe?.();
|
||||
};
|
||||
}, []);
|
||||
}, [isAnyAlertCreatedMoreThan20SecsAgo]);
|
||||
|
||||
if (!isFirstAlertCheckDone) {
|
||||
return <LoadingPlaceholder text="Loading..." />;
|
||||
}
|
||||
return (
|
||||
<div className={styles.insights}>
|
||||
<InsightsGeneralInfo />
|
||||
{showAllStackInfo && <AllStacksSelectedWarning />}
|
||||
{isOpenSource && !datasource && <NoDatasourceWarning />}
|
||||
<appScene.Component model={appScene} />
|
||||
{isAnyAlertCreatedMoreThan20SecsAgo ? (
|
||||
<>
|
||||
{isOpenSource && !datasource && <NoDatasourceWarning />}
|
||||
<appScene.Component model={appScene} />
|
||||
</>
|
||||
) : (
|
||||
<NoAlertCreatedTutorial />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
@ -97,15 +103,23 @@ const InsightsGeneralInfo = () => {
|
|||
return <Text type="secondary">Find out more about OnCall Insights and Metrics in our {docsLink}.</Text>;
|
||||
};
|
||||
|
||||
const AllStacksSelectedWarning = () => {
|
||||
const [alertVisible, setAlertVisible] = useState(true);
|
||||
|
||||
return alertVisible ? (
|
||||
<Alert onRemove={() => setAlertVisible(false)} severity="warning" title="" className={styles.alertBox}>
|
||||
Retrieving insights from multiple stacks has performance impact and loading data might take significantly more
|
||||
time. We recommend to select only specific stacks.
|
||||
</Alert>
|
||||
) : null;
|
||||
const NoAlertCreatedTutorial = () => {
|
||||
return (
|
||||
<div className={styles.spaceTop}>
|
||||
<Tutorial
|
||||
step={TutorialStep.Integrations}
|
||||
title={
|
||||
<VerticalGroup align="center" spacing="lg">
|
||||
<Text type="secondary">
|
||||
Your OnCall stack doesn’t have any alerts to visualise insights.
|
||||
<br />
|
||||
Make sure that you setup OnCall configuration to start monitoring.
|
||||
</Text>
|
||||
</VerticalGroup>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const NoDatasourceWarning = () => {
|
||||
|
|
@ -128,10 +142,10 @@ const getRootScene = (config: InsightsConfig, variables: ReturnType<typeof getVa
|
|||
pages: [
|
||||
new SceneAppPage({
|
||||
title: 'OnCall Insights',
|
||||
url: '/a/grafana-oncall-app/insights',
|
||||
url: `${PLUGIN_ROOT}/insights`,
|
||||
getScene: () =>
|
||||
new EmbeddedScene({
|
||||
$timeRange: new SceneTimeRange({ from: 'now-7d', to: 'now' }),
|
||||
$timeRange: new SceneTimeRange({ from: 'now-24h', to: 'now' }),
|
||||
$variables: new SceneVariableSet({
|
||||
variables: Object.values(variables),
|
||||
}),
|
||||
|
|
@ -152,22 +166,12 @@ const getRootScene = (config: InsightsConfig, variables: ReturnType<typeof getVa
|
|||
direction: 'column',
|
||||
children: [
|
||||
new SceneFlexLayout({
|
||||
height: 200,
|
||||
children: [
|
||||
getTotalAlertGroupsScene(config),
|
||||
getTotalAlertGroupsByStateScene(config),
|
||||
getNewAlertGroupsForSelectedPeriodScene(config),
|
||||
getMTTRScene(config),
|
||||
getMTTRChangedForPeriodStatScene(config),
|
||||
],
|
||||
height: 300,
|
||||
children: [getNewAlertGroupsScene(config), getMTTRAverage(config)],
|
||||
}),
|
||||
new SceneFlexLayout({
|
||||
height: 400,
|
||||
children: [getNewAlertGroupsDuringTimePeriodScene(config)],
|
||||
}),
|
||||
new SceneFlexLayout({
|
||||
height: 400,
|
||||
children: [getMTTRChangedForPeriodTimeseriesScene(config)],
|
||||
height: 300,
|
||||
children: [getNewAlertGroupsTimeseriesScene(config), getMTTRChangedTimeseriesScene(config)],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
|
|
@ -177,31 +181,10 @@ const getRootScene = (config: InsightsConfig, variables: ReturnType<typeof getVa
|
|||
canCollapse: true,
|
||||
isCollapsed: false,
|
||||
body: new SceneFlexLayout({
|
||||
height: 400,
|
||||
height: 300,
|
||||
children: [getAlertGroupsByIntegrationScene(config), getMTTRByIntegrationScene(config)],
|
||||
}),
|
||||
}),
|
||||
new NestedScene({
|
||||
title: 'Notified alert groups by Users (based on all Integrations)',
|
||||
canCollapse: true,
|
||||
isCollapsed: false,
|
||||
body: new SceneFlexLayout({
|
||||
direction: 'column',
|
||||
children: [
|
||||
new SceneFlexLayout({
|
||||
height: 400,
|
||||
children: [getNewAlertGroupsNotificationsDuringTimePeriodScene(config)],
|
||||
}),
|
||||
new SceneFlexLayout({
|
||||
height: 400,
|
||||
children: [
|
||||
getNewAlertGroupsNotificationsInTotalScene(config),
|
||||
getNewAlertGroupsNotificationsForPeriodTableScene(config),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
new NestedScene({
|
||||
title: 'Teams data',
|
||||
canCollapse: true,
|
||||
|
|
@ -210,12 +193,29 @@ const getRootScene = (config: InsightsConfig, variables: ReturnType<typeof getVa
|
|||
direction: 'column',
|
||||
children: [
|
||||
new SceneFlexLayout({
|
||||
height: 400,
|
||||
height: 300,
|
||||
children: [getAlertGroupsByTeamScene(config), getMTTRByTeamScene(config)],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
new NestedScene({
|
||||
title: 'Notified alert groups by Users (based on all Teams and Integrations)',
|
||||
canCollapse: true,
|
||||
isCollapsed: false,
|
||||
body: new SceneFlexLayout({
|
||||
direction: 'column',
|
||||
children: [
|
||||
new SceneFlexLayout({
|
||||
height: 300,
|
||||
children: [
|
||||
getNewAlertGroupsNotificationsTimeseriesScene(config),
|
||||
getNewAlertGroupsNotificationsTableScene(config),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getAlertGroupsByIntegrationScene({ datasource }: InsightsConfig) {
|
||||
export function getAlertGroupsByIntegrationScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'sort_desc(max_over_time(sum by(integration) (avg without(pod, instance)($alert_groups_total{slug=~"$stack", team=~"$team", integration=~"$integration"}))[1d:]))',
|
||||
expr: `sort_desc(delta(max_over_time(sum by(integration) (avg without(pod, instance)($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[1h:])[$__range:])>=0)`,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -74,6 +74,7 @@ export default function getAlertGroupsByIntegrationScene({ datasource }: Insight
|
|||
},
|
||||
],
|
||||
},
|
||||
decimals: 0,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
|
|
@ -97,7 +98,7 @@ export default function getAlertGroupsByIntegrationScene({ datasource }: Insight
|
|||
],
|
||||
},
|
||||
options: {
|
||||
cellHeight: 'sm',
|
||||
cellHeight: 'md',
|
||||
footer: {
|
||||
countRows: false,
|
||||
fields: '',
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getAlertGroupsByTeamScene({ datasource }: InsightsConfig) {
|
||||
export function getAlertGroupsByTeamScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'sort_desc(max_over_time(sum by(team) (avg without(pod, instance)($alert_groups_total{slug=~"$stack", team=~"$team", integration=~"$integration"}))[1d:]))',
|
||||
expr: `sort_desc(delta(max_over_time(sum by(team) (avg without(pod, instance)($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[1h:])[$__range:])>=0)`,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -74,6 +74,7 @@ export default function getAlertGroupsByTeamScene({ datasource }: InsightsConfig
|
|||
},
|
||||
],
|
||||
},
|
||||
decimals: 0,
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
|
|
@ -97,7 +98,7 @@ export default function getAlertGroupsByTeamScene({ datasource }: InsightsConfig
|
|||
],
|
||||
},
|
||||
options: {
|
||||
cellHeight: 'sm',
|
||||
cellHeight: 'md',
|
||||
footer: {
|
||||
countRows: false,
|
||||
fields: '',
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
import { ThresholdsMode } from '@grafana/data';
|
||||
import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getMTTRScene({ datasource }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'avg_over_time((sum($alert_groups_response_time_seconds_sum{slug=~"$stack", team=~"$team", integration=~"$integration"}) / sum($alert_groups_response_time_seconds_count{slug=~"$stack", team=~"$team", integration=~"$integration"}))[$__range:])',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
range: false,
|
||||
refId: 'A',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
title: 'Mean time to respond (MTTR)',
|
||||
description: 'Mean time between the start and first action of all alert groups for the last 7 days',
|
||||
pluginId: 'stat',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
color: {
|
||||
mode: 'thresholds',
|
||||
},
|
||||
mappings: [],
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{
|
||||
color: 'text',
|
||||
value: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
unit: 's',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byName',
|
||||
options: 'Value',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'displayName',
|
||||
value: 'MTTR',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
colorMode: 'value',
|
||||
graphMode: 'none',
|
||||
justifyMode: 'center',
|
||||
orientation: 'auto',
|
||||
reduceOptions: {
|
||||
calcs: ['lastNotNull'],
|
||||
fields: '',
|
||||
values: false,
|
||||
},
|
||||
textMode: 'auto',
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
|
@ -3,17 +3,17 @@ import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getMTTRChangedForPeriodStatScene({ datasource }: InsightsConfig) {
|
||||
export function getMTTRAverage({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'avg(sum($alert_groups_response_time_seconds_sum{slug=~"$stack", team=~"$team", integration=~"$integration"}) / sum($alert_groups_response_time_seconds_count{slug=~"$stack", team=~"$team", integration=~"$integration"}))',
|
||||
instant: false,
|
||||
expr: `avg_over_time((sum($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration"}) / sum($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[$__range:])`,
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
range: true,
|
||||
range: false,
|
||||
refId: 'A',
|
||||
},
|
||||
],
|
||||
|
|
@ -22,7 +22,7 @@ export default function getMTTRChangedForPeriodStatScene({ datasource }: Insight
|
|||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
title: 'MTTR changed for period',
|
||||
title: 'Mean time to respond (MTTR) average',
|
||||
pluginId: 'stat',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -57,7 +57,7 @@ export default function getMTTRChangedForPeriodStatScene({ datasource }: Insight
|
|||
justifyMode: 'center',
|
||||
orientation: 'auto',
|
||||
reduceOptions: {
|
||||
calcs: ['diff'],
|
||||
calcs: ['lastNotNull'],
|
||||
fields: '',
|
||||
values: false,
|
||||
},
|
||||
|
|
@ -3,14 +3,14 @@ import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getMTTRByIntegrationScene({ datasource }: InsightsConfig) {
|
||||
export function getMTTRByIntegrationScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'sort_desc(avg_over_time((sum by (integration)($alert_groups_response_time_seconds_sum{slug=~"$stack", team=~"$team", integration=~"$integration"}) / sum by (integration)($alert_groups_response_time_seconds_count{slug=~"$stack", team=~"$team", integration=~"$integration"}))[$__range:]))',
|
||||
expr: `sort_desc(avg_over_time((sum by (integration)($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration"}) / sum by (integration)($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[$__range:]))`,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -105,14 +105,14 @@ export default function getMTTRByIntegrationScene({ datasource }: InsightsConfig
|
|||
},
|
||||
{
|
||||
id: 'custom.width',
|
||||
value: 300,
|
||||
value: 200,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
cellHeight: 'sm',
|
||||
cellHeight: 'md',
|
||||
footer: {
|
||||
countRows: false,
|
||||
fields: '',
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getMTTRByTeamScene({ datasource }: InsightsConfig) {
|
||||
export function getMTTRByTeamScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'sort_desc(avg_over_time((sum by(team) ($alert_groups_response_time_seconds_sum{slug=~"$stack", team=~"$team", integration=~"$integration"}) / sum by(team)($alert_groups_response_time_seconds_count{slug=~"$stack", team=~"$team", integration=~"$integration"}))[$__range:]))',
|
||||
expr: `sort_desc(avg_over_time((sum by(team) ($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration"}) / sum by(team)($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[$__range:]))`,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -47,7 +47,7 @@ export default function getMTTRByTeamScene({ datasource }: InsightsConfig) {
|
|||
return new SceneFlexItem({
|
||||
$data: transformedData,
|
||||
body: new VizPanel({
|
||||
title: 'Mean time to respond by Team (MTTR)',
|
||||
title: 'Mean time to respond (MTTR) by Team',
|
||||
pluginId: 'table',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -102,7 +102,7 @@ export default function getMTTRByTeamScene({ datasource }: InsightsConfig) {
|
|||
],
|
||||
},
|
||||
options: {
|
||||
cellHeight: 'sm',
|
||||
cellHeight: 'md',
|
||||
footer: {
|
||||
countRows: false,
|
||||
fields: '',
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@ import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getMTTRChangedForPeriodTimeseriesScene({ datasource }: InsightsConfig) {
|
||||
export function getMTTRChangedTimeseriesScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'avg(sum($alert_groups_response_time_seconds_sum{slug=~"$stack", team=~"$team", integration=~"$integration"}) / sum($alert_groups_response_time_seconds_count{slug=~"$stack", team=~"$team", integration=~"$integration"}))',
|
||||
expr: `avg(sum($alert_groups_response_time_seconds_sum{slug=~"${stack}", team=~"$team", integration=~"$integration"}) / sum($alert_groups_response_time_seconds_count{slug=~"${stack}", team=~"$team", integration=~"$integration"}))`,
|
||||
instant: false,
|
||||
legendFormat: '__auto',
|
||||
range: true,
|
||||
|
|
@ -22,7 +22,7 @@ export default function getMTTRChangedForPeriodTimeseriesScene({ datasource }: I
|
|||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
title: 'MTTR changed for period',
|
||||
title: 'Mean time to respond (MTTR) changed',
|
||||
pluginId: 'timeseries',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -3,7 +3,7 @@ import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getNewAlertGroupsForSelectedPeriodScene({ datasource }: InsightsConfig) {
|
||||
export function getNewAlertGroupsScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
|
|
@ -12,7 +12,7 @@ export default function getNewAlertGroupsForSelectedPeriodScene({ datasource }:
|
|||
editorMode: 'code',
|
||||
excludeNullMetadata: false,
|
||||
exemplar: false,
|
||||
expr: 'increase(max_over_time(sum(avg without(pod, instance) ($alert_groups_total{slug=~"$stack", team=~"$team", integration=~"$integration"}))[1d:])[$__range:])',
|
||||
expr: `delta(max_over_time(sum(avg without(pod, instance) ($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[30m:])[$__range:]) >= 0`,
|
||||
format: 'time_series',
|
||||
fullMetaSearch: false,
|
||||
includeNullMetadata: true,
|
||||
|
|
@ -28,7 +28,7 @@ export default function getNewAlertGroupsForSelectedPeriodScene({ datasource }:
|
|||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
title: 'New alert groups for selected period',
|
||||
title: 'New alert groups',
|
||||
pluginId: 'stat',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
import { ThresholdsMode } from '@grafana/data';
|
||||
import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getNewAlertGroupsNotificationsInTotalScene({ datasource }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'sort_desc(max_over_time(sum by(username) (avg without(pod, instance)($user_was_notified_of_alert_groups_total{slug=~"$stack"}))[1d:]))',
|
||||
format: 'table',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
range: false,
|
||||
refId: 'A',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const transformedData = new SceneDataTransformer({
|
||||
$data: query,
|
||||
transformations: [
|
||||
{
|
||||
id: 'seriesToRows',
|
||||
options: {},
|
||||
},
|
||||
{
|
||||
id: 'organize',
|
||||
options: {
|
||||
excludeByName: {
|
||||
Time: true,
|
||||
username: false,
|
||||
},
|
||||
indexByName: {},
|
||||
renameByName: {
|
||||
Metric: 'Integration',
|
||||
Value: 'Alert groups',
|
||||
team: 'Team',
|
||||
username: 'Username',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return new SceneFlexItem({
|
||||
$data: transformedData,
|
||||
body: new VizPanel({
|
||||
title: 'New alert groups notifications in total',
|
||||
pluginId: 'table',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
color: {
|
||||
mode: 'thresholds',
|
||||
},
|
||||
custom: {
|
||||
align: 'auto',
|
||||
cellOptions: {
|
||||
mode: 'gradient',
|
||||
type: 'gauge',
|
||||
valueDisplayMode: 'color',
|
||||
},
|
||||
filterable: false,
|
||||
inspect: false,
|
||||
},
|
||||
mappings: [],
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{
|
||||
color: 'green',
|
||||
value: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byName',
|
||||
options: 'Username',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'custom.cellOptions',
|
||||
value: {
|
||||
type: 'auto',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'custom.width',
|
||||
value: 300,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
cellHeight: 'sm',
|
||||
footer: {
|
||||
countRows: false,
|
||||
fields: '',
|
||||
reducer: ['sum'],
|
||||
show: false,
|
||||
},
|
||||
showHeader: true,
|
||||
},
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
|
@ -3,14 +3,14 @@ import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getNewAlertGroupsNotificationsForPeriodTableScene({ datasource }: InsightsConfig) {
|
||||
export function getNewAlertGroupsNotificationsTableScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
editorMode: 'code',
|
||||
exemplar: false,
|
||||
expr: 'sort_desc(increase(max_over_time(sum by (username) (avg without(pod, instance) ($user_was_notified_of_alert_groups_total{slug=~"$stack"}))[1h:])[$__range:]))',
|
||||
expr: `sort_desc(delta(max_over_time(sum by (username) (avg without(pod, instance) ($user_was_notified_of_alert_groups_total{slug=~"${stack}"}))[1h:])[$__range:])>=0)`,
|
||||
format: 'table',
|
||||
instant: true,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -49,7 +49,7 @@ export default function getNewAlertGroupsNotificationsForPeriodTableScene({ data
|
|||
return new SceneFlexItem({
|
||||
$data: transformedData,
|
||||
body: new VizPanel({
|
||||
title: 'New alert groups notifications for period',
|
||||
title: 'New alert groups notifications',
|
||||
pluginId: 'table',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -99,7 +99,7 @@ export default function getNewAlertGroupsNotificationsForPeriodTableScene({ data
|
|||
],
|
||||
},
|
||||
options: {
|
||||
cellHeight: 'sm',
|
||||
cellHeight: 'md',
|
||||
footer: {
|
||||
countRows: false,
|
||||
fields: '',
|
||||
|
|
@ -3,7 +3,7 @@ import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getNewAlertGroupsNotificationsDuringTimePeriodScene({ datasource }: InsightsConfig) {
|
||||
export function getNewAlertGroupsNotificationsTimeseriesScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
|
|
@ -12,7 +12,7 @@ export default function getNewAlertGroupsNotificationsDuringTimePeriodScene({ da
|
|||
editorMode: 'code',
|
||||
excludeNullMetadata: false,
|
||||
exemplar: false,
|
||||
expr: 'increase(max_over_time(sum by (username) (avg without(pod, instance) ($user_was_notified_of_alert_groups_total{slug=~"$stack"}))[30m:])[1h:])',
|
||||
expr: `delta(max_over_time(sum by (username) (avg without(pod, instance) ($user_was_notified_of_alert_groups_total{slug=~"${stack}"}))[30m:])[1h:]) >= 0`,
|
||||
fullMetaSearch: false,
|
||||
instant: false,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -26,7 +26,7 @@ export default function getNewAlertGroupsNotificationsDuringTimePeriodScene({ da
|
|||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
title: 'New alert groups notifications during time period',
|
||||
title: 'New alert groups notifications',
|
||||
pluginId: 'timeseries',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -3,7 +3,7 @@ import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
|||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getNewAlertGroupsDuringTimePeriodScene({ datasource }: InsightsConfig) {
|
||||
export function getNewAlertGroupsTimeseriesScene({ datasource, stack }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
|
|
@ -12,7 +12,7 @@ export default function getNewAlertGroupsDuringTimePeriodScene({ datasource }: I
|
|||
editorMode: 'code',
|
||||
excludeNullMetadata: false,
|
||||
exemplar: false,
|
||||
expr: 'increase(max_over_time(sum by (integration) (avg without(pod, instance) ($alert_groups_total{slug=~"$stack", team=~"$team", integration=~"$integration"}))[30m:])[1h:])',
|
||||
expr: `delta(max_over_time(sum by (integration) (avg without(pod, instance) ($alert_groups_total{slug=~"${stack}", team=~"$team", integration=~"$integration"}))[30m:])[1h:]) >= 0`,
|
||||
fullMetaSearch: false,
|
||||
instant: false,
|
||||
legendFormat: '__auto',
|
||||
|
|
@ -26,7 +26,7 @@ export default function getNewAlertGroupsDuringTimePeriodScene({ datasource }: I
|
|||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
title: 'New alert groups during time period',
|
||||
title: 'New alert groups',
|
||||
pluginId: 'timeseries',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
import { ThresholdsMode } from '@grafana/data';
|
||||
import { SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getTotalAlertGroupsScene({ datasource }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
disableTextWrap: false,
|
||||
editorMode: 'code',
|
||||
excludeNullMetadata: false,
|
||||
exemplar: false,
|
||||
expr: 'max_over_time(sum(avg without(pod, instance) ($alert_groups_total{slug=~"$stack", team=~"$team", integration=~"$integration"}))[1d:])',
|
||||
format: 'time_series',
|
||||
fullMetaSearch: false,
|
||||
instant: false,
|
||||
legendFormat: '__auto',
|
||||
range: true,
|
||||
refId: 'A',
|
||||
useBackend: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return new SceneFlexItem({
|
||||
$data: query,
|
||||
body: new VizPanel({
|
||||
pluginId: 'stat',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
color: {
|
||||
mode: 'thresholds',
|
||||
},
|
||||
mappings: [],
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{
|
||||
color: 'text',
|
||||
value: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
unit: 'none',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byName',
|
||||
options: 'Value',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'displayName',
|
||||
value: 'Total alert groups',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
colorMode: 'value',
|
||||
graphMode: 'none',
|
||||
justifyMode: 'center',
|
||||
orientation: 'auto',
|
||||
reduceOptions: {
|
||||
calcs: ['lastNotNull'],
|
||||
fields: '',
|
||||
values: false,
|
||||
},
|
||||
textMode: 'auto',
|
||||
},
|
||||
pluginVersion: '9.5.2',
|
||||
title: 'Total alert groups',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
import { ThresholdsMode } from '@grafana/data';
|
||||
import { SceneDataTransformer, SceneFlexItem, SceneQueryRunner, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { InsightsConfig } from 'pages/insights/Insights.types';
|
||||
|
||||
export default function getTotalAlertGroupsByStateScene({ datasource }: InsightsConfig) {
|
||||
const query = new SceneQueryRunner({
|
||||
datasource,
|
||||
queries: [
|
||||
{
|
||||
disableTextWrap: false,
|
||||
editorMode: 'code',
|
||||
excludeNullMetadata: false,
|
||||
expr: 'sum by (state) (avg without(pod, instance) ($alert_groups_total{slug=~"$stack", team=~"$team", integration=~"$integration"}))',
|
||||
fullMetaSearch: false,
|
||||
legendFormat: '__auto',
|
||||
range: true,
|
||||
refId: 'A',
|
||||
useBackend: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const transformedData = new SceneDataTransformer({
|
||||
$data: query,
|
||||
transformations: [
|
||||
{
|
||||
id: 'joinByLabels',
|
||||
options: {
|
||||
value: 'state',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'organize',
|
||||
options: {
|
||||
excludeByName: {},
|
||||
indexByName: {
|
||||
acknowledged: 1,
|
||||
firing: 0,
|
||||
resolved: 2,
|
||||
silenced: 3,
|
||||
},
|
||||
renameByName: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return new SceneFlexItem({
|
||||
$data: transformedData,
|
||||
body: new VizPanel({
|
||||
title: 'Total alert groups by state',
|
||||
pluginId: 'bargauge',
|
||||
fieldConfig: {
|
||||
defaults: {
|
||||
color: {
|
||||
mode: 'thresholds',
|
||||
},
|
||||
mappings: [],
|
||||
thresholds: {
|
||||
mode: ThresholdsMode.Absolute,
|
||||
steps: [
|
||||
{
|
||||
color: 'green',
|
||||
value: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
matcher: {
|
||||
id: 'byName',
|
||||
options: 'firing',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'color',
|
||||
value: {
|
||||
fixedColor: 'red',
|
||||
mode: 'fixed',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
matcher: {
|
||||
id: 'byName',
|
||||
options: 'acknowledged',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'color',
|
||||
value: {
|
||||
fixedColor: 'dark-yellow',
|
||||
mode: 'fixed',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
matcher: {
|
||||
id: 'byName',
|
||||
options: 'silenced',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
id: 'color',
|
||||
value: {
|
||||
mode: 'fixed',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
options: {
|
||||
displayMode: 'gradient',
|
||||
minVizHeight: 10,
|
||||
minVizWidth: 0,
|
||||
orientation: 'vertical',
|
||||
reduceOptions: {
|
||||
calcs: ['lastNotNull'],
|
||||
fields: '',
|
||||
values: false,
|
||||
},
|
||||
showUnfilled: true,
|
||||
valueMode: 'color',
|
||||
},
|
||||
pluginVersion: '9.5.2',
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
|
@ -26,18 +26,6 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({
|
|||
}),
|
||||
}
|
||||
: {}),
|
||||
stack: new QueryVariable({
|
||||
...DEFAULT_VARIABLE_CONFIG,
|
||||
name: 'stack',
|
||||
label: 'Stack',
|
||||
value: stack,
|
||||
datasource,
|
||||
definition: 'label_values(${alert_groups_total},slug)',
|
||||
query: {
|
||||
query: 'label_values(${alert_groups_total},slug)',
|
||||
refId: 'PrometheusVariableQueryEditor-VariableQuery',
|
||||
},
|
||||
}),
|
||||
team: new QueryVariable({
|
||||
...DEFAULT_VARIABLE_CONFIG,
|
||||
name: 'team',
|
||||
|
|
@ -45,9 +33,9 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({
|
|||
text: ['All'],
|
||||
value: ['$__all'],
|
||||
datasource,
|
||||
definition: 'label_values(${alert_groups_total}{slug=~"$stack"},team)',
|
||||
definition: `label_values(\${alert_groups_total}{slug=~"${stack}"},team)`,
|
||||
query: {
|
||||
query: 'label_values(${alert_groups_total}{slug=~"$stack"},team)',
|
||||
query: `label_values(\${alert_groups_total}{slug=~"${stack}"},team)`,
|
||||
refId: 'PrometheusVariableQueryEditor-VariableQuery',
|
||||
},
|
||||
refresh: 2,
|
||||
|
|
@ -59,9 +47,9 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({
|
|||
text: ['All'],
|
||||
value: ['$__all'],
|
||||
datasource,
|
||||
definition: 'label_values(${alert_groups_total}{team=~"$team",slug=~"$stack"},integration)',
|
||||
definition: `label_values(\${alert_groups_total}{team=~"$team",slug=~"${stack}"},integration)`,
|
||||
query: {
|
||||
query: 'label_values(${alert_groups_total}{team=~"$team",slug=~"$stack"},integration)',
|
||||
query: `label_values(\${alert_groups_total}{team=~"$team",slug=~"${stack}"},integration)`,
|
||||
refId: 'PrometheusVariableQueryEditor-VariableQuery',
|
||||
},
|
||||
refresh: 2,
|
||||
|
|
@ -77,8 +65,8 @@ const getVariables = ({ isOpenSource, datasource, stack }: InsightsConfig) => ({
|
|||
query: 'metrics(alert_groups_total)',
|
||||
refId: 'PrometheusVariableQueryEditor-VariableQuery',
|
||||
},
|
||||
text: ['oncall_alert_groups_total', 'grafanacloud_oncall_stack_alert_groups_total'],
|
||||
value: ['oncall_alert_groups_total', 'grafanacloud_oncall_stack_alert_groups_total'],
|
||||
text: ['oncall_alert_groups_total', 'grafanacloud_oncall_instance_alert_groups_total'],
|
||||
value: ['oncall_alert_groups_total', 'grafanacloud_oncall_instance_alert_groups_total'],
|
||||
definition: 'metrics(alert_groups_total)',
|
||||
hide: 2,
|
||||
includeAll: false,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ import React, { useEffect, useRef, useState } from 'react';
|
|||
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { ActionKey } from 'models/loader/action-keys';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
||||
export function useForceUpdate() {
|
||||
const [, setValue] = useState(0);
|
||||
return () => setValue((value) => value + 1);
|
||||
|
|
@ -69,3 +72,10 @@ export function useDebouncedCallback<A extends any[]>(callback: (...args: A) =>
|
|||
}, wait);
|
||||
};
|
||||
}
|
||||
|
||||
export const useIsLoading = (actionKey: ActionKey) => {
|
||||
const {
|
||||
loaderStore: { isLoading },
|
||||
} = useStore();
|
||||
return isLoading(actionKey);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue