Skip to content

Commit

Permalink
[logs] Add reverse order option for retrieving Hue logs
Browse files Browse the repository at this point in the history
  • Loading branch information
Harshg999 committed Jan 23, 2025
1 parent 864283c commit cbc78b1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
9 changes: 7 additions & 2 deletions desktop/core/src/desktop/log/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
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
Expand Down Expand Up @@ -53,6 +54,7 @@ def decorator(*args, **kwargs):
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.
Expand All @@ -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

Expand All @@ -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)


Expand Down
28 changes: 22 additions & 6 deletions desktop/core/src/desktop/log/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def setup_method(self):
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')
Expand All @@ -46,7 +46,7 @@ def test_get_hue_logs_unauthorized(self):

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)
Expand All @@ -58,7 +58,7 @@ def test_log_directory_not_set(self):
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

Expand All @@ -71,8 +71,8 @@ def test_log_file_not_found(self):
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
Expand All @@ -82,4 +82,20 @@ def test_get_hue_logs_success(self):
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']}

0 comments on commit cbc78b1

Please sign in to comment.