diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 21f004ee9c..e33c86c79e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,10 @@ Change Log Unreleased ---------- +[4.11.14] +--------- +* feat: added channel_name for api call logs records + [4.11.13] --------- * feat: Update IntegratedChannelAPIRequestLogs list view diff --git a/enterprise/__init__.py b/enterprise/__init__.py index 3bf0eda716..0adaa06b59 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.11.13" +__version__ = "4.11.14" diff --git a/integrated_channels/blackboard/client.py b/integrated_channels/blackboard/client.py index 4d93163603..a4e871138e 100644 --- a/integrated_channels/blackboard/client.py +++ b/integrated_channels/blackboard/client.py @@ -610,6 +610,7 @@ def _get(self, url, data=None): time_taken=time_taken, status_code=get_response.status_code, response_body=get_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if get_response.status_code >= 400: raise ClientError(get_response.text, get_response.status_code) @@ -630,6 +631,7 @@ def _patch(self, url, data): time_taken=time_taken, status_code=patch_response.status_code, response_body=patch_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if patch_response.status_code >= 400: raise ClientError(patch_response.text, patch_response.status_code) @@ -650,6 +652,7 @@ def _post(self, url, data): time_taken=time_taken, status_code=post_response.status_code, response_body=post_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if post_response.status_code >= 400: @@ -671,6 +674,7 @@ def _delete(self, url): time_taken=time_taken, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if response.status_code >= 400: raise ClientError(response.text, response.status_code) diff --git a/integrated_channels/canvas/client.py b/integrated_channels/canvas/client.py index 277f9488fc..8911ccf6ad 100644 --- a/integrated_channels/canvas/client.py +++ b/integrated_channels/canvas/client.py @@ -325,6 +325,7 @@ def cleanup_duplicate_assignment_records(self, courses): time_taken=duration_seconds, status_code=resp.status_code, response_body=resp.text, + channel_name=self.enterprise_configuration.channel_code() ) if resp.status_code >= 400: @@ -557,6 +558,7 @@ def _post(self, url, data): time_taken=duration_seconds, status_code=post_response.status_code, response_body=post_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if post_response.status_code >= 400: @@ -583,6 +585,7 @@ def _put(self, url, data): time_taken=duration_seconds, status_code=put_response.status_code, response_body=put_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if put_response.status_code >= 400: raise ClientError(put_response.text, put_response.status_code) @@ -610,6 +613,7 @@ def _delete(self, url): time_taken=duration_seconds, status_code=delete_response.status_code, response_body=delete_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if delete_response.status_code >= 400: raise ClientError(delete_response.text, delete_response.status_code) @@ -671,6 +675,7 @@ def _search_for_canvas_user_by_email(self, user_email): time_taken=duration_seconds, status_code=rsps.status_code, response_body=rsps.text, + channel_name=self.enterprise_configuration.channel_code() ) if rsps.status_code >= 400: @@ -705,6 +710,7 @@ def _get_canvas_user_courses_by_id(self, user_id): time_taken=duration_seconds, status_code=rsps.status_code, response_body=rsps.text, + channel_name=self.enterprise_configuration.channel_code() ) if rsps.status_code >= 400: @@ -749,6 +755,7 @@ def _handle_canvas_assignment_retrieval( time_taken=duration_seconds, status_code=resp.status_code, response_body=resp.text, + channel_name=self.enterprise_configuration.channel_code() ) more_pages_present = True @@ -796,6 +803,7 @@ def _handle_canvas_assignment_retrieval( time_taken=duration_seconds, status_code=resp.status_code, response_body=resp.text, + channel_name=self.enterprise_configuration.channel_code() ) current_page_count += 1 @@ -828,6 +836,7 @@ def _handle_canvas_assignment_retrieval( time_taken=duration_seconds, status_code=resp.status_code, response_body=resp.text, + channel_name=self.enterprise_configuration.channel_code() ) try: @@ -865,6 +874,7 @@ def _handle_canvas_assignment_submission(self, grade, course_id, assignment_id, time_taken=duration_seconds, status_code=submission_response.status_code, response_body=submission_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if submission_response.status_code >= 400: @@ -979,6 +989,7 @@ def _get_oauth_access_token(self): time_taken=duration_seconds, status_code=auth_response.status_code, response_body=auth_response.text, + channel_name=self.enterprise_configuration.channel_code() ) if auth_response.status_code >= 400: raise ClientError(auth_response.text, auth_response.status_code) diff --git a/integrated_channels/canvas/utils.py b/integrated_channels/canvas/utils.py index 4a5321cfe8..3f9c82f551 100644 --- a/integrated_channels/canvas/utils.py +++ b/integrated_channels/canvas/utils.py @@ -54,6 +54,7 @@ def find_root_canvas_account(enterprise_configuration, session): time_taken=duration_seconds, status_code=resp.status_code, response_body=resp.text, + channel_name=enterprise_configuration.channel_code() ) all_accounts = resp.json() root_account = None @@ -97,6 +98,7 @@ def find_course_in_account(enterprise_configuration, session, canvas_account_id, time_taken=duration_seconds, status_code=resp.status_code, response_body=resp.text, + channel_name=enterprise_configuration.channel_code() ) all_courses_response = resp.json() diff --git a/integrated_channels/cornerstone/client.py b/integrated_channels/cornerstone/client.py index 6f4a74244e..97b7db0dfc 100644 --- a/integrated_channels/cornerstone/client.py +++ b/integrated_channels/cornerstone/client.py @@ -126,6 +126,7 @@ def create_course_completion(self, user_id, payload): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) return response.status_code, response.text diff --git a/integrated_channels/cornerstone/views.py b/integrated_channels/cornerstone/views.py index 47308b86ff..457cbdd2d3 100644 --- a/integrated_channels/cornerstone/views.py +++ b/integrated_channels/cornerstone/views.py @@ -173,6 +173,7 @@ def get(self, request, *args, **kwargs): payload=f"Request Headers: {headers_json}", time_taken=duration_seconds, status_code=200, - response_body=json.dumps(data) + response_body=json.dumps(data), + channel_name=enterprise_config.channel_code() ) return Response(data) diff --git a/integrated_channels/degreed2/client.py b/integrated_channels/degreed2/client.py index 95b8d1eae1..7929f12de9 100644 --- a/integrated_channels/degreed2/client.py +++ b/integrated_channels/degreed2/client.py @@ -487,6 +487,7 @@ def _get(self, url, scope): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if attempts <= self.MAX_RETRIES and response.status_code == 429: sleep_seconds = self._calculate_backoff(attempts) @@ -531,6 +532,7 @@ def _post(self, url, data, scope): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if attempts <= self.MAX_RETRIES and response.status_code == 429: sleep_seconds = self._calculate_backoff(attempts) @@ -575,6 +577,7 @@ def _patch(self, url, data, scope): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if attempts <= self.MAX_RETRIES and response.status_code == 429: sleep_seconds = self._calculate_backoff(attempts) @@ -619,6 +622,7 @@ def _delete(self, url, data, scope): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if attempts <= self.MAX_RETRIES and response.status_code == 429: sleep_seconds = self._calculate_backoff(attempts) @@ -682,6 +686,7 @@ def _get_oauth_access_token(self, scope): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) try: diff --git a/integrated_channels/integrated_channel/migrations/0033_integratedchannelapirequestlogs_channel_name.py b/integrated_channels/integrated_channel/migrations/0033_integratedchannelapirequestlogs_channel_name.py new file mode 100644 index 0000000000..6c6fec4596 --- /dev/null +++ b/integrated_channels/integrated_channel/migrations/0033_integratedchannelapirequestlogs_channel_name.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.23 on 2024-02-16 07:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('integrated_channel', '0032_alter_integratedchannelapirequestlogs_endpoint'), + ] + + operations = [ + migrations.AddField( + model_name='integratedchannelapirequestlogs', + name='channel_name', + field=models.TextField(blank=True, help_text='Name of the integrated channel associated with this API call log record.'), + ), + ] diff --git a/integrated_channels/integrated_channel/models.py b/integrated_channels/integrated_channel/models.py index 44ab495e35..792e60ee5a 100644 --- a/integrated_channels/integrated_channel/models.py +++ b/integrated_channels/integrated_channel/models.py @@ -907,6 +907,10 @@ class IntegratedChannelAPIRequestLogs(TimeStampedModel): response_body = models.TextField( help_text="API call response body", blank=True, null=True ) + channel_name = models.TextField( + help_text="Name of the integrated channel associated with this API call log record.", + blank=True + ) class Meta: app_label = "integrated_channel" @@ -942,6 +946,7 @@ def store_api_call( time_taken, status_code, response_body, + channel_name ): """ Creates new record in IntegratedChannelAPIRequestLogs table. @@ -955,6 +960,7 @@ def store_api_call( time_taken=time_taken, status_code=status_code, response_body=response_body, + channel_name=channel_name ) record.save() except Exception as e: # pylint: disable=broad-except @@ -967,4 +973,5 @@ def store_api_call( f"time_taken={time_taken}" f"status_code={status_code}" f"response_body={response_body}" + f"channel_name={channel_name}" ) diff --git a/integrated_channels/moodle/client.py b/integrated_channels/moodle/client.py index 6192311250..cd883e12a3 100644 --- a/integrated_channels/moodle/client.py +++ b/integrated_channels/moodle/client.py @@ -169,6 +169,7 @@ def _post(self, additional_params): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) return response @@ -213,6 +214,7 @@ def _get_access_token(self): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) try: @@ -287,6 +289,7 @@ def _get_course_contents(self, course_id): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) return response @@ -347,6 +350,7 @@ def _get_courses(self, key): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) return response diff --git a/integrated_channels/sap_success_factors/client.py b/integrated_channels/sap_success_factors/client.py index 3ba32ec971..a4e89eadc7 100644 --- a/integrated_channels/sap_success_factors/client.py +++ b/integrated_channels/sap_success_factors/client.py @@ -102,6 +102,7 @@ def get_oauth_access_token(self, client_id, client_secret, company_id, user_id, time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) try: @@ -289,6 +290,7 @@ def _call_post_with_user_override(self, sap_user_id, url, payload): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if response.status_code >= 400: @@ -320,6 +322,7 @@ def _call_post_with_session(self, url, payload): time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) if response.status_code >= 400: LOGGER.error( @@ -401,6 +404,7 @@ def _call_search_students_recursively(self, sap_search_student_url, all_inactive time_taken=duration_seconds, status_code=response.status_code, response_body=response.text, + channel_name=self.enterprise_configuration.channel_code() ) sap_inactive_learners = response.json() except ValueError as error: diff --git a/integrated_channels/utils.py b/integrated_channels/utils.py index 9c8a273128..879043a9e0 100644 --- a/integrated_channels/utils.py +++ b/integrated_channels/utils.py @@ -517,7 +517,8 @@ def stringify_and_store_api_record( data, time_taken, status_code, - response_body + response_body, + channel_name ): """ Stringify the given data and store the API record in the database. @@ -537,6 +538,7 @@ def stringify_and_store_api_record( f"stringify_and_store_api_record: Error occured during stringification: {e}" f"enterprise_customer={enterprise_customer}" f"enterprise_customer_configuration_id={enterprise_customer_configuration_id}" + f"channel name={channel_name}" f"data={data}" ) # Store stringified data in the database @@ -549,12 +551,14 @@ def stringify_and_store_api_record( time_taken=time_taken, status_code=status_code, response_body=response_body, + channel_name=channel_name ) except Exception as e: # pylint: disable=broad-except LOGGER.error( f"stringify_and_store_api_record: Error occured while storing: {e}" f"enterprise_customer={enterprise_customer}" f"enterprise_customer_configuration_id={enterprise_customer_configuration_id}" + f"channel name={channel_name}" f"data={data}" ) return data diff --git a/tests/test_integrated_channels/test_utils.py b/tests/test_integrated_channels/test_utils.py index c7910be641..1725666c75 100644 --- a/tests/test_integrated_channels/test_utils.py +++ b/tests/test_integrated_channels/test_utils.py @@ -359,26 +359,26 @@ def test_stringify_and_store_api_record( # Test with dict input stringified_data = utils.stringify_and_store_api_record( - "Customer", 123, "/endpoint", data, 1.23, 200, "response" + "Customer", 123, "/endpoint", data, 1.23, 200, "response", 'integrated_channel_name' ) assert stringified_data == json.dumps(data) # Test with int input stringified_int = utils.stringify_and_store_api_record( - "Customer", 123, "/endpoint", 123, 1.23, 200, "response" + "Customer", 123, "/endpoint", 123, 1.23, 200, "response", 'integrated_channel_name' ) assert stringified_int == "123" # Test with tuple input data_tuple = (1, 2, "hello") stringified_tuple = utils.stringify_and_store_api_record( - "Customer", 123, "/endpoint", data_tuple, 1.23, 200, "response" + "Customer", 123, "/endpoint", data_tuple, 1.23, 200, "response", 'integrated_channel_name' ) assert stringified_tuple == json.dumps(data_tuple) # Test with list input data_list = [1, 2, "world"] stringified_list = utils.stringify_and_store_api_record( - "Customer", 123, "/endpoint", data_list, 1.23, 200, "response" + "Customer", 123, "/endpoint", data_list, 1.23, 200, "response", 'integrated_channel_name' ) assert stringified_list == json.dumps(data_list)