From 9474172f8063cd4f487feb47360dda3be2638cbd Mon Sep 17 00:00:00 2001 From: Anthony Mahanna <43019056+aMahanna@users.noreply.github.com> Date: Thu, 23 Nov 2023 10:54:55 -0500 Subject: [PATCH] DE-699 | Update global server logs retrieval (#299) * DE-699 | initial commit * add deprecation warning * bump stacklevel --- arango/database.py | 80 +++++++++++++++++++++++++++++++++++++++++- tests/test_database.py | 37 ++++++++++++++----- 2 files changed, 108 insertions(+), 9 deletions(-) diff --git a/arango/database.py b/arango/database.py index 1a97af9e..e33bd5ae 100644 --- a/arango/database.py +++ b/arango/database.py @@ -615,7 +615,10 @@ def read_log( search: Optional[str] = None, sort: Optional[str] = None, ) -> Result[Json]: - """Read the global log from server. + """Read the global log from server. This method is deprecated + in ArangoDB 3.8 and will be removed in a future version + of the driver. Use :func:`arango.database.Database.read_log_entries` + instead. :param upto: Return the log entries up to the given level (mutually exclusive with parameter **level**). Allowed values are "fatal", @@ -642,6 +645,9 @@ def read_log( :rtype: dict :raise arango.exceptions.ServerReadLogError: If read fails. """ + m = "read_log() is deprecated in ArangoDB 3.8 and will be removed in a future version of the driver. Use read_log_entries() instead." # noqa: E501 + warn(m, DeprecationWarning, stacklevel=2) + params = dict() if upto is not None: params["upto"] = upto @@ -671,6 +677,78 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) + def read_log_entries( + self, + upto: Optional[Union[int, str]] = None, + level: Optional[Union[int, str]] = None, + start: Optional[int] = None, + size: Optional[int] = None, + offset: Optional[int] = None, + search: Optional[str] = None, + sort: Optional[str] = None, + server_id: Optional[str] = None, + ) -> Result[Json]: + """Read the global log from server. + + :param upto: Return the log entries up to the given level (mutually + exclusive with parameter **level**). Allowed values are "fatal", + "error", "warning", "info" (default) and "debug". + :type upto: int | str + :param level: Return the log entries of only the given level (mutually + exclusive with **upto**). Allowed values are "fatal", "error", + "warning", "info" (default) and "debug". + :type level: int | str + :param start: Return the log entries whose ID is greater or equal to + the given value. + :type start: int + :param size: Restrict the size of the result to the given value. This + can be used for pagination. + :type size: int + :param offset: Number of entries to skip (e.g. for pagination). + :type offset: int + :param search: Return only the log entries containing the given text. + :type search: str + :param sort: Sort the log entries according to the given fashion, which + can be "sort" or "desc". + :type sort: str + :param server_id: Returns all log entries of the specified server. + All other query parameters remain valid. If no serverId is given, + the asked server will reply. This parameter is only meaningful + on Coordinators. + :type server_id: str + :return: Server log entries. + :rtype: dict + :raise arango.exceptions.ServerReadLogError: If read fails. + """ + params = dict() + if upto is not None: + params["upto"] = upto + if level is not None: + params["level"] = level + if start is not None: + params["start"] = start + if size is not None: + params["size"] = size + if offset is not None: + params["offset"] = offset + if search is not None: + params["search"] = search + if sort is not None: + params["sort"] = sort + if server_id is not None: + params["serverId"] = server_id + + request = Request(method="get", endpoint="/_admin/log/entries", params=params) + + def response_handler(resp: Response) -> Json: + if not resp.is_success: + raise ServerReadLogError(resp, request) + + result: Json = resp.body + return result + + return self._execute(request, response_handler) + def log_levels(self, server_id: Optional[str] = None) -> Result[Json]: """Return current logging levels. diff --git a/tests/test_database.py b/tests/test_database.py index 4fa0c0ed..da6307a4 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -167,31 +167,52 @@ def test_database_misc_methods(sys_db, db, bad_db, cluster): assert err.value.error_code in {11, 1228} # Test read_log with default parameters + # Deprecated in 3.8.0 + # TODO: Remove in future release log = sys_db.read_log(upto="fatal") assert "lid" in log assert "level" in log assert "text" in log assert "total_amount" in log + log_entry = sys_db.read_log_entries(upto="fatal") + assert "total" in log_entry + assert "messages" in log_entry + + kwargs = { + "level": "error", + "start": 0, + "size": 100000, + "offset": 0, + "search": "test", + "sort": "desc", + } + # Test read_log with specific parameters - log = sys_db.read_log( - level="error", - start=0, - size=100000, - offset=0, - search="test", - sort="desc", - ) + # Deprecated in 3.8.0 + # TODO: Remove in future release + log = sys_db.read_log(**kwargs) assert "lid" in log assert "level" in log assert "text" in log assert "total_amount" in log + log_entry = sys_db.read_log_entries(**kwargs) + assert "total" in log_entry + assert "messages" in log_entry + # Test read_log with bad database + # Deprecated in 3.8.0 + # TODO: Remove in future release with assert_raises(ServerReadLogError) as err: bad_db.read_log() assert err.value.error_code in {11, 1228} + # Test read_log_entries with bad database + with assert_raises(ServerReadLogError) as err: + bad_db.read_log_entries() + assert err.value.error_code in {11, 1228} + # Test reload routing assert isinstance(db.reload_routing(), bool)