Skip to content

Commit 3288a4a

Browse files
authored
fix(api): add missing logging for Attack Paths query execution and scan error handling (#10269)
1 parent c4d692f commit 3288a4a

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
lines changed

api/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ All notable changes to the **Prowler API** are documented in this file.
1010

1111
---
1212

13+
## [1.20.1] (Prowler UNRELEASED)
14+
15+
### 🐞 Fixed
16+
17+
- Attack Paths: Add missing logging for query execution and exception details in scan error handling [(#10269)](https://github.com/prowler-cloud/prowler/pull/10269)
18+
19+
---
20+
1321
## [1.20.0] (Prowler v5.19.0)
1422

1523
### 🚀 Added

api/src/backend/api/v1/views.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import json
44
import logging
55
import os
6+
import time
67

78
from collections import defaultdict
89
from copy import deepcopy
@@ -2570,14 +2571,35 @@ def run_attack_paths_query(self, request, pk=None):
25702571
provider_id,
25712572
)
25722573

2574+
start = time.monotonic()
25732575
graph = attack_paths_views_helpers.execute_query(
25742576
database_name,
25752577
query_definition,
25762578
parameters,
25772579
provider_id,
25782580
)
2581+
query_duration = time.monotonic() - start
25792582
graph_database.clear_cache(database_name)
25802583

2584+
result_nodes = len(graph.get("nodes", []))
2585+
result_relationships = len(graph.get("relationships", []))
2586+
logger.info(
2587+
"attack_paths_query_run",
2588+
extra={
2589+
"user_id": str(request.user.id),
2590+
"tenant_id": str(attack_paths_scan.provider.tenant_id),
2591+
"metadata": {
2592+
"query_id": query_definition.id,
2593+
"provider": query_definition.provider,
2594+
"scan_id": pk,
2595+
"provider_id": provider_id,
2596+
"result_nodes": result_nodes,
2597+
"result_relationships": result_relationships,
2598+
"query_duration": round(query_duration, 3),
2599+
},
2600+
},
2601+
)
2602+
25812603
status_code = status.HTTP_200_OK
25822604
if not graph.get("nodes"):
25832605
status_code = status.HTTP_404_NOT_FOUND
@@ -2618,13 +2640,35 @@ def run_custom_attack_paths_query(self, request, pk=None):
26182640
)
26192641
provider_id = str(attack_paths_scan.provider_id)
26202642

2643+
start = time.monotonic()
26212644
graph = attack_paths_views_helpers.execute_custom_query(
26222645
database_name,
26232646
serializer.validated_data["query"],
26242647
provider_id,
26252648
)
2649+
query_duration = time.monotonic() - start
26262650
graph_database.clear_cache(database_name)
26272651

2652+
query_length = len(serializer.validated_data["query"])
2653+
result_nodes = len(graph.get("nodes", []))
2654+
result_relationships = len(graph.get("relationships", []))
2655+
logger.info(
2656+
"attack_paths_custom_query_run",
2657+
extra={
2658+
"user_id": str(request.user.id),
2659+
"tenant_id": str(attack_paths_scan.provider.tenant_id),
2660+
"metadata": {
2661+
"provider": attack_paths_scan.provider.provider,
2662+
"scan_id": pk,
2663+
"provider_id": provider_id,
2664+
"query_length": query_length,
2665+
"result_nodes": result_nodes,
2666+
"result_relationships": result_relationships,
2667+
"query_duration": round(query_duration, 3),
2668+
},
2669+
},
2670+
)
2671+
26282672
status_code = status.HTTP_200_OK
26292673
if not graph.get("nodes"):
26302674
status_code = status.HTTP_404_NOT_FOUND

api/src/backend/config/custom_logging.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import logging
33
from enum import StrEnum
44

5+
56
from config.env import env
67
from django_guid.log_filters import CorrelationId
78

@@ -62,6 +63,8 @@ def format(self, record):
6263
log_record["duration"] = record.duration
6364
if hasattr(record, "status_code"):
6465
log_record["status_code"] = record.status_code
66+
if hasattr(record, "metadata"):
67+
log_record["metadata"] = record.metadata
6568

6669
if record.exc_info:
6770
log_record["exc_info"] = self.formatException(record.exc_info)
@@ -107,6 +110,8 @@ def format(self, record):
107110
log_components.append(f"done in {record.duration}s:")
108111
if hasattr(record, "status_code"):
109112
log_components.append(f"{record.status_code}")
113+
if hasattr(record, "metadata"):
114+
log_components.append(f"metadata={record.metadata}")
110115

111116
if record.exc_info:
112117
log_components.append(self.formatException(record.exc_info))

api/src/backend/tasks/jobs/attack_paths/aws.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ def sync_aws_account(
239239
failed_syncs[func_name] = exception_message
240240

241241
logger.warning(
242-
f"Caught exception syncing function {func_name} from AWS account {prowler_api_provider.uid}. We "
243-
"are continuing on to the next AWS sync function.",
242+
f"Caught exception syncing function {func_name} from AWS account {prowler_api_provider.uid}: {e}. "
243+
"Continuing to the next AWS sync function.",
244+
exc_info=True,
244245
)
245246

246247
continue

api/src/backend/tasks/jobs/attack_paths/scan.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,20 @@ def run(tenant_id: str, scan_id: str, task_id: str) -> dict[str, Any]:
212212
try:
213213
graph_database.drop_database(tmp_cartography_config.neo4j_database)
214214

215-
except Exception:
215+
except Exception as e:
216216
logger.error(
217-
f"Failed to drop temporary Neo4j database {tmp_cartography_config.neo4j_database} during cleanup"
217+
f"Failed to drop temporary Neo4j database {tmp_cartography_config.neo4j_database} during cleanup: {e}",
218+
exc_info=True,
218219
)
219220

220221
try:
221222
db_utils.finish_attack_paths_scan(
222223
attack_paths_scan, StateChoices.FAILED, ingestion_exceptions
223224
)
224-
except Exception:
225-
logger.warning(
226-
f"Could not mark attack paths scan {attack_paths_scan.id} as FAILED (row may have been deleted)"
225+
except Exception as e:
226+
logger.error(
227+
f"Could not mark attack paths scan {attack_paths_scan.id} as FAILED (row may have been deleted): {e}",
228+
exc_info=True,
227229
)
228230

229231
raise

0 commit comments

Comments
 (0)