From d1b308fbe428b695d160ecc185e2c72fa4ceba27 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 21 Apr 2020 09:33:36 +0200 Subject: [PATCH] logger: add DebugLogview (#42751) --- hobo/logger.py | 66 ++++++++++++++++++++++++++++++++ hobo/test_urls.py | 3 ++ tests_multitenant/debug_log.html | 28 ++++++++++++++ tests_multitenant/settings.py | 1 + tests_multitenant/test_logger.py | 34 ++++++++++++++++ tox.ini | 1 + 6 files changed, 133 insertions(+) create mode 100644 tests_multitenant/debug_log.html diff --git a/hobo/logger.py b/hobo/logger.py index ea7fe43..7dec537 100644 --- a/hobo/logger.py +++ b/hobo/logger.py @@ -24,7 +24,10 @@ import time import warnings from django.conf import settings +from django.core.exceptions import PermissionDenied from django.db import connection +from django.http import JsonResponse +from django.views.generic import TemplateView from hobo.middleware.utils import StoreRequestMiddleware @@ -220,3 +223,66 @@ class DebugLog(object): return for record in cls(debug_log_path)._parse(cursor=cursor): yield record + + +class DebugLogView(TemplateView): + '''Use with DebugLogView.as_view(templante_name='local_template_path.html') + + Template like this can be used : + + + + + + + + + + + + + + + + {% for record in view.records %} + + + + + + + + + + {% endfor %} + + Next page + + ''' + + paginate = 50 + + def get(self, request, *args, **kwargs): + internal_ips = getattr(settings, 'INTERNAL_IPS', []) + if request.META.get('REMOTE_ADDR') not in internal_ips: + raise PermissionDenied + if request.is_ajax(): + return JsonResponse({ + 'err': 0, + 'data': [record for record in self.records()], + 'cursor': self.cursor, + 'next': '%s?cursor=%s' % (self.request.path, self.cursor), + }) + return super(DebugLogView, self).get(request, *args, **kwargs) + + def records(self): + try: + cursor = int(self.request.GET['cursor']) + if cursor < 0: + cursor = 0 + except (ValueError, TypeError, KeyError): + cursor = 0 + for i, record in zip(range(self.paginate), DebugLog.lines(cursor=cursor)): + self.cursor = record.get('cursor') + yield record diff --git a/hobo/test_urls.py b/hobo/test_urls.py index d1f4635..350b980 100644 --- a/hobo/test_urls.py +++ b/hobo/test_urls.py @@ -3,6 +3,8 @@ import logging from django.conf.urls import url from django.http import HttpResponse +from hobo.logger import DebugLogView + def helloworld(request): logging.getLogger(__name__).error('wat!') @@ -12,4 +14,5 @@ def helloworld(request): urlpatterns = [ url(r'^$', helloworld), + url(r'^__debug__/$', DebugLogView.as_view(template_name='debug_log.html', paginate=10)), ] diff --git a/tests_multitenant/debug_log.html b/tests_multitenant/debug_log.html new file mode 100644 index 0000000..09a4178 --- /dev/null +++ b/tests_multitenant/debug_log.html @@ -0,0 +1,28 @@ +
TimestampLevelTenantIPUserRequest IDLogggerMessage
{{ record.timestamp }}{{ record.level }}{{ record.tenant}}{{ record.user }}{{ record.request_id }}{{ record.name }}
{{ record.message}}
+ + + + + + + + + + + + + + {% for record in view.records %} + + + + + + + + + + {% endfor %} + +
TimestampLevelTenantIPUserRequest IDLogggerMessage
{{ record.timestamp }}{{ record.level }}{{ record.tenant}}{{ record.user }}{{ record.request_id }}{{ record.name }}
{{ record.message}}
+Next page diff --git a/tests_multitenant/settings.py b/tests_multitenant/settings.py index 2cc60a7..45042a9 100644 --- a/tests_multitenant/settings.py +++ b/tests_multitenant/settings.py @@ -37,6 +37,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ + 'tests_multitenant/', ], 'APP_DIRS': True, 'OPTIONS': { diff --git a/tests_multitenant/test_logger.py b/tests_multitenant/test_logger.py index 39f46c5..0f0554f 100644 --- a/tests_multitenant/test_logger.py +++ b/tests_multitenant/test_logger.py @@ -105,3 +105,37 @@ def test_debug_log(tenants, settings, app, rf, debug_log, freezer): lines2 = list(DebugLog.lines(cursor=lines[0]['cursor'])) assert len(lines2) == 1 assert lines[1] == lines2[0] + + + # test of DebugLogView + + for i in range(100): + debug_log.debug('log %s is \nok', i, extra={'request': request}) + + settings.ALLOWED_HOSTS = ['*'] + app.extra_environ['HTTP_HOST'] = tenants[0].domain_url + response = app.get('/__debug__/', status=403) + settings.INTERNAL_IPS = ['127.0.0.1'] + response = app.get('/__debug__/') + assert len(response.pyquery('tbody tr')) == 10 + cells = [response.pyquery(td).text() for td in response.pyquery('tbody tr').eq(0).find('td')] + assert cells == [ + '20 avril 2020 02:00', + 'INFO', + 'tenant1.example.net', + '-', + 'r:' + request_id, + '', + 'log 2 is ok' + ] + + response2 = response.click('Next page') + assert len(response2.pyquery('tbody tr')) == 10 + + # test JSON requests + ajax_response = app.get( + '/__debug__/' + response2.pyquery('a').attr('href'), + extra_environ={'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}) + assert 'data' in ajax_response.json + assert isinstance(ajax_response.json['cursor'], int) + assert ajax_response.json['next'].startswith('/__debug__/?cursor=') diff --git a/tox.ini b/tox.ini index 18aa238..74306b3 100644 --- a/tox.ini +++ b/tox.ini @@ -56,6 +56,7 @@ deps: enum34<=1.1.6 py2: django-appconf<1.0.4 psycopg2-binary + pyquery commands = py2: ./getlasso.sh py3: ./getlasso3.sh -- 2.28.0