diff --git a/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py b/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py
index 635eda8af6f29dbc68436cd22fafbccf878abf52..690a14416b3d0a9883931e7af0f93c87d9a8f40f 100644
--- a/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py
+++ b/openedx/core/djangoapps/oauth_dispatch/tests/test_views.py
@@ -7,10 +7,10 @@ import unittest
 
 import ddt
 import httpretty
-from Cryptodome.PublicKey import RSA
 from django.conf import settings
 from django.urls import reverse
-from django.test import RequestFactory, TestCase, override_settings
+from django.test import RequestFactory, TestCase
+from mock import call, patch
 from oauth2_provider import models as dot_models
 from organizations.tests.factories import OrganizationFactory
 
@@ -212,6 +212,35 @@ class TestAccessTokenView(AccessTokenLoginMixin, mixins.AccessTokenMixin, _Dispa
             should_be_restricted=False,
         )
 
+    @ddt.data(
+        ('jwt', 'jwt'),
+        (None, 'no_token_type_supplied'),
+    )
+    @ddt.unpack
+    @patch('openedx.core.djangoapps.monitoring_utils.set_custom_metric')
+    def test_access_token_metrics(self, token_type, expected_token_type, mock_set_custom_metric):
+        response = self._post_request(self.user, self.dot_app, token_type=token_type)
+        self.assertEqual(response.status_code, 200)
+        expected_calls = [
+            call('oauth_token_type', expected_token_type),
+            call('oauth_grant_type', 'password'),
+        ]
+        mock_set_custom_metric.assert_has_calls(expected_calls, any_order=True)
+
+    @patch('openedx.core.djangoapps.monitoring_utils.set_custom_metric')
+    def test_access_token_metrics_for_bad_request(self, mock_set_custom_metric):
+        grant_type = dot_models.Application.GRANT_PASSWORD
+        invalid_body = {
+            'grant_type': grant_type.replace('-', '_'),
+        }
+        bad_response = self.client.post(self.url, invalid_body)
+        self.assertEqual(bad_response.status_code, 400)
+        expected_calls = [
+            call('oauth_token_type', 'no_token_type_supplied'),
+            call('oauth_grant_type', 'password'),
+        ]
+        mock_set_custom_metric.assert_has_calls(expected_calls, any_order=True)
+
     @ddt.data(
         (False, True, settings.DEFAULT_JWT_ISSUER),
         (True, False, settings.RESTRICTED_APPLICATION_JWT_ISSUER),
@@ -529,13 +558,29 @@ class TestViewDispatch(TestCase):
         """
         return RequestFactory().get('/?client_id={}'.format(client_id))
 
-    def test_dispatching_post_to_dot(self):
+    def _verify_oauth_metrics_calls(self, mock_set_custom_metric, expected_oauth_adapter):
+        """
+        Args:
+            mock_set_custom_metric: MagicMock of set_custom_metric
+            expected_oauth_adapter: Either 'dot' or 'dop'
+        """
+        expected_calls = [
+            call('oauth_client_id', '{}-id'.format(expected_oauth_adapter)),
+            call('oauth_adapter', expected_oauth_adapter),
+        ]
+        mock_set_custom_metric.assert_has_calls(expected_calls, any_order=True)
+
+    @patch('openedx.core.djangoapps.monitoring_utils.set_custom_metric')
+    def test_dispatching_post_to_dot(self, mock_set_custom_metric):
         request = self._post_request('dot-id')
         self.assertEqual(self.view.select_backend(request), self.dot_adapter.backend)
+        self._verify_oauth_metrics_calls(mock_set_custom_metric, 'dot')
 
-    def test_dispatching_post_to_dop(self):
+    @patch('openedx.core.djangoapps.monitoring_utils.set_custom_metric')
+    def test_dispatching_post_to_dop(self, mock_set_custom_metric):
         request = self._post_request('dop-id')
         self.assertEqual(self.view.select_backend(request), self.dop_adapter.backend)
+        self._verify_oauth_metrics_calls(mock_set_custom_metric, 'dop')
 
     def test_dispatching_get_to_dot(self):
         request = self._get_request('dot-id')
diff --git a/openedx/core/djangoapps/oauth_dispatch/views.py b/openedx/core/djangoapps/oauth_dispatch/views.py
index e1a8b80d93ef8924966e6a42c28cb25d259f641a..3f0bb447e7a24e27d2aac7f60dc028f969f4b943 100644
--- a/openedx/core/djangoapps/oauth_dispatch/views.py
+++ b/openedx/core/djangoapps/oauth_dispatch/views.py
@@ -102,15 +102,12 @@ class AccessTokenView(RatelimitMixin, _DispatchingView):
     def dispatch(self, request, *args, **kwargs):
         response = super(AccessTokenView, self).dispatch(request, *args, **kwargs)
 
-        if response.status_code == 200:
-            monitoring_utils.set_custom_metric('oauth_grant_type', request.POST.get('grant_type', ''))
+        token_type = request.POST.get('token_type', 'no_token_type_supplied').lower()
+        monitoring_utils.set_custom_metric('oauth_token_type', token_type)
+        monitoring_utils.set_custom_metric('oauth_grant_type', request.POST.get('grant_type', ''))
 
-            if request.POST.get('token_type', '').lower() == 'jwt':
-                response.content = self._build_jwt_response_from_access_token_response(request, response)
-
-                monitoring_utils.set_custom_metric('oauth_token_type', 'jwt')
-            else:
-                monitoring_utils.set_custom_metric('oauth_token_type', 'oauth')
+        if response.status_code == 200 and token_type == 'jwt':
+            response.content = self._build_jwt_response_from_access_token_response(request, response)
 
         return response