mirror of https://github.com/grafana/grafana
Alerting: Enable alerts preview on notification policies page (#68291)
* Basic implementation in web worker * Move instances discovery to the worker * Remove filtering from the worker * Use normalized routes, use rtk query for alert groups fetching * Reorganize matchers utilities to be available for web workers * Move object matchers to the machers util file, rename worker * Move worker code to a separate hook, add perf logging * Add a mock for the web worker code, fix tests * Fix tests warnings * Remove notification policy feature flag * Add normalizeRoute tests, change the regex match to test for label matching * Move worker init to the file scope * Simplify useAsyncFn hookpull/68482/head
parent
55622615de
commit
f7b8a666f4
@ -0,0 +1,20 @@ |
||||
import { useCallback } from 'react'; |
||||
|
||||
import { AlertmanagerGroup, RouteWithID } from '../../../../plugins/datasource/alertmanager/types'; |
||||
|
||||
export function useRouteGroupsMatcher() { |
||||
const getRouteGroupsMap = useCallback(async (route: RouteWithID, __: AlertmanagerGroup[]) => { |
||||
const groupsMap = new Map<string, AlertmanagerGroup[]>(); |
||||
function addRoutes(route: RouteWithID) { |
||||
groupsMap.set(route.id, []); |
||||
|
||||
route.routes?.forEach((r) => addRoutes(r)); |
||||
} |
||||
|
||||
addRoutes(route); |
||||
|
||||
return groupsMap; |
||||
}, []); |
||||
|
||||
return { getRouteGroupsMap }; |
||||
} |
@ -1,14 +1,7 @@ |
||||
import { FeatureDescription } from 'react-enable/dist/FeatureState'; |
||||
|
||||
export enum AlertingFeature { |
||||
NotificationPoliciesV2MatchingInstances = 'notification-policies.v2.matching-instances', |
||||
} |
||||
export enum AlertingFeature {} |
||||
|
||||
const FEATURES: FeatureDescription[] = [ |
||||
{ |
||||
name: AlertingFeature.NotificationPoliciesV2MatchingInstances, |
||||
defaultValue: false, |
||||
}, |
||||
]; |
||||
const FEATURES: FeatureDescription[] = []; |
||||
|
||||
export default FEATURES; |
||||
|
@ -0,0 +1,27 @@ |
||||
import * as comlink from 'comlink'; |
||||
|
||||
import type { AlertmanagerGroup, RouteWithID } from '../../../plugins/datasource/alertmanager/types'; |
||||
|
||||
import { findMatchingAlertGroups, normalizeRoute } from './utils/notification-policies'; |
||||
|
||||
const routeGroupsMatcher = { |
||||
getRouteGroupsMap(rootRoute: RouteWithID, groups: AlertmanagerGroup[]): Map<string, AlertmanagerGroup[]> { |
||||
const normalizedRootRoute = normalizeRoute(rootRoute); |
||||
|
||||
function addRouteGroups(route: RouteWithID, acc: Map<string, AlertmanagerGroup[]>) { |
||||
const routeGroups = findMatchingAlertGroups(normalizedRootRoute, route, groups); |
||||
acc.set(route.id, routeGroups); |
||||
|
||||
route.routes?.forEach((r) => addRouteGroups(r, acc)); |
||||
} |
||||
|
||||
const routeGroupsMap = new Map<string, AlertmanagerGroup[]>(); |
||||
addRouteGroups(normalizedRootRoute, routeGroupsMap); |
||||
|
||||
return routeGroupsMap; |
||||
}, |
||||
}; |
||||
|
||||
export type RouteGroupsMatcher = typeof routeGroupsMatcher; |
||||
|
||||
comlink.expose(routeGroupsMatcher); |
@ -0,0 +1,31 @@ |
||||
import * as comlink from 'comlink'; |
||||
import { useCallback } from 'react'; |
||||
|
||||
import { AlertmanagerGroup, RouteWithID } from '../../../plugins/datasource/alertmanager/types'; |
||||
|
||||
import { logInfo } from './Analytics'; |
||||
import type { RouteGroupsMatcher } from './routeGroupsMatcher.worker'; |
||||
|
||||
const worker = new Worker(new URL('./routeGroupsMatcher.worker.ts', import.meta.url), { type: 'module' }); |
||||
const routeMatcher = comlink.wrap<RouteGroupsMatcher>(worker); |
||||
|
||||
export function useRouteGroupsMatcher() { |
||||
const getRouteGroupsMap = useCallback(async (rootRoute: RouteWithID, alertGroups: AlertmanagerGroup[]) => { |
||||
const startTime = performance.now(); |
||||
|
||||
const result = await routeMatcher.getRouteGroupsMap(rootRoute, alertGroups); |
||||
|
||||
const timeSpent = performance.now() - startTime; |
||||
|
||||
logInfo(`Route Groups Matched in ${timeSpent} ms`, { |
||||
matchingTime: timeSpent.toString(), |
||||
alertGroupsCount: alertGroups.length.toString(), |
||||
// Counting all nested routes might be too time-consuming, so we only count the first level
|
||||
topLevelRoutesCount: rootRoute.routes?.length.toString() ?? '0', |
||||
}); |
||||
|
||||
return result; |
||||
}, []); |
||||
|
||||
return { getRouteGroupsMap }; |
||||
} |
Loading…
Reference in new issue