useGroupedAlerts.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { uniqBy } from 'lodash';
  2. import { useMemo } from 'react';
  3. import { Labels } from '@grafana/data';
  4. import { AlertmanagerGroup } from 'app/plugins/datasource/alertmanager/types';
  5. export const useGroupedAlerts = (groups: AlertmanagerGroup[], groupBy: string[]): AlertmanagerGroup[] => {
  6. return useMemo(() => {
  7. if (groupBy.length === 0) {
  8. const emptyGroupings = groups.filter((group) => Object.keys(group.labels).length === 0);
  9. if (emptyGroupings.length > 1) {
  10. // Merges multiple ungrouped grouping
  11. return groups.reduce((combinedGroups, group) => {
  12. if (Object.keys(group.labels).length === 0) {
  13. const noGroupingGroup = combinedGroups.find(({ labels }) => Object.keys(labels));
  14. if (!noGroupingGroup) {
  15. combinedGroups.push({ alerts: group.alerts, labels: {}, receiver: { name: 'NONE' } });
  16. } else {
  17. noGroupingGroup.alerts = uniqBy([...noGroupingGroup.alerts, ...group.alerts], 'labels');
  18. }
  19. } else {
  20. combinedGroups.push(group);
  21. }
  22. return combinedGroups;
  23. }, [] as AlertmanagerGroup[]);
  24. } else {
  25. return groups;
  26. }
  27. }
  28. const alerts = groups.flatMap(({ alerts }) => alerts);
  29. return alerts.reduce((groupings, alert) => {
  30. const alertContainsGroupings = groupBy.every((groupByLabel) => Object.keys(alert.labels).includes(groupByLabel));
  31. if (alertContainsGroupings) {
  32. const existingGrouping = groupings.find((group) => {
  33. return groupBy.every((groupKey) => {
  34. return group.labels[groupKey] === alert.labels[groupKey];
  35. });
  36. });
  37. if (!existingGrouping) {
  38. const labels = groupBy.reduce((acc, key) => {
  39. acc = { ...acc, [key]: alert.labels[key] };
  40. return acc;
  41. }, {} as Labels);
  42. groupings.push({
  43. alerts: [alert],
  44. labels,
  45. receiver: {
  46. name: 'NONE',
  47. },
  48. });
  49. } else {
  50. existingGrouping.alerts.push(alert);
  51. }
  52. } else {
  53. const noGroupingGroup = groupings.find((group) => Object.keys(group.labels).length === 0);
  54. if (!noGroupingGroup) {
  55. groupings.push({ alerts: [alert], labels: {}, receiver: { name: 'NONE' } });
  56. } else {
  57. noGroupingGroup.alerts.push(alert);
  58. }
  59. }
  60. return groupings;
  61. }, [] as AlertmanagerGroup[]);
  62. }, [groups, groupBy]);
  63. };