diff --git a/backend/app/plan/utils.py b/backend/app/plan/utils.py index e752f5e0..a27bdf90 100644 --- a/backend/app/plan/utils.py +++ b/backend/app/plan/utils.py @@ -1,5 +1,4 @@ import ast -import os from typing import Optional import msgpack from uuid import UUID @@ -8,6 +7,7 @@ from backend.addresses.Address import Address from backend.app.config import get_settings from backend.app.plan.data_classes import PropertyRequestData from backend.app.db.functions.tasks.Tasks import SubTaskInterface +from backend.utils.cloudwatch import build_cloudwatch_log_url from starlette.responses import Response from utils.logger import setup_logger @@ -241,33 +241,6 @@ def parse_eco_packages( return measures, mapped["target_sap"], mapped["plan_type"], already_installed -def build_cloudwatch_log_url(start_ms: Optional[int]) -> str: - """ - Build a CloudWatch Logs URL for the current Lambda invocation, - including timestamp window from start_ms to end_ms (epoch ms). - """ - logger.info("Building cloudwatch logs URL") - region = os.environ["AWS_REGION"] - logger.info("Building cloudwatch logs URL: Got AWS region") - log_group = os.environ["AWS_LAMBDA_LOG_GROUP_NAME"] - logger.info("Building cloudwatch logs URL: Got lambda log group name") - log_stream = os.environ["AWS_LAMBDA_LOG_STREAM_NAME"] - logger.info("Building cloudwatch logs URL: Got lambda log stream name") - - # CloudWatch console requires / encoded as $252F - encoded_group = log_group.replace("/", "$252F") - encoded_stream = log_stream.replace("/", "$252F") - - # Return the full URL with time range - return ( - f"https://console.aws.amazon.com/cloudwatch/home?" - f"region={region}" - f"#logsV2:log-groups/log-group/{encoded_group}" - f"/log-events/{encoded_stream}" - f"$3Fstart={start_ms}" - ) - - def handle_error( msg: str, exception: Exception, diff --git a/backend/categorisation/handler/handler.py b/backend/categorisation/handler/handler.py index a1f69ea6..04dc0c44 100644 --- a/backend/categorisation/handler/handler.py +++ b/backend/categorisation/handler/handler.py @@ -3,7 +3,7 @@ import time from typing import Any, Mapping from backend.app.db.functions.tasks.Tasks import SubTaskInterface -from backend.app.plan.utils import build_cloudwatch_log_url +from backend.utils.cloudwatch import build_cloudwatch_log_url from backend.categorisation.categorisation_trigger_request import ( CategorisationTriggerRequest, ) diff --git a/backend/categorisation/processor.py b/backend/categorisation/processor.py index 88bc121e..e589c016 100644 --- a/backend/categorisation/processor.py +++ b/backend/categorisation/processor.py @@ -15,7 +15,8 @@ from backend.app.db.functions.tasks.Tasks import SubTaskInterface from backend.app.db.models.recommendations import PlanModel, ScenarioModel from backend.app.domain.classes.plan import Plan from backend.app.domain.classes.scenario import Scenario -from backend.app.plan.utils import build_cloudwatch_log_url, handle_error +from backend.app.plan.utils import handle_error +from backend.utils.cloudwatch import build_cloudwatch_log_url from backend.categorisation.categorisation_trigger_request import ( CategorisationTriggerRequest, ) diff --git a/backend/engine/engine.py b/backend/engine/engine.py index 8b4ee821..c9e3972f 100644 --- a/backend/engine/engine.py +++ b/backend/engine/engine.py @@ -23,8 +23,9 @@ from backend.app.db.functions.tasks.Tasks import SubTaskInterface from backend.app.plan.schemas import PlanTriggerRequest from backend.app.plan.utils import ( - get_cleaned, patch_epc, extract_property_request_data, handle_error, build_cloudwatch_log_url + get_cleaned, patch_epc, extract_property_request_data, handle_error ) +from backend.utils.cloudwatch import build_cloudwatch_log_url from backend.app.utils import sap_to_epc import backend.app.assumptions as assumptions diff --git a/backend/utils/cloudwatch.py b/backend/utils/cloudwatch.py new file mode 100644 index 00000000..e5309da2 --- /dev/null +++ b/backend/utils/cloudwatch.py @@ -0,0 +1,30 @@ +import os +from typing import Optional + +from utils.logger import setup_logger + +logger = setup_logger() + + +def build_cloudwatch_log_url(start_ms: Optional[int]) -> str: + """ + Build a CloudWatch Logs URL for the current Lambda invocation, including a + timestamp window starting at start_ms. Requires AWS_REGION, + AWS_LAMBDA_LOG_GROUP_NAME, and AWS_LAMBDA_LOG_STREAM_NAME to be set in the + environment — i.e. only safe to call inside a Lambda runtime. + """ + logger.info("Building cloudwatch logs URL") + region = os.environ["AWS_REGION"] + log_group = os.environ["AWS_LAMBDA_LOG_GROUP_NAME"] + log_stream = os.environ["AWS_LAMBDA_LOG_STREAM_NAME"] + + encoded_group = log_group.replace("/", "$252F") + encoded_stream = log_stream.replace("/", "$252F") + + return ( + f"https://console.aws.amazon.com/cloudwatch/home?" + f"region={region}" + f"#logsV2:log-groups/log-group/{encoded_group}" + f"/log-events/{encoded_stream}" + f"$3Fstart={start_ms}" + ) diff --git a/backend/utils/subtasks.py b/backend/utils/subtasks.py index 36e67b78..21ca24b1 100644 --- a/backend/utils/subtasks.py +++ b/backend/utils/subtasks.py @@ -7,7 +7,7 @@ from uuid import UUID from backend.app.db.functions.tasks.Tasks import SubTaskInterface, TasksInterface from backend.app.db.models.tasks import SourceEnum -from backend.app.plan.utils import build_cloudwatch_log_url +from backend.utils.cloudwatch import build_cloudwatch_log_url from utils.logger import setup_logger