From 3b029141e8a771b75669604d77193e528b66c0e4 Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 10 Apr 2024 15:24:48 +0300 Subject: [PATCH 1/4] fix(provider): linearb to accept issued_at (#1086) --- keep/providers/linearb_provider/linearb_provider.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keep/providers/linearb_provider/linearb_provider.py b/keep/providers/linearb_provider/linearb_provider.py index 88e08105d..a7e06baa9 100644 --- a/keep/providers/linearb_provider/linearb_provider.py +++ b/keep/providers/linearb_provider/linearb_provider.py @@ -74,6 +74,7 @@ def _notify( ended_at="", git_ref="", should_delete="", + issued_at="", **kwargs: dict, ): """ @@ -165,7 +166,7 @@ def _notify( "At least 1 team is required for creating an incident" ) - issued_at = datetime.datetime.now().isoformat() + issued_at = issued_at or datetime.datetime.now().isoformat() payload = { "provider_id": incident_id, From 49ccf0a5b0f4b058dff10b53473fce678f5afdaf Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 10 Apr 2024 17:55:10 +0300 Subject: [PATCH 2/4] fix(api): maximum response size and linearb services (#1087) --- keep/api/api.py | 4 ++++ .../linearb_provider/linearb_provider.py | 2 ++ keep/step/step.py | 21 ++++++++++++------- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/keep/api/api.py b/keep/api/api.py index 90e764bbe..16584c184 100644 --- a/keep/api/api.py +++ b/keep/api/api.py @@ -6,6 +6,7 @@ import uvicorn from dotenv import find_dotenv, load_dotenv from fastapi import FastAPI, HTTPException, Request, Response +from fastapi.middleware.gzip import GZipMiddleware from fastapi.responses import JSONResponse from opentelemetry import trace from starlette.middleware.base import BaseHTTPMiddleware @@ -134,6 +135,9 @@ def get_app( version="0.1.0", ) app.add_middleware(RawContextMiddleware, plugins=(plugins.RequestIdPlugin(),)) + app.add_middleware( + GZipMiddleware, minimum_size=30 * 1024 * 1024 + ) # Approximately 30 MiB, https://cloud.google.com/run/quotas app.add_middleware( CORSMiddleware, allow_origins=["*"], diff --git a/keep/providers/linearb_provider/linearb_provider.py b/keep/providers/linearb_provider/linearb_provider.py index a7e06baa9..1c6aeb6c2 100644 --- a/keep/providers/linearb_provider/linearb_provider.py +++ b/keep/providers/linearb_provider/linearb_provider.py @@ -135,6 +135,8 @@ def _notify( if services: if isinstance(services, str): services = json.loads(services) + if len(services) > 0 and isinstance(services[0], dict): + services = [service["name"] for service in services] payload["services"] = services elif "services" in payload: service_names = [service["name"] for service in payload["services"]] diff --git a/keep/step/step.py b/keep/step/step.py index 7e37d98ba..e786946dc 100644 --- a/keep/step/step.py +++ b/keep/step/step.py @@ -73,7 +73,9 @@ def _check_throttling(self, action_name): throttling_type = throttling.get("type") throttling_config = throttling.get("with") - throttle = ThrottleFactory.get_instance(self.context_manager, throttling_type, throttling_config) + throttle = ThrottleFactory.get_instance( + self.context_manager, throttling_type, throttling_config + ) alert_id = self.context_manager.get_workflow_id() return throttle.check_throttling(action_name, alert_id) @@ -201,19 +203,24 @@ def _run_single(self): else: evaluated_if_met = True + action_name = self.config.get("name") if not evaluated_if_met: self.logger.info( - "Action %s evaluated NOT to run, Reason: %s evaluated to false.", - self.config.get("name"), - if_met, + f"Action {action_name} evaluated NOT to run, Reason: {if_met} evaluated to false.", + extra={ + "condition": if_conf, + "rendered": if_met, + }, ) return if if_conf: self.logger.info( - "Action %s evaluated to run! Reason: %s evaluated to true.", - self.config.get("name"), - if_met, + f"Action {action_name} evaluated to run! Reason: {if_met} evaluated to true.", + extra={ + "condition": if_conf, + "rendered": if_met, + }, ) else: self.logger.info( From 6d441e858d9b47cede72b3e098fb3311d52ff169 Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 10 Apr 2024 19:45:45 +0300 Subject: [PATCH 3/4] fix(api): slow workflows endpoint (#1090) --- keep-ui/app/workflows/[workflow_id]/page.tsx | 2 +- .../runs/[workflow_execution_id]/layout.tsx | 11 -- .../runs/[workflow_execution_id]/page.tsx | 102 +++++++++--------- keep/api/routes/workflows.py | 22 ++-- 4 files changed, 64 insertions(+), 73 deletions(-) delete mode 100644 keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/layout.tsx diff --git a/keep-ui/app/workflows/[workflow_id]/page.tsx b/keep-ui/app/workflows/[workflow_id]/page.tsx index d213a7fab..764792ec3 100644 --- a/keep-ui/app/workflows/[workflow_id]/page.tsx +++ b/keep-ui/app/workflows/[workflow_id]/page.tsx @@ -100,7 +100,7 @@ export default function WorkflowDetailPage({ {workflowExecutions.map((execution) => ( - {execution.started} + {new Date(execution.started + "Z").toLocaleString()} {execution.id} {execution.triggered_by} {execution.status} diff --git a/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/layout.tsx b/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/layout.tsx deleted file mode 100644 index d096de65d..000000000 --- a/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/layout.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { Card, Title, Subtitle } from "@tremor/react"; - -export default function Layout({ children }: { children: any }) { - return ( - <> -
-
{children}
-
- - ); -} diff --git a/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/page.tsx b/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/page.tsx index 7c2774a2f..37822ff61 100644 --- a/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/page.tsx +++ b/keep-ui/app/workflows/[workflow_id]/runs/[workflow_execution_id]/page.tsx @@ -122,11 +122,11 @@ export default function WorkflowExecutionPage({ {stepId} - + Value -
+                        
                           {JSON.stringify(stepResults, null, 2)}
                         
@@ -140,43 +140,61 @@ export default function WorkflowExecutionPage({ )}
0 ? "mt-8" : ""}> {executionStatus === "success" ? ( - - Workflow Logs - - - - - Timestamp - - - Message - - - - - {logs.map((log, index) => ( - + <> + {error && ( + + {error + ? error.split("\n").map((line, index) => ( + // Render each line as a separate paragraph or div. + // The key is index, which is sufficient for simple lists like this. +

{line}

+ )) + : "An unknown error occurred during execution."} +
+ )} + + Workflow Logs +
+ + - {log.timestamp} + Timestamp - {log.message} + Message - ))} - -
-
- ) : executionStatus === "in_progress" ? ( + + + {logs.map((log, index) => ( + + + {log.timestamp} + + + {log.message} + + + ))} + + + + + ) : (

@@ -186,22 +204,6 @@ export default function WorkflowExecutionPage({

- ) : ( - - {error - ? error.split('\n').map((line, index) => ( - // Render each line as a separate paragraph or div. - // The key is index, which is sufficient for simple lists like this. -

{line}

- )) - : "An unknown error occurred during execution." - } -
)}
diff --git a/keep/api/routes/workflows.py b/keep/api/routes/workflows.py index a3f81e805..a53743700 100644 --- a/keep/api/routes/workflows.py +++ b/keep/api/routes/workflows.py @@ -386,19 +386,19 @@ def get_workflow_by_id( workflow_executions_dtos = [] with tracer.start_as_current_span("create_workflow_dtos"): for workflow_execution in workflow_executions: - workflow_execution_dto = WorkflowExecutionDTO( - id=workflow_execution.id, - workflow_id=workflow_execution.workflow_id, - status=workflow_execution.status, - started=workflow_execution.started, - triggered_by=workflow_execution.triggered_by, - error=workflow_execution.error, - execution_time=workflow_execution.execution_time, - results=workflow_execution.results, - ) + workflow_execution_dto = { + "id": workflow_execution.id, + "workflow_id": workflow_execution.workflow_id, + "status": workflow_execution.status, + "started": workflow_execution.started.isoformat(), + "triggered_by": workflow_execution.triggered_by, + "error": workflow_execution.error, + "execution_time": workflow_execution.execution_time, + "results": workflow_execution.results, + } workflow_executions_dtos.append(workflow_execution_dto) - return workflow_executions_dtos + return JSONResponse(content=workflow_executions_dtos) @router.delete("/{workflow_id}", description="Delete workflow") From a2cc3597a740516111826a06ffb1bdd6f2b2ad54 Mon Sep 17 00:00:00 2001 From: Tal Date: Wed, 10 Apr 2024 20:07:40 +0300 Subject: [PATCH 4/4] fix(api): remove results from workflows response (#1091) --- keep/api/core/db.py | 10 +++++++++- keep/api/routes/workflows.py | 1 - 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/keep/api/core/db.py b/keep/api/core/db.py index 6449a8b24..ba2a32312 100644 --- a/keep/api/core/db.py +++ b/keep/api/core/db.py @@ -688,7 +688,15 @@ def finish_workflow_execution(tenant_id, workflow_id, execution_id, status, erro def get_workflow_executions(tenant_id, workflow_id, limit=50): with Session(engine) as session: workflow_executions = session.exec( - select(WorkflowExecution) + select( + WorkflowExecution.id, + WorkflowExecution.workflow_id, + WorkflowExecution.started, + WorkflowExecution.status, + WorkflowExecution.triggered_by, + WorkflowExecution.execution_time, + WorkflowExecution.error, + ) .where(WorkflowExecution.tenant_id == tenant_id) .where(WorkflowExecution.workflow_id == workflow_id) .where( diff --git a/keep/api/routes/workflows.py b/keep/api/routes/workflows.py index a53743700..04dff9638 100644 --- a/keep/api/routes/workflows.py +++ b/keep/api/routes/workflows.py @@ -394,7 +394,6 @@ def get_workflow_by_id( "triggered_by": workflow_execution.triggered_by, "error": workflow_execution.error, "execution_time": workflow_execution.execution_time, - "results": workflow_execution.results, } workflow_executions_dtos.append(workflow_execution_dto)