From cea317305acc271efddd523e35f1f7f42e18e653 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 21 Jan 2022 11:56:34 +0100
Subject: [PATCH] views: add a log on endpoint result (#60911)

---
 passerelle/views.py            | 21 ++++++++++++++++++++-
 tests/test_generic_endpoint.py | 23 ++++++++++++++---------
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/passerelle/views.py b/passerelle/views.py
index 76ab38f6..a964e6db 100644
--- a/passerelle/views.py
+++ b/passerelle/views.py
@@ -56,7 +56,7 @@ from passerelle.base.models import BaseResource, ResourceLog
 from passerelle.compat import json_loads
 from passerelle.utils.conversion import normalize
 from passerelle.utils.json import unflatten
-from passerelle.utils.jsonresponse import APIError
+from passerelle.utils.jsonresponse import APIError, JSONEncoder
 from passerelle.utils.paginator import InfinitePaginator
 
 from .forms import ResourceLogSearchForm
@@ -517,6 +517,7 @@ class GenericEndpointView(GenericConnectorMixin, SingleObjectMixin, View):
             raise WrongParameter(missing, extra)
 
         params = self.get_params(request, *args, **kwargs)
+        in_cache = False
         if request.method == 'GET' and self.endpoint.endpoint_info.cache_duration:
             cache_key = hashlib.md5(
                 force_bytes(repr(self.get_object().slug) + repr(self.endpoint) + repr(params))
@@ -524,6 +525,7 @@ class GenericEndpointView(GenericConnectorMixin, SingleObjectMixin, View):
             result = cache.get(cache_key)
             if result is not None:
                 # filter result after caching
+                in_cache = True
                 result = self.filter_result(request, params, result)
                 return result
 
@@ -532,6 +534,23 @@ class GenericEndpointView(GenericConnectorMixin, SingleObjectMixin, View):
             cache.set(cache_key, result, self.endpoint.endpoint_info.cache_duration)
         # filter result after caching
         result = self.filter_result(request, params, result)
+        try:
+            data = json.dumps(result, cls=JSONEncoder)
+        except TypeError:
+            data = str(result)
+        self.connector.logger.debug(
+            'endpoint %s %s (%r) ' % (request.method, url, payload),
+            extra={
+                'request': request,
+                'connector': connector_name,
+                'connector_endpoint': endpoint_name,
+                'connector_endpoint_method': request.method,
+                'connector_endpoint_url': url,
+                'connector_payload': payload,
+                'connector_result': data,
+                'connector_result_in_cache': in_cache,
+            },
+        )
         return result
 
     def filter_result(self, request, params, result):
diff --git a/tests/test_generic_endpoint.py b/tests/test_generic_endpoint.py
index e07a63f2..aba83252 100644
--- a/tests/test_generic_endpoint.py
+++ b/tests/test_generic_endpoint.py
@@ -132,13 +132,18 @@ def test_proxy_logger(mocked_get, caplog, app, arcgis):
     assert '/arcgis/test/mapservice-query?' in log.extra['connector_endpoint_url']
 
     # Resource Generic Logger
-    for record in caplog.records:
-        if record.name != 'passerelle.resource.arcgis.test':
-            continue
-        assert record.levelno == 20
-        assert record.levelname == 'INFO'
-        assert record.name == 'passerelle.resource.arcgis.test'
-        assert u"endpoint GET /arcgis/test/mapservice-query?" in record.message
+    record = caplog.records[0]
+    assert record.levelno == 20
+    assert record.levelname == 'INFO'
+    assert record.name == 'passerelle.resource.arcgis.test'
+    assert u"endpoint GET /arcgis/test/mapservice-query?" in record.message
+    assert not hasattr(record, 'connector_result')
+    record = caplog.records[1]
+    assert record.levelno == 10
+    assert record.levelname == 'DEBUG'
+    assert record.name == 'passerelle.resource.arcgis.test'
+    assert u"endpoint GET /arcgis/test/mapservice-query?" in record.message
+    assert hasattr(record, 'connector_result')
 
     data = resp.json['data']
     assert data[0]['id'] == '4'
@@ -174,8 +179,8 @@ def test_proxy_logger_transaction_id(mocked_send, app, arcgis):
         status=200,
     )
 
-    log1, log2 = ResourceLog.objects.filter(appname='arcgis', slug='test').all()
-    assert log1.extra['transaction_id'] == log2.extra['transaction_id']
+    log1, log2, log3 = ResourceLog.objects.filter(appname='arcgis', slug='test').all()
+    assert log1.extra['transaction_id'] == log2.extra['transaction_id'] == log3.extra['transaction_id']
 
 
 @mock.patch('passerelle.utils.Request.patch')
-- 
2.34.1

