diff --git a/src/deadline/client/api/_submit_job_bundle.py b/src/deadline/client/api/_submit_job_bundle.py index e888dcbb0..1b4d9a09b 100644 --- a/src/deadline/client/api/_submit_job_bundle.py +++ b/src/deadline/client/api/_submit_job_bundle.py @@ -276,6 +276,11 @@ def create_job_from_job_bundle( if logging.DEBUG >= logger.getEffectiveLevel(): logger.debug(json.dumps(create_job_args, indent=1)) + api.get_deadline_cloud_library_telemetry_client().record_event( + event_type="com.amazon.rum.deadline.submission", + event_details={}, + ) + create_job_response = deadline.create_job(**create_job_args) logger.debug(f"CreateJob Response {create_job_response}") @@ -302,6 +307,10 @@ def _default_create_job_result_callback() -> bool: create_job_result_callback, ) + api.get_deadline_cloud_library_telemetry_client().record_event( + event_type="com.amazon.rum.deadline.create_job", event_details={"is_success": success} + ) + if not success: raise DeadlineOperationError(status_message) diff --git a/src/deadline/client/api/_telemetry.py b/src/deadline/client/api/_telemetry.py index 24c8a7ce9..a019286b3 100644 --- a/src/deadline/client/api/_telemetry.py +++ b/src/deadline/client/api/_telemetry.py @@ -70,6 +70,9 @@ class TelemetryClient: ENDPOINT_PREFIX = "management." + _common_details: Dict[str, Any] = {} + _system_metadata: Dict[str, Any] = {} + def __init__( self, package_name: str, @@ -91,8 +94,10 @@ def __init__( # IDs for this session self.session_id: str = str(uuid.uuid4()) self.telemetry_id: str = self._get_telemetry_identifier(config=config) - # Get common data we'll include in each request - self.system_metadata = self._get_system_metadata(config=config) + # If a different base package is provided, include info from this library as supplementary info + if package_name != "deadline-cloud-library": + self._common_details["deadline-cloud-version"] = version + self._system_metadata = self._get_system_metadata(config=config) self._start_threads() @@ -198,7 +203,7 @@ def _process_event_queue_thread(self): { "details": str(json.dumps(event_data.event_details)), "id": str(uuid.uuid4()), - "metadata": str(json.dumps(self.system_metadata)), + "metadata": str(json.dumps(self._system_metadata)), "timestamp": int(datetime.now().timestamp()), "type": event_data.event_type, }, @@ -228,8 +233,7 @@ def _record_summary_statistics( self, event_type: str, summary: SummaryStatistics, from_gui: bool ): details: Dict[str, Any] = asdict(summary) - details["usage_mode"] = "GUI" if from_gui else "CLI" - self._put_telemetry_record(TelemetryEvent(event_type=event_type, event_details=details)) + self.record_event(event_type=event_type, event_details=details, from_gui=from_gui) def record_hashing_summary(self, summary: SummaryStatistics, *, from_gui: bool = False): self._record_summary_statistics( @@ -241,12 +245,18 @@ def record_upload_summary(self, summary: SummaryStatistics, *, from_gui: bool = "com.amazon.rum.deadline.job_attachments.upload_summary", summary, from_gui ) - def record_error(self, event_details: Dict[str, Any], exception_type: str): + def record_error( + self, event_details: Dict[str, Any], exception_type: str, from_gui: bool = False + ): event_details["exception_type"] = exception_type # Possibility to add stack trace here - self.record_event("com.amazon.rum.deadline.error", event_details) + self.record_event("com.amazon.rum.deadline.error", event_details, from_gui=from_gui) - def record_event(self, event_type: str, event_details: Dict[str, Any]): + def record_event( + self, event_type: str, event_details: Dict[str, Any], *, from_gui: bool = False + ): + event_details.update(self._common_details) + event_details["usage_mode"] = "GUI" if from_gui else "CLI" self._put_telemetry_record( TelemetryEvent( event_type=event_type, @@ -254,15 +264,19 @@ def record_event(self, event_type: str, event_details: Dict[str, Any]): ) ) + def update_common_details(self, details: Dict[str, Any]): + """Updates the dict of common data that is included in every telemetry request.""" + self._common_details.update(details) + def get_telemetry_client( package_name: str, package_ver: str, config: Optional[ConfigParser] = None ) -> TelemetryClient: """ Retrieves the cached telemetry client, lazy-loading the first time this is called. + :param package_name: Base package name to associate data by. + :param package_ver: Base package version to associate data by. :param config: Optional configuration to use for the client. Loads defaults if not given. - :param package_name: Optional override package name to include in requests. Defaults to the 'deadline-cloud' package. - :param package_ver: Optional override package version to include in requests. Defaults to the 'deadline-cloud' version. :return: Telemetry client to make requests with. """ global __cached_telemetry_client diff --git a/src/deadline/client/cli/_groups/bundle_group.py b/src/deadline/client/cli/_groups/bundle_group.py index 7519eeec8..dd53fa6a0 100644 --- a/src/deadline/client/cli/_groups/bundle_group.py +++ b/src/deadline/client/cli/_groups/bundle_group.py @@ -191,6 +191,12 @@ def _decide_cancel_submission( raise DeadlineOperationError( f"Failed to submit the job bundle to Amazon Deadline Cloud:\n{exc}" ) from exc + except Exception as exc: + api.get_deadline_cloud_library_telemetry_client().record_error( + event_details={"exception_scope": "on_submit"}, + exception_type=str(type(exc)), + ) + raise @cli_bundle.command(name="gui-submit") diff --git a/src/deadline/client/ui/dialogs/submit_job_progress_dialog.py b/src/deadline/client/ui/dialogs/submit_job_progress_dialog.py index 670066367..a2a0559c3 100644 --- a/src/deadline/client/ui/dialogs/submit_job_progress_dialog.py +++ b/src/deadline/client/ui/dialogs/submit_job_progress_dialog.py @@ -509,7 +509,9 @@ def handle_create_job_thread_succeeded(self, success: bool, status_message: str) job creation has finished. """ api.get_deadline_cloud_library_telemetry_client().record_event( - event_type="com.amazon.rum.deadline.create_job", event_details={"is_success": success} + event_type="com.amazon.rum.deadline.create_job", + event_details={"is_success": success}, + from_gui=True, ) if success: diff --git a/src/deadline/client/ui/dialogs/submit_job_to_deadline_dialog.py b/src/deadline/client/ui/dialogs/submit_job_to_deadline_dialog.py index abc1ace81..ea5930354 100644 --- a/src/deadline/client/ui/dialogs/submit_job_to_deadline_dialog.py +++ b/src/deadline/client/ui/dialogs/submit_job_to_deadline_dialog.py @@ -457,6 +457,7 @@ def on_submit(self): event_details={ "submitter_name": settings.submitter_name, }, + from_gui=True, ) self.create_job_response = job_progress_dialog.start_submission( @@ -476,8 +477,9 @@ def on_submit(self): except Exception as exc: logger.exception("error submitting job") api.get_deadline_cloud_library_telemetry_client().record_error( - event_details={"submitter_name": settings.submitter_name}, + event_details={"exception_scope": "on_submit"}, exception_type=str(type(exc)), + from_gui=True, ) QMessageBox.warning(self, f"{settings.submitter_name} Job Submission", str(exc)) job_progress_dialog.close() diff --git a/test/unit/deadline_client/api/test_api_telemetry.py b/test/unit/deadline_client/api/test_api_telemetry.py index d1010068c..52ce5c8e8 100644 --- a/test/unit/deadline_client/api/test_api_telemetry.py +++ b/test/unit/deadline_client/api/test_api_telemetry.py @@ -24,7 +24,7 @@ def fixture_telemetry_client(fresh_deadline_config): side_effect=[("user-id", "identity-store-id")], ): return TelemetryClient( - "test-library", "0.1.2.1234", config=config.config_file.read_config() + "deadline-cloud-library", "0.1.2.1234", config=config.config_file.read_config() ) @@ -170,7 +170,11 @@ def test_record_error(telemetry_client): queue_mock = MagicMock() test_error_details = {"some_field": "some_value"} test_exc = Exception("some exception") - expected_event_details = {"some_field": "some_value", "exception_type": str(type(test_exc))} + expected_event_details = { + "some_field": "some_value", + "exception_type": str(type(test_exc)), + "usage_mode": "CLI", + } expected_event = TelemetryEvent( event_type="com.amazon.rum.deadline.error", event_details=expected_event_details )