From 1aa1f889df02aa2e5a34a6fd84b837d7c3ac85b4 Mon Sep 17 00:00:00 2001 From: martinRenou Date: Thu, 21 Sep 2023 16:25:20 +0200 Subject: [PATCH] Using logging instead of prints --- src/sagemaker/base_predictor.py | 5 +- src/sagemaker/cli/compatibility/v2/files.py | 5 +- src/sagemaker/fw_utils.py | 2 +- .../inference_recommender_mixin.py | 19 +-- src/sagemaker/local/entities.py | 21 ++-- src/sagemaker/local/image.py | 4 +- src/sagemaker/model.py | 11 +- .../model_monitor/clarify_model_monitoring.py | 37 +++--- .../model_monitor/model_monitoring.py | 100 ++++++++------- .../model_monitor/monitoring_files.py | 17 ++- src/sagemaker/session.py | 118 +++++++++--------- tests/integ/timeout.py | 27 ++-- 12 files changed, 189 insertions(+), 177 deletions(-) diff --git a/src/sagemaker/base_predictor.py b/src/sagemaker/base_predictor.py index 3baecd8014..99ef6ef55f 100644 --- a/src/sagemaker/base_predictor.py +++ b/src/sagemaker/base_predictor.py @@ -63,6 +63,9 @@ LOGGER = logging.getLogger("sagemaker") +logger = logging.getLogger(__name__) + + class PredictorBase(abc.ABC): """An object that encapsulates a deployed model.""" @@ -714,7 +717,7 @@ def list_monitors(self): endpoint_name=self.endpoint_name ) if len(monitoring_schedules_dict["MonitoringScheduleSummaries"]) == 0: - print("No monitors found for endpoint. endpoint: {}".format(self.endpoint_name)) + logger.debug("No monitors found for endpoint. endpoint: %s", self.endpoint_name) return [] monitors = [] diff --git a/src/sagemaker/cli/compatibility/v2/files.py b/src/sagemaker/cli/compatibility/v2/files.py index 0d118b1c73..c231b06ced 100644 --- a/src/sagemaker/cli/compatibility/v2/files.py +++ b/src/sagemaker/cli/compatibility/v2/files.py @@ -22,7 +22,8 @@ from sagemaker.cli.compatibility.v2.ast_transformer import ASTTransformer -LOGGER = logging.getLogger(__name__) +# Setting LOGGER for backward compatibility, in case users import this... +logger = LOGGER = logging.getLogger(__name__) class FileUpdater(object): @@ -59,7 +60,7 @@ def _make_output_dirs_if_needed(self): os.makedirs(output_dir) if os.path.exists(self.output_path): - LOGGER.warning("Overwriting file %s", self.output_path) + logger.warning("Overwriting file %s", self.output_path) class PyFileUpdater(FileUpdater): diff --git a/src/sagemaker/fw_utils.py b/src/sagemaker/fw_utils.py index 4c97032384..d33b71ad10 100644 --- a/src/sagemaker/fw_utils.py +++ b/src/sagemaker/fw_utils.py @@ -474,7 +474,7 @@ def tar_and_upload_dir( if s3_resource is None: s3_resource = session.resource("s3", region_name=session.region_name) else: - print("Using provided s3_resource") + logger.debug("Using provided s3_resource") s3_resource.Object(bucket, key).upload_file(tar_file, ExtraArgs=extra_args) finally: diff --git a/src/sagemaker/inference_recommender/inference_recommender_mixin.py b/src/sagemaker/inference_recommender/inference_recommender_mixin.py index ed3357a532..cd9a1abb58 100644 --- a/src/sagemaker/inference_recommender/inference_recommender_mixin.py +++ b/src/sagemaker/inference_recommender/inference_recommender_mixin.py @@ -28,7 +28,8 @@ "mxnet": "MXNET", } -LOGGER = logging.getLogger("sagemaker") +# Setting LOGGER for backward compatibility, in case users import it... +logger = LOGGER = logging.getLogger("sagemaker") class Phase: @@ -145,10 +146,10 @@ def right_size( ) if endpoint_configurations or traffic_pattern or stopping_conditions or resource_limit: - LOGGER.info("Advanced Job parameters were specified. Running Advanced job...") + logger.info("Advanced Job parameters were specified. Running Advanced job...") job_type = "Advanced" else: - LOGGER.info("Advanced Job parameters were not specified. Running Default job...") + logger.info("Advanced Job parameters were not specified. Running Default job...") job_type = "Default" self._init_sagemaker_session_if_does_not_exist() @@ -173,7 +174,7 @@ def right_size( vpc_config=self.vpc_config, enable_network_isolation=self.enable_network_isolation(), ) - LOGGER.warning("Attempting to create new model with name %s", self.name) + logger.warning("Attempting to create new model with name %s", self.name) self.sagemaker_session.create_model(**create_model_args) ret_name = self.sagemaker_session.create_inference_recommendations_job( @@ -281,23 +282,23 @@ def _update_params_for_right_size( if accelerator_type: raise ValueError("accelerator_type is not compatible with right_size().") if instance_type or initial_instance_count: - LOGGER.warning( + logger.warning( "instance_type or initial_instance_count specified." "Overriding right_size() recommendations." ) return None if async_inference_config: - LOGGER.warning( + logger.warning( "async_inference_config is specified. Overriding right_size() recommendations." ) return None if serverless_inference_config: - LOGGER.warning( + logger.warning( "serverless_inference_config is specified. Overriding right_size() recommendations." ) return None if explainer_config: - LOGGER.warning( + logger.warning( "explainer_config is specified. Overriding right_size() recommendations." ) return None @@ -359,7 +360,7 @@ def _update_params_for_recommendation_id( """ if instance_type is not None and initial_instance_count is not None: - LOGGER.warning( + logger.warning( "Both instance_type and initial_instance_count are specified," "overriding the recommendation result." ) diff --git a/src/sagemaker/local/entities.py b/src/sagemaker/local/entities.py index 89c9c7025d..3eb4ab2b34 100644 --- a/src/sagemaker/local/entities.py +++ b/src/sagemaker/local/entities.py @@ -683,8 +683,10 @@ def start(self, **kwargs): ) self._executions[execution_id] = execution - print( - f"Starting execution for pipeline {self.pipeline.name}. Execution ID is {execution_id}" + logger.info( + "Starting execution for pipeline %s. Execution ID is %s", + self.pipeline.name, + execution_id, ) self.last_modified_time = datetime.datetime.now().timestamp() @@ -771,31 +773,32 @@ def update_execution_success(self): """Mark execution as succeeded.""" self.status = _LocalExecutionStatus.SUCCEEDED.value self.last_modified_time = datetime.datetime.now().timestamp() - print(f"Pipeline execution {self.pipeline_execution_name} SUCCEEDED") + logger.info("Pipeline execution %s SUCCEEDED", self.pipeline_execution_name) def update_execution_failure(self, step_name, failure_message): """Mark execution as failed.""" self.status = _LocalExecutionStatus.FAILED.value self.failure_reason = f"Step '{step_name}' failed with message: {failure_message}" self.last_modified_time = datetime.datetime.now().timestamp() - print( - f"Pipeline execution {self.pipeline_execution_name} FAILED because step " - f"'{step_name}' failed." + logger.info( + "Pipeline execution %s FAILED because step '%s' failed.", + self.pipeline_execution_name, + step_name, ) def update_step_properties(self, step_name, step_properties): """Update pipeline step execution output properties.""" self.step_execution.get(step_name).update_step_properties(step_properties) - print(f"Pipeline step '{step_name}' SUCCEEDED.") + logger.info("Pipeline step '%s' SUCCEEDED.", step_name) def update_step_failure(self, step_name, failure_message): """Mark step_name as failed.""" - print(f"Pipeline step '{step_name}' FAILED. Failure message is: {failure_message}") + logger.info("Pipeline step '%s' FAILED. Failure message is: %s", step_name, failure_message) self.step_execution.get(step_name).update_step_failure(failure_message) def mark_step_executing(self, step_name): """Update pipelines step's status to EXECUTING and start_time to now.""" - print(f"Starting pipeline step: '{step_name}'") + logger.info("Starting pipeline step: '%s'", step_name) self.step_execution.get(step_name).mark_step_executing() def _initialize_step_execution(self, steps): diff --git a/src/sagemaker/local/image.py b/src/sagemaker/local/image.py index 98a5a7c629..22a15c0570 100644 --- a/src/sagemaker/local/image.py +++ b/src/sagemaker/local/image.py @@ -230,7 +230,7 @@ def process( # Print our Job Complete line to have a similar experience to training on SageMaker where # you see this line at the end. - print("===== Job Complete =====") + logger.info("===== Job Complete =====") def train(self, input_data_config, output_data_config, hyperparameters, environment, job_name): """Run a training job locally using docker-compose. @@ -310,7 +310,7 @@ def train(self, input_data_config, output_data_config, hyperparameters, environm # Print our Job Complete line to have a similar experience to training on SageMaker where # you see this line at the end. - print("===== Job Complete =====") + logger.info("===== Job Complete =====") return artifacts def serve(self, model_dir, environment): diff --git a/src/sagemaker/model.py b/src/sagemaker/model.py index 9caca5feff..56f68372ae 100644 --- a/src/sagemaker/model.py +++ b/src/sagemaker/model.py @@ -77,7 +77,8 @@ from sagemaker.enums import EndpointType from sagemaker.session import get_add_model_package_inference_args -LOGGER = logging.getLogger("sagemaker") +# Setting LOGGER for backward compatibility, in case users import it... +logger = LOGGER = logging.getLogger("sagemaker") NEO_ALLOWED_FRAMEWORKS = set( ["mxnet", "tensorflow", "keras", "pytorch", "onnx", "xgboost", "tflite"] @@ -737,7 +738,7 @@ def _upload_code(self, key_prefix: str, repack: bool = False) -> None: script_name=os.path.basename(self.entry_point), ) - LOGGER.info( + logger.info( "Repacking model artifact (%s), script artifact " "(%s), and dependencies (%s) " "into single tar.gz file located at %s. " @@ -1258,13 +1259,13 @@ def compile( self.image_uri = job_status.get("InferenceImage", None) self._is_compiled_model = True else: - LOGGER.warning( + logger.warning( "The instance type %s is not supported for deployment via SageMaker." "Please deploy the model manually.", target_instance_family, ) else: - LOGGER.warning( + logger.warning( "Devices described by Target Platform OS, Architecture and Accelerator are not" "supported for deployment via SageMaker. Please deploy the model manually." ) @@ -1484,7 +1485,7 @@ def deploy( and instance_type.startswith("ml.inf") and not self._is_compiled_model ): - LOGGER.warning( + logger.warning( "Your model is not compiled. Please compile your model before using Inferentia." ) diff --git a/src/sagemaker/model_monitor/clarify_model_monitoring.py b/src/sagemaker/model_monitor/clarify_model_monitoring.py index 8905731b08..bc572827cd 100644 --- a/src/sagemaker/model_monitor/clarify_model_monitoring.py +++ b/src/sagemaker/model_monitor/clarify_model_monitoring.py @@ -29,7 +29,8 @@ from sagemaker.clarify import SageMakerClarifyProcessor, ModelPredictedLabelConfig from sagemaker.lineage._utils import get_resource_name_from_arn -_LOGGER = logging.getLogger(__name__) +# Setting _LOGGER for backward compatibility, in case users import it... +logger = _LOGGER = logging.getLogger(__name__) class ClarifyModelMonitor(mm.ModelMonitor): @@ -223,7 +224,7 @@ def _upload_analysis_config(self, analysis_config, output_s3_uri, job_definition str(uuid.uuid4()), "analysis_config.json", ) - _LOGGER.info("Uploading analysis config to {s3_uri}.") + logger.info("Uploading analysis config to {s3_uri}.") return s3.S3Uploader.upload_string_as_file_body( json.dumps(analysis_config), desired_s3_uri=s3_uri, @@ -604,7 +605,7 @@ def create_monitoring_schedule( "Monitoring Schedule. To create another, first delete the existing one " "using my_monitor.delete_monitoring_schedule()." ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) if (batch_transform_input is not None) ^ (endpoint_input is None): @@ -613,7 +614,7 @@ def create_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) self._check_monitoring_schedule_cron_validity( @@ -667,7 +668,7 @@ def create_monitoring_schedule( self.job_definition_name = new_job_definition_name self.monitoring_schedule_name = monitor_schedule_name except Exception: - _LOGGER.exception("Failed to create monitoring schedule.") + logger.exception("Failed to create monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_model_bias_job_definition( @@ -675,7 +676,7 @@ def create_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise # noinspection PyMethodOverriding @@ -756,7 +757,7 @@ def update_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) # Only need to update schedule expression @@ -820,7 +821,7 @@ def update_monitoring_schedule( if network_config is not None: self.network_config = network_config except Exception: - _LOGGER.exception("Failed to update monitoring schedule.") + logger.exception("Failed to update monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_model_bias_job_definition( @@ -828,7 +829,7 @@ def update_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise def delete_monitoring_schedule(self): @@ -838,7 +839,7 @@ def delete_monitoring_schedule(self): message = "Deleting Model Bias Job Definition with name: {}".format( self.job_definition_name ) - _LOGGER.info(message) + logger.info(message) self.sagemaker_session.sagemaker_client.delete_model_bias_job_definition( JobDefinitionName=self.job_definition_name ) @@ -1045,7 +1046,7 @@ def create_monitoring_schedule( "Monitoring Schedule. To create another, first delete the existing one " "using my_monitor.delete_monitoring_schedule()." ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) if (batch_transform_input is not None) ^ (endpoint_input is None): @@ -1054,7 +1055,7 @@ def create_monitoring_schedule( "Amazon Model Monitoring Schedule." "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) self._check_monitoring_schedule_cron_validity( @@ -1107,7 +1108,7 @@ def create_monitoring_schedule( self.job_definition_name = new_job_definition_name self.monitoring_schedule_name = monitor_schedule_name except Exception: - _LOGGER.exception("Failed to create monitoring schedule.") + logger.exception("Failed to create monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_model_explainability_job_definition( @@ -1115,7 +1116,7 @@ def create_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise # noinspection PyMethodOverriding @@ -1198,7 +1199,7 @@ def update_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) # Only need to update schedule expression @@ -1265,7 +1266,7 @@ def update_monitoring_schedule( if network_config is not None: self.network_config = network_config except Exception: - _LOGGER.exception("Failed to update monitoring schedule.") + logger.exception("Failed to update monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_model_explainability_job_definition( @@ -1273,7 +1274,7 @@ def update_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise def delete_monitoring_schedule(self): @@ -1283,7 +1284,7 @@ def delete_monitoring_schedule(self): message = "Deleting Model Explainability Job Definition with name: {}".format( self.job_definition_name ) - _LOGGER.info(message) + logger.info(message) self.sagemaker_session.sagemaker_client.delete_model_explainability_job_definition( JobDefinitionName=self.job_definition_name ) diff --git a/src/sagemaker/model_monitor/model_monitoring.py b/src/sagemaker/model_monitor/model_monitoring.py index a28eaa184b..b949c6538b 100644 --- a/src/sagemaker/model_monitor/model_monitoring.py +++ b/src/sagemaker/model_monitor/model_monitoring.py @@ -103,7 +103,8 @@ _PROBABILITY_THRESHOLD_ATTRIBUTE_ENV_NAME = "probability_threshold_attribute" _CATEGORICAL_DRIFT_METHOD_ENV_NAME = "categorical_drift_method" -_LOGGER = logging.getLogger(__name__) +# Setting _LOGGER for backward compatibility, in case users import it... +logger = _LOGGER = logging.getLogger(__name__) framework_name = "model-monitor" @@ -348,7 +349,7 @@ def create_monitoring_schedule( "Monitoring Schedule. To create another, first delete the existing one " "using my_monitor.delete_monitoring_schedule()." ) - print(message) + logger.warning(message) raise ValueError(message) if not output: @@ -360,7 +361,7 @@ def create_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) self._check_monitoring_schedule_cron_validity( @@ -518,7 +519,7 @@ def update_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide atmost one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) if endpoint_input is not None: @@ -696,10 +697,9 @@ def latest_monitoring_statistics(self, file_name=STATISTICS_JSON_DEFAULT_FILE_NA """ executions = self.list_executions() if len(executions) == 0: - print( - "No executions found for schedule. monitoring_schedule_name: {}".format( - self.monitoring_schedule_name - ) + logger.warning( + "No executions found for schedule. monitoring_schedule_name: %s", + self.monitoring_schedule_name, ) return None @@ -724,10 +724,9 @@ def latest_monitoring_constraint_violations( """ executions = self.list_executions() if len(executions) == 0: - print( - "No executions found for schedule. monitoring_schedule_name: {}".format( - self.monitoring_schedule_name - ) + logger.warning( + "No executions found for schedule. monitoring_schedule_name: %s", + self.monitoring_schedule_name, ) return None @@ -770,10 +769,9 @@ def list_executions(self): ) if len(monitoring_executions_dict["MonitoringExecutionSummaries"]) == 0: - print( - "No executions found for schedule. monitoring_schedule_name: {}".format( - self.monitoring_schedule_name - ) + logger.warning( + "No executions found for schedule. monitoring_schedule_name: %s", + self.monitoring_schedule_name, ) return [] @@ -833,7 +831,7 @@ def update_monitoring_alert( if self.monitoring_schedule_name is None: message = "Nothing to update, please create a schedule first." - _LOGGER.error(message) + logger.error(message) raise ValueError(message) if not data_points_to_alert and not evaluation_period: @@ -862,7 +860,7 @@ def list_monitoring_alerts( """ if self.monitoring_schedule_name is None: message = "No alert to list, please create a schedule first." - _LOGGER.warning(message) + logger.warning(message) return [], None monitoring_alert_dict: Dict = self.sagemaker_session.list_monitoring_alerts( @@ -931,7 +929,7 @@ def list_monitoring_alert_history( """ if self.monitoring_schedule_name is None: message = "No alert history to list, please create a schedule first." - _LOGGER.warning(message) + logger.warning(message) return [], None monitoring_alert_history_dict: Dict = self.sagemaker_session.list_monitoring_alert_history( @@ -1554,7 +1552,7 @@ def _create_monitoring_schedule_from_job_definition( for the one time monitoring schedule (NOW), e.g. "-PT1H" (default: None) """ message = "Creating Monitoring Schedule with name: {}".format(monitor_schedule_name) - _LOGGER.info(message) + logger.info(message) self._check_monitoring_schedule_cron_validity( schedule_cron_expression=schedule_cron_expression, @@ -1653,7 +1651,7 @@ def _update_monitoring_schedule( """ if self.job_definition_name is None or self.monitoring_schedule_name is None: message = "Nothing to update, please create a schedule first." - _LOGGER.error(message) + logger.error(message) raise ValueError(message) self._check_monitoring_schedule_cron_validity( @@ -1991,7 +1989,7 @@ def create_monitoring_schedule( "Monitoring Schedule. To create another, first delete the existing one " "using my_monitor.delete_monitoring_schedule()." ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) if (batch_transform_input is not None) ^ (endpoint_input is None): @@ -2000,7 +1998,7 @@ def create_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) self._check_monitoring_schedule_cron_validity( @@ -2054,7 +2052,7 @@ def create_monitoring_schedule( self.job_definition_name = new_job_definition_name self.monitoring_schedule_name = monitor_schedule_name except Exception: - _LOGGER.exception("Failed to create monitoring schedule.") + logger.exception("Failed to create monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_data_quality_job_definition( @@ -2062,7 +2060,7 @@ def create_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise def update_monitoring_schedule( @@ -2143,7 +2141,7 @@ def update_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide atmost one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) # check if this schedule is in v2 format and update as per v2 format if it is @@ -2430,7 +2428,7 @@ def _update_data_quality_monitoring_schedule( if network_config is not None: self.network_config = network_config except Exception: - _LOGGER.exception("Failed to update monitoring schedule.") + logger.exception("Failed to update monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_data_quality_job_definition( @@ -2438,7 +2436,7 @@ def _update_data_quality_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise def delete_monitoring_schedule(self): @@ -2449,7 +2447,7 @@ def delete_monitoring_schedule(self): message = "Deleting Data Quality Job Definition with name: {}".format( self.job_definition_name ) - _LOGGER.info(message) + logger.info(message) self.sagemaker_session.sagemaker_client.delete_data_quality_job_definition( JobDefinitionName=self.job_definition_name ) @@ -2570,10 +2568,9 @@ def latest_monitoring_statistics(self): """ executions = self.list_executions() if len(executions) == 0: - print( - "No executions found for schedule. monitoring_schedule_name: {}".format( - self.monitoring_schedule_name - ) + logger.warning( + "No executions found for schedule. monitoring_schedule_name: %s", + self.monitoring_schedule_name, ) return None @@ -2583,9 +2580,10 @@ def latest_monitoring_statistics(self): return latest_monitoring_execution.statistics() except ClientError: status = latest_monitoring_execution.describe()["ProcessingJobStatus"] - print( - "Unable to retrieve statistics as job is in status '{}'. Latest statistics only " - "available for completed executions.".format(status) + logger.warning( + "Unable to retrieve statistics as job is in status '%s'. Latest statistics only " + "available for completed executions.", + status, ) def latest_monitoring_constraint_violations(self): @@ -2600,10 +2598,9 @@ def latest_monitoring_constraint_violations(self): """ executions = self.list_executions() if len(executions) == 0: - print( - "No executions found for schedule. monitoring_schedule_name: {}".format( - self.monitoring_schedule_name - ) + logger.warning( + "No executions found for schedule. monitoring_schedule_name: %s", + self.monitoring_schedule_name, ) return None @@ -2612,9 +2609,10 @@ def latest_monitoring_constraint_violations(self): return latest_monitoring_execution.constraint_violations() except ClientError: status = latest_monitoring_execution.describe()["ProcessingJobStatus"] - print( - "Unable to retrieve constraint violations as job is in status '{}'. Latest " - "violations only available for completed executions.".format(status) + logger.warning( + "Unable to retrieve constraint violations as job is in status '%s'. Latest " + "violations only available for completed executions.", + status, ) @staticmethod @@ -3109,7 +3107,7 @@ def create_monitoring_schedule( "Monitoring Schedule. To create another, first delete the existing one " "using my_monitor.delete_monitoring_schedule()." ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) if (batch_transform_input is not None) ^ (endpoint_input is None): @@ -3118,7 +3116,7 @@ def create_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide only one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) self._check_monitoring_schedule_cron_validity( @@ -3173,7 +3171,7 @@ def create_monitoring_schedule( self.job_definition_name = new_job_definition_name self.monitoring_schedule_name = monitor_schedule_name except Exception: - _LOGGER.exception("Failed to create monitoring schedule.") + logger.exception("Failed to create monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_model_quality_job_definition( @@ -3181,7 +3179,7 @@ def create_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise def update_monitoring_schedule( @@ -3279,7 +3277,7 @@ def update_monitoring_schedule( "Amazon Model Monitoring Schedule. " "Please provide atmost one of the above required inputs" ) - _LOGGER.error(message) + logger.error(message) raise ValueError(message) # Need to update schedule with a new job definition @@ -3340,7 +3338,7 @@ def update_monitoring_schedule( if network_config is not None: self.network_config = network_config except Exception: - _LOGGER.exception("Failed to update monitoring schedule.") + logger.exception("Failed to update monitoring schedule.") # noinspection PyBroadException try: self.sagemaker_session.sagemaker_client.delete_model_quality_job_definition( @@ -3348,7 +3346,7 @@ def update_monitoring_schedule( ) except Exception: # pylint: disable=W0703 message = "Failed to delete job definition {}.".format(new_job_definition_name) - _LOGGER.exception(message) + logger.exception(message) raise def delete_monitoring_schedule(self): @@ -3358,7 +3356,7 @@ def delete_monitoring_schedule(self): message = "Deleting Model Quality Job Definition with name: {}".format( self.job_definition_name ) - _LOGGER.info(message) + logger.info(message) self.sagemaker_session.sagemaker_client.delete_model_quality_job_definition( JobDefinitionName=self.job_definition_name ) diff --git a/src/sagemaker/model_monitor/monitoring_files.py b/src/sagemaker/model_monitor/monitoring_files.py index 90ec627087..6768a5270f 100644 --- a/src/sagemaker/model_monitor/monitoring_files.py +++ b/src/sagemaker/model_monitor/monitoring_files.py @@ -18,6 +18,7 @@ from __future__ import print_function, absolute_import import json +import logging import os import uuid @@ -28,6 +29,8 @@ NO_SUCH_KEY_CODE = "NoSuchKey" +logger = logging.getLogger(__name__) + class ModelMonitoringFile(object): """Represents a file with a body and an S3 uri.""" @@ -123,11 +126,12 @@ def from_s3_uri(cls, statistics_file_s3_uri, kms_key=None, sagemaker_session=Non ) ) except ClientError as error: - print( - "\nCould not retrieve statistics file at location '{}'. " + logger.warning( + "\nCould not retrieve statistics file at location '%s'. " "To manually retrieve Statistics object from a given uri, " "use 'my_model_monitor.statistics(my_s3_uri)' or " - "'Statistics.from_s3_uri(my_s3_uri)'".format(statistics_file_s3_uri) + "'Statistics.from_s3_uri(my_s3_uri)'", + statistics_file_s3_uri, ) raise error @@ -253,11 +257,12 @@ def from_s3_uri(cls, constraints_file_s3_uri, kms_key=None, sagemaker_session=No ) ) except ClientError as error: - print( - "\nCould not retrieve constraints file at location '{}'. " + logger.warning( + "\nCould not retrieve constraints file at location '%s'. " "To manually retrieve Constraints object from a given uri, " "use 'my_model_monitor.constraints(my_s3_uri)' or " - "'Constraints.from_s3_uri(my_s3_uri)'".format(constraints_file_s3_uri) + "'Constraints.from_s3_uri(my_s3_uri)'", + constraints_file_s3_uri, ) raise error diff --git a/src/sagemaker/session.py b/src/sagemaker/session.py index 5b5df7a792..28097a72bf 100644 --- a/src/sagemaker/session.py +++ b/src/sagemaker/session.py @@ -135,7 +135,8 @@ from sagemaker import exceptions from sagemaker.session_settings import SessionSettings -LOGGER = logging.getLogger("sagemaker") +# Setting LOGGER for backward compatibility, in case users import it... +logger = LOGGER = logging.getLogger("sagemaker") NOTEBOOK_METADATA_FILE = "/opt/ml/metadata/resource-metadata.json" MODEL_MONITOR_ONE_TIME_SCHEDULE = "NOW" @@ -485,7 +486,7 @@ def download_data(self, path, bucket, key_prefix="", extra_args=None): response = s3.list_objects_v2(**request_parameters) contents = response.get("Contents", None) if not contents: - LOGGER.info( + logger.info( "Nothing to download from bucket: %s, key_prefix: %s.", bucket, key_prefix ) return [] @@ -630,7 +631,7 @@ def _create_s3_bucket_if_it_does_not_exist(self, bucket_name, region): CreateBucketConfiguration={"LocationConstraint": region}, ) - LOGGER.info("Created S3 bucket: %s", bucket_name) + logger.info("Created S3 bucket: %s", bucket_name) except ClientError as e: error_code = e.response["Error"]["Code"] message = e.response["Error"]["Message"] @@ -645,7 +646,7 @@ def _create_s3_bucket_if_it_does_not_exist(self, bucket_name, region): else: raise elif error_code == "403" and message == "Forbidden": - LOGGER.error( + logger.error( "Bucket %s exists, but access is forbidden. Please try again after " "adding appropriate access.", bucket.name, @@ -966,8 +967,8 @@ def train( # noqa: C901 ) def submit(request): - LOGGER.info("Creating training-job with name: %s", job_name) - LOGGER.debug("train request: %s", json.dumps(request, indent=4)) + logger.info("Creating training-job with name: %s", job_name) + logger.debug("train request: %s", json.dumps(request, indent=4)) self.sagemaker_client.create_training_job(**request) self._intercept_create_request(train_request, submit, self.train.__name__) @@ -1276,8 +1277,8 @@ def update_training_job( resource_config=resource_config, remote_debug_config=remote_debug_config, ) - LOGGER.info("Updating training job with name %s", job_name) - LOGGER.debug("Update request: %s", json.dumps(update_training_job_request, indent=4)) + logger.info("Updating training job with name %s", job_name) + logger.debug("Update request: %s", json.dumps(update_training_job_request, indent=4)) self.sagemaker_client.update_training_job(**update_training_job_request) def _get_update_training_job_request( @@ -1444,8 +1445,8 @@ def process( ) def submit(request): - LOGGER.info("Creating processing-job with name %s", job_name) - LOGGER.debug("process request: %s", json.dumps(request, indent=4)) + logger.info("Creating processing-job with name %s", job_name) + logger.debug("process request: %s", json.dumps(request, indent=4)) self.sagemaker_client.create_processing_job(**request) self._intercept_create_request(process_request, submit, self.process.__name__) @@ -1723,8 +1724,8 @@ def create_monitoring_schedule( if tags is not None: monitoring_schedule_request["Tags"] = tags - LOGGER.info("Creating monitoring schedule name %s.", monitoring_schedule_name) - LOGGER.debug( + logger.info("Creating monitoring schedule name %s.", monitoring_schedule_name) + logger.debug( "monitoring_schedule_request= %s", json.dumps(monitoring_schedule_request, indent=4) ) self.sagemaker_client.create_monitoring_schedule(**monitoring_schedule_request) @@ -2059,8 +2060,8 @@ def update_monitoring_schedule( "NetworkConfig" ] = _network_config - LOGGER.info("Updating monitoring schedule with name: %s .", monitoring_schedule_name) - LOGGER.debug( + logger.info("Updating monitoring schedule with name: %s .", monitoring_schedule_name) + logger.debug( "monitoring_schedule_request= %s", json.dumps(monitoring_schedule_request, indent=4) ) self.sagemaker_client.update_monitoring_schedule(**monitoring_schedule_request) @@ -2072,8 +2073,7 @@ def start_monitoring_schedule(self, monitoring_schedule_name): monitoring_schedule_name (str): The name of the Amazon SageMaker Monitoring Schedule to start. """ - print() - print("Starting Monitoring Schedule with name: {}".format(monitoring_schedule_name)) + logger.info("Starting Monitoring Schedule with name: %s", monitoring_schedule_name) self.sagemaker_client.start_monitoring_schedule( MonitoringScheduleName=monitoring_schedule_name ) @@ -2085,8 +2085,7 @@ def stop_monitoring_schedule(self, monitoring_schedule_name): monitoring_schedule_name (str): The name of the Amazon SageMaker Monitoring Schedule to stop. """ - print() - print("Stopping Monitoring Schedule with name: {}".format(monitoring_schedule_name)) + logger.info("Stopping Monitoring Schedule with name: %s", monitoring_schedule_name) self.sagemaker_client.stop_monitoring_schedule( MonitoringScheduleName=monitoring_schedule_name ) @@ -2098,8 +2097,7 @@ def delete_monitoring_schedule(self, monitoring_schedule_name): monitoring_schedule_name (str): The name of the Amazon SageMaker Monitoring Schedule to delete. """ - print() - print("Deleting Monitoring Schedule with name: {}".format(monitoring_schedule_name)) + logger.info("Deleting Monitoring Schedule with name: %s", monitoring_schedule_name) self.sagemaker_client.delete_monitoring_schedule( MonitoringScheduleName=monitoring_schedule_name ) @@ -2397,8 +2395,8 @@ def auto_ml( ) def submit(request): - LOGGER.info("Creating auto-ml-job with name: %s", job_name) - LOGGER.debug("auto ml request: %s", json.dumps(request), indent=4) + logger.info("Creating auto-ml-job with name: %s", job_name) + logger.debug("auto ml request: %s", json.dumps(request), indent=4) self.sagemaker_client.create_auto_ml_job(**request) self._intercept_create_request(auto_ml_job_request, submit, self.auto_ml.__name__) @@ -2684,7 +2682,7 @@ def compile_model( if tags is not None: compilation_job_request["Tags"] = tags - LOGGER.info("Creating compilation-job with name: %s", job_name) + logger.info("Creating compilation-job with name: %s", job_name) self.sagemaker_client.create_compilation_job(**compilation_job_request) def package_model_for_edge( @@ -2736,7 +2734,7 @@ def package_model_for_edge( if resource_key is not None: edge_packaging_job_request["ResourceKey"] = resource_key - LOGGER.info("Creating edge-packaging-job with name: %s", job_name) + logger.info("Creating edge-packaging-job with name: %s", job_name) self.sagemaker_client.create_edge_packaging_job(**edge_packaging_job_request) def tune( # noqa: C901 @@ -2935,8 +2933,8 @@ def tune( # noqa: C901 if tags is not None: tune_request["Tags"] = tags - LOGGER.info("Creating hyperparameter tuning job with name: %s", job_name) - LOGGER.debug("tune request: %s", json.dumps(tune_request, indent=4)) + logger.info("Creating hyperparameter tuning job with name: %s", job_name) + logger.debug("tune request: %s", json.dumps(tune_request, indent=4)) self.sagemaker_client.create_hyper_parameter_tuning_job(**tune_request) def create_tuning_job( @@ -2989,8 +2987,8 @@ def create_tuning_job( ) def submit(request): - LOGGER.info("Creating hyperparameter tuning job with name: %s", job_name) - LOGGER.debug("tune request: %s", json.dumps(request, indent=4)) + logger.info("Creating hyperparameter tuning job with name: %s", job_name) + logger.debug("tune request: %s", json.dumps(request, indent=4)) self.sagemaker_client.create_hyper_parameter_tuning_job(**request) self._intercept_create_request(tune_request, submit, self.create_tuning_job.__name__) @@ -3346,15 +3344,15 @@ def stop_tuning_job(self, name): ClientError: If an error occurs while trying to stop the hyperparameter tuning job. """ try: - LOGGER.info("Stopping tuning job: %s", name) + logger.info("Stopping tuning job: %s", name) self.sagemaker_client.stop_hyper_parameter_tuning_job(HyperParameterTuningJobName=name) except ClientError as e: error_code = e.response["Error"]["Code"] # allow to pass if the job already stopped if error_code == "ValidationException": - LOGGER.info("Tuning job: %s is already stopped or not running.", name) + logger.info("Tuning job: %s is already stopped or not running.", name) else: - LOGGER.error( + logger.error( "Error occurred while attempting to stop tuning job: %s. Please try again.", name, ) @@ -3554,8 +3552,8 @@ def transform( ) def submit(request): - LOGGER.info("Creating transform job with name: %s", job_name) - LOGGER.debug("Transform request: %s", json.dumps(request, indent=4)) + logger.info("Creating transform job with name: %s", job_name) + logger.debug("Transform request: %s", json.dumps(request, indent=4)) self.sagemaker_client.create_transform_job(**request) self._intercept_create_request(transform_request, submit, self.transform.__name__) @@ -3697,8 +3695,8 @@ def create_model( ) def submit(request): - LOGGER.info("Creating model with name: %s", name) - LOGGER.debug("CreateModel request: %s", json.dumps(request, indent=4)) + logger.info("Creating model with name: %s", name) + logger.debug("CreateModel request: %s", json.dumps(request, indent=4)) try: self.sagemaker_client.create_model(**request) except ClientError as e: @@ -3708,7 +3706,7 @@ def submit(request): error_code == "ValidationException" and "Cannot create already existing model" in message ): - LOGGER.warning("Using already existing model: %s", name) + logger.warning("Using already existing model: %s", name) else: raise @@ -3808,14 +3806,14 @@ def create_model_package_from_algorithm(self, name, description, algorithm_arn, }, } try: - LOGGER.info("Creating model package with name: %s", name) + logger.info("Creating model package with name: %s", name) self.sagemaker_client.create_model_package(**request) except ClientError as e: error_code = e.response["Error"]["Code"] message = e.response["Error"]["Message"] if error_code == "ValidationException" and "ModelPackage already exists" in message: - LOGGER.warning("Using already existing model package: %s", name) + logger.warning("Using already existing model package: %s", name) else: raise @@ -4059,7 +4057,7 @@ def create_endpoint_config( Returns: str: Name of the endpoint point configuration created. """ - LOGGER.info("Creating endpoint-config with name %s", name) + logger.info("Creating endpoint-config with name %s", name) tags = tags or [] provided_production_variant = production_variant( @@ -4161,7 +4159,7 @@ def create_endpoint_config_from_existing( Returns: str: Name of the endpoint point configuration created. """ - LOGGER.info("Creating endpoint-config with name %s", new_config_name) + logger.info("Creating endpoint-config with name %s", new_config_name) existing_endpoint_config_desc = self.sagemaker_client.describe_endpoint_config( EndpointConfigName=existing_config_name @@ -4275,7 +4273,7 @@ def create_endpoint(self, endpoint_name, config_name, tags=None, wait=True, live Returns: str: Name of the Amazon SageMaker ``Endpoint`` created. """ - LOGGER.info("Creating endpoint with name %s", endpoint_name) + logger.info("Creating endpoint with name %s", endpoint_name) tags = tags or [] tags = _append_project_tags(tags) @@ -4366,7 +4364,7 @@ def delete_endpoint(self, endpoint_name): Args: endpoint_name (str): Name of the Amazon SageMaker ``Endpoint`` to delete. """ - LOGGER.info("Deleting endpoint with name: %s", endpoint_name) + logger.info("Deleting endpoint with name: %s", endpoint_name) self.sagemaker_client.delete_endpoint(EndpointName=endpoint_name) def delete_endpoint_config(self, endpoint_config_name): @@ -4376,7 +4374,7 @@ def delete_endpoint_config(self, endpoint_config_name): endpoint_config_name (str): Name of the Amazon SageMaker endpoint configuration to delete. """ - LOGGER.info("Deleting endpoint configuration with name: %s", endpoint_config_name) + logger.info("Deleting endpoint configuration with name: %s", endpoint_config_name) self.sagemaker_client.delete_endpoint_config(EndpointConfigName=endpoint_config_name) def create_inference_component( @@ -4710,7 +4708,7 @@ def delete_model(self, model_name): Args: model_name (str): Name of the Amazon SageMaker model to delete. """ - LOGGER.info("Deleting model with name: %s", model_name) + logger.info("Deleting model with name: %s", model_name) self.sagemaker_client.delete_model(ModelName=model_name) def list_group_resources(self, group, filters, next_token: str = ""): @@ -4829,7 +4827,7 @@ def list_tags(self, resource_arn, max_results=50): non_aws_tags.append(tag) return non_aws_tags except ClientError as error: - print("Error retrieving tags. resource_arn: {}".format(resource_arn)) + logger.error("Error retrieving tags. resource_arn: %s", resource_arn) raise error def wait_for_job(self, job, poll=5): @@ -4963,15 +4961,15 @@ def stop_transform_job(self, name): ClientError: If an error occurs while trying to stop the batch transform job. """ try: - LOGGER.info("Stopping transform job: %s", name) + logger.info("Stopping transform job: %s", name) self.sagemaker_client.stop_transform_job(TransformJobName=name) except ClientError as e: error_code = e.response["Error"]["Code"] # allow to pass if the job already stopped if error_code == "ValidationException": - LOGGER.info("Transform job: %s is already stopped or not running.", name) + logger.info("Transform job: %s is already stopped or not running.", name) else: - LOGGER.error("Error occurred while attempting to stop transform job: %s.", name) + logger.error("Error occurred while attempting to stop transform job: %s.", name) raise def wait_for_endpoint(self, endpoint, poll=DEFAULT_EP_POLL, live_logging=False): @@ -5373,7 +5371,7 @@ def endpoint_from_production_variants( if role is not None: config_options["ExecutionRoleArn"] = role - LOGGER.info("Creating endpoint-config with name %s", name) + logger.info("Creating endpoint-config with name %s", name) self.sagemaker_client.create_endpoint_config(**config_options) return self.create_endpoint( @@ -5437,7 +5435,7 @@ def get_caller_identity_arn(self): domain_desc = self.sagemaker_client.describe_domain(DomainId=domain_id) return domain_desc["DefaultUserSettings"]["ExecutionRole"] except ClientError: - LOGGER.debug( + logger.debug( "Couldn't call 'describe_notebook_instance' to get the Role " "ARN of the instance %s.", instance_name, @@ -5456,7 +5454,7 @@ def get_caller_identity_arn(self): try: role = self.boto_session.client("iam").get_role(RoleName=role_name)["Role"]["Arn"] except ClientError: - LOGGER.warning( + logger.warning( "Couldn't call 'get_role' to get Role ARN from role name %s to get Role path.", role_name, ) @@ -5465,7 +5463,7 @@ def get_caller_identity_arn(self): # Guessing this conditional's purpose was to handle lack of IAM permissions # https://github.com/aws/sagemaker-python-sdk/issues/2089#issuecomment-791802713 if "AmazonSageMaker-ExecutionRole" in assumed_role: - LOGGER.warning( + logger.warning( "Assuming role was created in SageMaker AWS console, " "as the name contains `AmazonSageMaker-ExecutionRole`. " "Defaulting to Role ARN with service-role in path. " @@ -6084,7 +6082,7 @@ def wait_for_athena_query(self, query_execution_id: str, poll: int = 5): .get("State") ) while query_state not in ("SUCCEEDED", "FAILED"): - LOGGER.info("Query %s is being executed.", query_execution_id) + logger.info("Query %s is being executed.", query_execution_id) time.sleep(poll) query_state = ( self.get_query_execution(query_execution_id=query_execution_id) @@ -6093,9 +6091,9 @@ def wait_for_athena_query(self, query_execution_id: str, poll: int = 5): .get("State") ) if query_state == "SUCCEEDED": - LOGGER.info("Query %s successfully executed.", query_execution_id) + logger.info("Query %s successfully executed.", query_execution_id) else: - LOGGER.error("Failed to execute query %s.", query_execution_id) + logger.error("Failed to execute query %s.", query_execution_id) def download_athena_query_result( self, @@ -6351,8 +6349,8 @@ def create_inference_recommendations_job( ) def submit(request): - LOGGER.info("Creating Inference Recommendations job with name: %s", job_name) - LOGGER.debug("process request: %s", json.dumps(request, indent=4)) + logger.info("Creating Inference Recommendations job with name: %s", job_name) + logger.debug("process request: %s", json.dumps(request, indent=4)) self.sagemaker_client.create_inference_recommendations_job(**request) self._intercept_create_request( @@ -7386,7 +7384,7 @@ def _wait_until_training_done(callable_fn, desc, poll=5): # access policy based on resource tags, The caveat here is for true AccessDenied # cases the routine will fail after 5 mins if err.response["Error"]["Code"] == "AccessDeniedException" and elapsed_time <= 300: - LOGGER.warning( + logger.warning( "Received AccessDeniedException. This could mean the IAM role does not " "have the resource permissions, in which case please add resource access " "and retry. For cases where the role has tag based resource policy, " @@ -7412,7 +7410,7 @@ def _wait_until(callable_fn, poll=5): # access policy based on resource tags, The caveat here is for true AccessDenied # cases the routine will fail after 5 mins if err.response["Error"]["Code"] == "AccessDeniedException" and elapsed_time <= 300: - LOGGER.warning( + logger.warning( "Received AccessDeniedException. This could mean the IAM role does not " "have the resource permissions, in which case please add resource access " "and retry. For cases where the role has tag based resource policy, " @@ -7627,7 +7625,7 @@ def _check_job_status(job, desc, status_key_name): status = _STATUS_CODE_TABLE.get(status, status) if status == "Stopped": - LOGGER.warning( + logger.warning( "Job ended with status 'Stopped' rather than 'Completed'. " "This could mean the job timed out or stopped early for some other reason: " "Consider checking whether it completed as you expect." diff --git a/tests/integ/timeout.py b/tests/integ/timeout.py index b86249eaf8..49f447e5a3 100644 --- a/tests/integ/timeout.py +++ b/tests/integ/timeout.py @@ -23,7 +23,8 @@ from sagemaker import Predictor from tests.integ.retry import retries -LOGGER = logging.getLogger("timeout") +# Setting LOGGER for backward compatibility, in case users import it... +logger = LOGGER = logging.getLogger("timeout") @contextmanager @@ -73,7 +74,7 @@ def timeout_and_delete_endpoint_by_name( sagemaker_session=sagemaker_session, endpoint_name=endpoint_name ) sagemaker_session.delete_endpoint(endpoint_name) - LOGGER.info("deleted endpoint {}".format(endpoint_name)) + logger.info("deleted endpoint %s", endpoint_name) _show_logs(endpoint_name, "Endpoints", sagemaker_session) if no_errors: @@ -111,7 +112,7 @@ def timeout_and_delete_model_with_transformer( attempts -= 1 try: transformer.delete_model() - LOGGER.info("deleted SageMaker model {}".format(transformer.model_name)) + logger.info("deleted SageMaker model %s", transformer.model_name) _show_logs(transformer.model_name, "Models", sagemaker_session) if no_errors: @@ -147,7 +148,7 @@ def timeout_and_delete_model_by_name( attempts -= 1 try: sagemaker_session.delete_model(model_name) - LOGGER.info("deleted model {}".format(model_name)) + logger.info("deleted model %s", model_name) _show_logs(model_name, "Models", sagemaker_session) if no_errors: @@ -200,10 +201,10 @@ def _delete_schedules_associated_with_endpoint(sagemaker_session, endpoint_name) # Delete schedules. monitor.delete_monitoring_schedule() except Exception as e: - LOGGER.warning( - "Failed to delete monitor {},\nError: {}".format( - monitor.monitoring_schedule_name, e - ) + logger.warning( + "Failed to delete monitor %s,\nError: %s", + monitor.monitoring_schedule_name, + e, ) @@ -211,7 +212,7 @@ def _show_logs(resource_name, resource_type, sagemaker_session): log_group = "/aws/sagemaker/{}/{}".format(resource_type, resource_name) try: # print out logs before deletion for debuggability - LOGGER.info("cloudwatch logs for log group {}:".format(log_group)) + logger.info("cloudwatch logs for log group %s:", log_group) logs = AWSLogs( log_group_name=log_group, log_stream_name="ALL", @@ -220,7 +221,7 @@ def _show_logs(resource_name, resource_type, sagemaker_session): ) logs.list_logs() except Exception: - LOGGER.exception( + logger.exception( "Failure occurred while listing cloudwatch log group %s. Swallowing exception but printing " "stacktrace for debugging.", log_group, @@ -231,12 +232,12 @@ def _cleanup_logs(resource_name, resource_type, sagemaker_session): log_group = "/aws/sagemaker/{}/{}".format(resource_type, resource_name) try: # print out logs before deletion for debuggability - LOGGER.info("deleting cloudwatch log group {}:".format(log_group)) + logger.info("deleting cloudwatch log group %s:", log_group) cwl_client = sagemaker_session.boto_session.client("logs") cwl_client.delete_log_group(logGroupName=log_group) - LOGGER.info("deleted cloudwatch log group: {}".format(log_group)) + logger.info("deleted cloudwatch log group: %s", log_group) except Exception: - LOGGER.exception( + logger.exception( "Failure occurred while cleaning up cloudwatch log group %s. " "Swallowing exception but printing stacktrace for debugging.", log_group,