diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 3923e54a5..7a01195c8 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -922,6 +922,24 @@ Log backtrace on level=debug Default: `True' +##### request_header_on_debug + +Log request on level=debug + +Default: `True' + +##### request_content_on_debug + +Log request on level=debug + +Default: `True' + +##### response_content_on_debug = True + +Log response on level=debug + +Default: `True' + #### headers In this section additional HTTP headers that are sent to clients can be diff --git a/config b/config index ff4f5c539..e21d708c2 100644 --- a/config +++ b/config @@ -127,7 +127,16 @@ #bad_put_request_content = False # Log backtrace on level=debug -# backtrace_on_debug = True +#backtrace_on_debug = True + +# Log request header on level=debug +#request_header_on_debug = True + +# Log request content on level=debug +#request_content_on_debug = True + +# Log response content on level=debug +#response_content_on_debug = True [headers] diff --git a/radicale/app/__init__.py b/radicale/app/__init__.py index 274657941..1e6020d5d 100644 --- a/radicale/app/__init__.py +++ b/radicale/app/__init__.py @@ -82,6 +82,8 @@ def __init__(self, configuration: config.Configuration) -> None: super().__init__(configuration) self._mask_passwords = configuration.get("logging", "mask_passwords") self._bad_put_request_content = configuration.get("logging", "bad_put_request_content") + self._request_header_on_debug = configuration.get("logging", "request_header_on_debug") + self._response_content_on_debug = configuration.get("logging", "response_content_on_debug") self._auth_delay = configuration.get("auth", "delay") self._internal_server = configuration.get("server", "_internal_server") self._max_content_length = configuration.get( @@ -141,7 +143,8 @@ def response(status: int, headers: types.WSGIResponseHeaders, answers = [] if answer is not None: if isinstance(answer, str): - logger.debug("Response content:\n%s", answer) + if self._response_content_on_debug: + logger.debug("Response content:\n%s", answer) headers["Content-Type"] += "; charset=%s" % self._encoding answer = answer.encode(self._encoding) accept_encoding = [ @@ -187,8 +190,9 @@ def response(status: int, headers: types.WSGIResponseHeaders, logger.info("%s request for %r%s received from %s%s", request_method, unsafe_path, depthinfo, remote_host, remote_useragent) - logger.debug("Request headers:\n%s", - pprint.pformat(self._scrub_headers(environ))) + if self._request_header_on_debug: + logger.debug("Request headers:\n%s", + pprint.pformat(self._scrub_headers(environ))) # SCRIPT_NAME is already removed from PATH_INFO, according to the # WSGI specification. diff --git a/radicale/app/base.py b/radicale/app/base.py index 55e8e1917..0a3a27cf1 100644 --- a/radicale/app/base.py +++ b/radicale/app/base.py @@ -50,6 +50,7 @@ def __init__(self, configuration: config.Configuration) -> None: self._web = web.load(configuration) self._encoding = configuration.get("encoding", "request") self._log_bad_put_request_content = configuration.get("logging", "bad_put_request_content") + self._response_content_on_debug = configuration.get("logging", "response_content_on_debug") self._hook = hook.load(configuration) def _read_xml_request_body(self, environ: types.WSGIEnviron @@ -71,8 +72,9 @@ def _read_xml_request_body(self, environ: types.WSGIEnviron def _xml_response(self, xml_content: ET.Element) -> bytes: if logger.isEnabledFor(logging.DEBUG): - logger.debug("Response content:\n%s", - xmlutils.pretty_xml(xml_content)) + if self._response_content_on_debug: + logger.debug("Response content:\n%s", + xmlutils.pretty_xml(xml_content)) f = io.BytesIO() ET.ElementTree(xml_content).write(f, encoding=self._encoding, xml_declaration=True) diff --git a/radicale/config.py b/radicale/config.py index 567847c01..7e3cadeca 100644 --- a/radicale/config.py +++ b/radicale/config.py @@ -260,6 +260,18 @@ def _convert_to_bool(value: Any) -> bool: "value": "True", "help": "log backtrace on level=debug", "type": bool}), + ("request_header_on_debug", { + "value": "True", + "help": "log request header on level=debug", + "type": bool}), + ("request_content_on_debug", { + "value": "True", + "help": "log request content on level=debug", + "type": bool}), + ("response_content_on_debug", { + "value": "True", + "help": "log response content on level=debug", + "type": bool}), ("mask_passwords", { "value": "True", "help": "mask passwords in logs", diff --git a/radicale/httputils.py b/radicale/httputils.py index 8255615ff..246332eea 100644 --- a/radicale/httputils.py +++ b/radicale/httputils.py @@ -142,7 +142,8 @@ def read_request_body(configuration: "config.Configuration", environ: types.WSGIEnviron) -> str: content = decode_request(configuration, environ, read_raw_request_body(configuration, environ)) - logger.debug("Request content:\n%s", content) + if configuration.get("logging", "request_content_on_debug"): + logger.debug("Request content:\n%s", content) return content diff --git a/radicale/rights/from_file.py b/radicale/rights/from_file.py index 01fa2fb76..3b8ede053 100644 --- a/radicale/rights/from_file.py +++ b/radicale/rights/from_file.py @@ -75,10 +75,11 @@ def authorization(self, user: str, path: str) -> str: raise RuntimeError("Error in section %r of rights file %r: " "%s" % (section, self._filename, e)) from e if user_match and collection_match: - logger.debug("Rule %r:%r matches %r:%r from section %r", + permission = rights_config.get(section, "permissions") + logger.debug("Rule %r:%r matches %r:%r from section %r permission %r", user, sane_path, user_pattern, - collection_pattern, section) - return rights_config.get(section, "permissions") + collection_pattern, section, permission) + return permission logger.debug("Rule %r:%r doesn't match %r:%r from section %r", user, sane_path, user_pattern, collection_pattern, section)