]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Lower log level of errors due to user requests to INFO
authorAkihiro Motoki <motoki@da.jp.nec.com>
Wed, 19 Feb 2014 19:21:55 +0000 (04:21 +0900)
committerAkihiro Motoki <motoki@da.jp.nec.com>
Tue, 25 Feb 2014 10:43:14 +0000 (19:43 +0900)
Errors due to bad client requests (e.g., NotFound, BadRequest)
are logged as exception/trace level and it is annoying
from the point of operators' view.
This commit changes the log level for errors due to
user requests (HTTP 4xx errors) to INFO.

Closes-Bug: #1282394
Change-Id: Ic5646333db88ce856f9366e914cf961890d30501

neutron/api/v2/resource.py
neutron/tests/unit/test_api_v2_resource.py

index a6e9765e387382f1441581b3e5ba199ba721f23b..fb139b2ac5a4b96fbe168c400f0325af67b9164a 100644 (file)
@@ -84,17 +84,24 @@ def Resource(controller, faults=None, deserializers=None, serializers=None):
             result = method(request=request, **args)
         except (exceptions.NeutronException,
                 netaddr.AddrFormatError) as e:
-            LOG.exception(_('%s failed'), action)
+            for fault in faults:
+                if isinstance(e, fault):
+                    mapped_exc = faults[fault]
+                    break
+            else:
+                mapped_exc = webob.exc.HTTPInternalServerError
+            if 400 <= mapped_exc.code < 500:
+                LOG.info(_('%(action)s failed (client error): %(exc)s'),
+                         {'action': action, 'exc': e})
+            else:
+                LOG.exception(_('%s failed'), action)
             e = translate(e, language)
             # following structure is expected by python-neutronclient
             err_data = {'type': e.__class__.__name__,
                         'message': e, 'detail': ''}
             body = serializer.serialize({'NeutronError': err_data})
             kwargs = {'body': body, 'content_type': content_type}
-            for fault in faults:
-                if isinstance(e, fault):
-                    raise faults[fault](**kwargs)
-            raise webob.exc.HTTPInternalServerError(**kwargs)
+            raise mapped_exc(**kwargs)
         except webob.exc.HTTPException as e:
             LOG.exception(_('%s failed'), action)
             translate(e, language)
index 298283cb957d3549a1ed4abe0a226e39a660a2d6..63fc061da92b49d11c55d778a592b399f0cccbd4 100644 (file)
@@ -324,6 +324,33 @@ class ResourceTestCase(base.BaseTestCase):
         res = resource.delete('', extra_environ=environ)
         self.assertEqual(res.status_int, 204)
 
+    def _test_error_log_level(self, map_webob_exc, expect_log_info=False,
+                              use_fault_map=True):
+        class TestException(q_exc.NeutronException):
+            message = 'Test Exception'
+
+        controller = mock.MagicMock()
+        controller.test.side_effect = TestException()
+        faults = {TestException: map_webob_exc} if use_fault_map else {}
+        resource = webtest.TestApp(wsgi_resource.Resource(controller, faults))
+        environ = {'wsgiorg.routing_args': (None, {'action': 'test'})}
+        with mock.patch.object(wsgi_resource, 'LOG') as log:
+            res = resource.get('', extra_environ=environ, expect_errors=True)
+            self.assertEqual(res.status_int, map_webob_exc.code)
+        self.assertEqual(expect_log_info, log.info.called)
+        self.assertNotEqual(expect_log_info, log.exception.called)
+
+    def test_4xx_error_logged_info_level(self):
+        self._test_error_log_level(exc.HTTPNotFound, expect_log_info=True)
+
+    def test_non_4xx_error_logged_exception_level(self):
+        self._test_error_log_level(exc.HTTPServiceUnavailable,
+                                   expect_log_info=False)
+
+    def test_unmapped_error_logged_exception_level(self):
+        self._test_error_log_level(exc.HTTPInternalServerError,
+                                   expect_log_info=False, use_fault_map=False)
+
     def test_no_route_args(self):
         controller = mock.MagicMock()