Эх сурвалжийг харах

[api][logs] Add reverse order option for retrieving Hue logs (#3968)

Harsh Gupta 10 сар өмнө
parent
commit
162e33a880

+ 7 - 2
desktop/core/src/desktop/log/api.py

@@ -26,6 +26,7 @@ from wsgiref.util import FileWrapper
 from django.http import HttpResponse
 
 from desktop.auth.backend import is_admin
+from desktop.lib.conf import coerce_bool
 from desktop.lib.django_util import JsonResponse
 from desktop.lib.i18n import smart_str
 from desktop.log import DEFAULT_LOG_DIR
@@ -53,6 +54,7 @@ def api_error_handler(view_fn):
 def get_hue_logs(request):
   """
   Retrieves the last X characters of log messages from the log file.
+  Optionally, the log messages can be returned in reverse order.
 
   Args:
     request: The HTTP request object.
@@ -68,11 +70,14 @@ def get_hue_logs(request):
   Notes:
     This endpoint retrieves the last X characters of log messages from the log file.
     The log file is read up to the buffer size, and if it's smaller than the buffer size,
-    the previous log file is read to complete the buffer.
+    the previous log file is read to complete the buffer. If the 'reverse' query parameter
+    is set to True, the log messages are returned in reverse order.
   """
   if not is_admin(request.user):
     return HttpResponse("You must be a Hue admin to access this endpoint.", status=403)
 
+  reverse_logs = coerce_bool(request.GET.get('reverse', False))
+
   # Buffer size for reading log files
   LOG_BUFFER_SIZE = 32 * 1024
 
@@ -98,7 +103,7 @@ def get_hue_logs(request):
       # Read the previous log file contents
       buffer = _read_previous_log_file(LOG_BUFFER_SIZE, previous_log_file, prev_log_file_size, log_file_size) + buffer
 
-  response = {'hue_hostname': socket.gethostname(), 'logs': ''.join(buffer)}
+  response = {'hue_hostname': socket.gethostname(), 'logs': buffer[::-1] if reverse_logs else buffer}
   return JsonResponse(response)
 
 

+ 22 - 6
desktop/core/src/desktop/log/api_test.py

@@ -36,7 +36,7 @@ class TestHueLogs:
     self.user_not_admin = User.objects.get(username="test_not_admin")
 
   def test_get_hue_logs_unauthorized(self):
-    request = Mock(method='GET', user=self.user_not_admin)
+    request = Mock(method='GET', GET={}, user=self.user_not_admin)
 
     response = get_hue_logs(request)
     res_content = response.content.decode('utf-8')
@@ -46,7 +46,7 @@ class TestHueLogs:
 
   def test_log_directory_not_set(self):
     with patch('desktop.log.api.os.getenv') as os_getenv:
-      request = Mock(method='GET', user=self.user_admin)
+      request = Mock(method='GET', GET={}, user=self.user_admin)
       os_getenv.return_value = None
 
       response = get_hue_logs(request)
@@ -58,7 +58,7 @@ class TestHueLogs:
   def test_log_file_not_found(self):
     with patch('desktop.log.api.os.getenv') as os_getenv:
       with patch('desktop.log.api.os.path.exists') as os_path_exist:
-        request = Mock(method='GET', user=self.user_admin)
+        request = Mock(method='GET', GET={}, user=self.user_admin)
         os_getenv.return_value = '/var/log/hue/'
         os_path_exist.return_value = False
 
@@ -71,8 +71,8 @@ class TestHueLogs:
   def test_get_hue_logs_success(self):
     with patch('desktop.log.api.os') as mock_os:
       with patch('desktop.log.api._read_log_file') as _read_log_file:
-        request = Mock(method='GET', user=self.user_admin)
-        _read_log_file.return_value = 'test log content'
+        request = Mock(method='GET', GET={}, user=self.user_admin)
+        _read_log_file.return_value = ['Line 1: test log content', 'Line 2: more log lines']
 
         mock_os.os_getenv.return_value = '/var/log/hue/'
         mock_os.path.exists.return_value = True
@@ -82,4 +82,20 @@ class TestHueLogs:
         response_data = json.loads(response.content)
 
         assert response.status_code == 200
-        assert response_data == {'hue_hostname': socket.gethostname(), 'logs': 'test log content'}
+        assert response_data == {'hue_hostname': socket.gethostname(), 'logs': ['Line 1: test log content', 'Line 2: more log lines']}
+
+  def test_get_hue_logs_reverse_success(self):
+    with patch('desktop.log.api.os') as mock_os:
+      with patch('desktop.log.api._read_log_file') as _read_log_file:
+        request = Mock(method='GET', GET={'reverse': 'true'}, user=self.user_admin)
+        _read_log_file.return_value = ['Line 1: test log content', 'Line 2: more log lines']
+
+        mock_os.os_getenv.return_value = '/var/log/hue/'
+        mock_os.path.exists.return_value = True
+        mock_os.path.getsize.return_value = 32 * 1024 * 2  # Greater than log buffer size
+
+        response = get_hue_logs(request)
+        response_data = json.loads(response.content)
+
+        assert response.status_code == 200
+        assert response_data == {'hue_hostname': socket.gethostname(), 'logs': ['Line 2: more log lines', 'Line 1: test log content']}