Skip to content

Commit

Permalink
feat: multiple alerts matching rules PoC (#2727)
Browse files Browse the repository at this point in the history
  • Loading branch information
VladimirFilonov authored Dec 25, 2024
1 parent 4256d64 commit 0940902
Show file tree
Hide file tree
Showing 17 changed files with 479 additions and 111 deletions.
30 changes: 25 additions & 5 deletions keep-ui/app/(keep)/rules/CorrelationSidebar/CorrelationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const CorrelationForm = ({
/>
</span>
</fieldset>
<fieldset className="grid grid-cols-2">
<fieldset className="grid grid-cols-3">
<div className="mr-10">
<label
className="flex items-center text-tremor-default font-medium text-tremor-content-strong"
Expand All @@ -109,7 +109,7 @@ export const CorrelationForm = ({
<Controller
control={control}
name="groupedAttributes"
render={({ field: { value, onChange } }) => (
render={({field: {value, onChange}}) => (
<MultiSelect
className="mt-2"
value={value}
Expand All @@ -126,7 +126,7 @@ export const CorrelationForm = ({
/>
</div>

<div>
<div className="mr-10">
<label
className="flex items-center text-tremor-default font-medium text-tremor-content-strong"
htmlFor="resolveOn"
Expand All @@ -137,7 +137,7 @@ export const CorrelationForm = ({
<Controller
control={control}
name="resolveOn"
render={({ field: { value, onChange } }) => (
render={({field: {value, onChange}}) => (
<Select value={value} onValueChange={onChange} className="mt-2">
<SelectItem value="never">No auto-resolution</SelectItem>
<SelectItem value="all">All alerts resolved</SelectItem>
Expand All @@ -147,13 +147,33 @@ export const CorrelationForm = ({
)}
/>
</div>

<div>
<label
className="flex items-center text-tremor-default font-medium text-tremor-content-strong"
htmlFor="resolveOn"
>
Start incident on{" "}
</label>

<Controller
control={control}
name="createOn"
render={({field: {value, onChange}}) => (
<Select value={value} onValueChange={onChange} className="mt-2">
<SelectItem value="any">Any condition met</SelectItem>
<SelectItem value="all">All conditions met</SelectItem>
</Select>
)}
/>
</div>
</fieldset>

<div className="flex items-center space-x-2">
<Controller
control={control}
name="requireApprove"
render={({ field: { value, onChange } }) => (
render={({field: {value, onChange}}) => (
<Switch
color="orange"
id="requireManualApprove"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const CorrelationSidebarBody = ({
groupedAttributes,
requireApprove,
resolveOn,
createOn,
} = correlationFormData;

const body = {
Expand All @@ -77,6 +78,7 @@ export const CorrelationSidebarBody = ({
groupingCriteria: alertsFound.length ? groupedAttributes : [],
requireApprove: requireApprove,
resolveOn: resolveOn,
createOn: createOn,
};

try {
Expand Down
1 change: 1 addition & 0 deletions keep-ui/app/(keep)/rules/CorrelationSidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const DEFAULT_CORRELATION_FORM_VALUES: CorrelationFormType = {
groupedAttributes: [],
requireApprove: false,
resolveOn: "never",
createOn: "any",
query: {
combinator: "or",
rules: [
Expand Down
1 change: 1 addition & 0 deletions keep-ui/app/(keep)/rules/CorrelationSidebar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export type CorrelationFormType = {
groupedAttributes: string[];
requireApprove: boolean;
resolveOn: "all" | "first" | "last" | "never";
createOn: "any" | "all";
query: RuleGroupType;
};
1 change: 1 addition & 0 deletions keep-ui/app/(keep)/rules/CorrelationTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export const CorrelationTable = ({ rules }: CorrelationTableProps) => {
groupedAttributes: selectedRule.grouping_criteria,
requireApprove: selectedRule.require_approve,
resolveOn: selectedRule.resolve_on,
createOn: selectedRule.create_on,
query: queryInGroup,
incidents: selectedRule.incidents,
};
Expand Down
1 change: 1 addition & 0 deletions keep-ui/utils/hooks/useRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type Rule = {
update_time: string | null;
require_approve: boolean;
resolve_on: "all" | "first" | "last" | "never";
create_on: "any" | "all";
distribution: { [group: string]: { [timestamp: string]: number } };
incidents: number;
};
Expand Down
30 changes: 11 additions & 19 deletions keep/api/bl/incidents_bl.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ def create_incident(
"Incident DTO created",
extra={"incident_id": new_incident_dto.id, "tenant_id": self.tenant_id},
)
self.__update_client_on_incident_change()
self.update_client_on_incident_change()
self.logger.info(
"Client updated on incident change",
extra={"incident_id": new_incident_dto.id, "tenant_id": self.tenant_id},
)
self.__run_workflows(new_incident_dto, "created")
self.send_workflow_event(new_incident_dto, "created")
self.logger.info(
"Workflows run on incident",
extra={"incident_id": new_incident_dto.id, "tenant_id": self.tenant_id},
Expand Down Expand Up @@ -134,7 +134,7 @@ def __update_elastic(self, alert_fingerprints: List[str]):
self.logger.exception("Failed to push alert to elasticsearch")
raise

def __update_client_on_incident_change(self, incident_id: Optional[UUID] = None):
def update_client_on_incident_change(self, incident_id: Optional[UUID] = None):
if self.pusher_client is not None:
self.logger.info(
"Pushing incident change to client",
Expand All @@ -150,7 +150,7 @@ def __update_client_on_incident_change(self, incident_id: Optional[UUID] = None)
extra={"incident_id": incident_id, "tenant_id": self.tenant_id},
)

def __run_workflows(self, incident_dto: IncidentDto, action: str):
def send_workflow_event(self, incident_dto: IncidentDto, action: str) -> None:
try:
workflow_manager = WorkflowManager.get_instance()
workflow_manager.insert_incident(self.tenant_id, incident_dto, action)
Expand Down Expand Up @@ -227,17 +227,9 @@ def delete_incident(self, incident_id: UUID) -> None:
)
if not deleted:
raise HTTPException(status_code=404, detail="Incident not found")
self.__update_client_on_incident_change()
try:
workflow_manager = WorkflowManager.get_instance()
self.logger.info("Adding incident to the workflow manager queue")
workflow_manager.insert_incident(self.tenant_id, incident_dto, "deleted")
self.logger.info("Added incident to the workflow manager queue")
except Exception:
self.logger.exception(
"Failed to run workflows based on incident",
extra={"incident_id": incident_dto.id, "tenant_id": self.tenant_id},
)

self.update_client_on_incident_change()
self.send_workflow_event(incident_dto, "deleted")

def update_incident(
self,
Expand All @@ -260,12 +252,12 @@ def update_incident(

new_incident_dto = IncidentDto.from_db_incident(incident)

self.__update_client_on_incident_change(incident.id)
self.update_client_on_incident_change(incident.id)
self.logger.info(
"Client updated on incident change",
extra={"incident_id": incident.id},
)
self.__run_workflows(new_incident_dto, "updated")
self.send_workflow_event(new_incident_dto, "updated")
self.logger.info(
"Workflows run on incident",
extra={"incident_id": incident.id},
Expand All @@ -279,13 +271,13 @@ def __postprocess_alerts_change(self, incident, alert_fingerprints):
"Alerts pushed to elastic",
extra={"incident_id": incident.id, "alert_fingerprints": alert_fingerprints},
)
self.__update_client_on_incident_change(incident.id)
self.update_client_on_incident_change(incident.id)
self.logger.info(
"Client updated on incident change",
extra={"incident_id": incident.id, "alert_fingerprints": alert_fingerprints},
)
incident_dto = IncidentDto.from_db_incident(incident)
self.__run_workflows(incident_dto, "updated")
self.send_workflow_event(incident_dto, "updated")
self.logger.info(
"Workflows run on incident",
extra={"incident_id": incident.id, "alert_fingerprints": alert_fingerprints},
Expand Down
Loading

0 comments on commit 0940902

Please sign in to comment.