Plain is headed towards 1.0! Subscribe for development updates →

 1import logging
 2
 3request_logger = logging.getLogger("plain.request")
 4
 5
 6def log_response(
 7    message,
 8    *args,
 9    response=None,
10    request=None,
11    logger=request_logger,
12    level=None,
13    exception=None,
14):
15    """
16    Log errors based on Response status.
17
18    Log 5xx responses as errors and 4xx responses as warnings (unless a level
19    is given as a keyword argument). The Response status_code and the
20    request are passed to the logger's extra parameter.
21    """
22    # Check if the response has already been logged. Multiple requests to log
23    # the same response can be received in some cases, e.g., when the
24    # response is the result of an exception and is logged when the exception
25    # is caught, to record the exception.
26    if getattr(response, "_has_been_logged", False):
27        return
28
29    if level is None:
30        if response.status_code >= 500:
31            level = "error"
32        elif response.status_code >= 400:
33            level = "warning"
34        else:
35            level = "info"
36
37    getattr(logger, level)(
38        message,
39        *args,
40        extra={
41            "status_code": response.status_code,
42            "request": request,
43        },
44        exc_info=exception,
45    )
46    response._has_been_logged = True