Flask下的默认日志是自己定义的一套请求日志记录,常常与我们自己定义的工程日志记录格式不太一致。类似于这样

127.0.0.1 - - [01/May/2022 14:53:40] "POST /api/login/status HTTP/1.1" 200 -

与此同时,Flask的请求记录日志并不是定义在Flask模块下,而是在Werkzeug模块下。源码如下

class WSGIRequestHandler(BaseHTTPRequestHandler):
    """A request handler that implements WSGI dispatching."""

    ......
    
    def log_request(
        self, code: t.Union[int, str] = "-", size: t.Union[int, str] = "-"
    ) -> None:
        try:
            path = uri_to_iri(self.path)
            msg = f"{self.command} {path} {self.request_version}"
        except AttributeError:
            # path isn't set if the requestline was bad
            msg = self.requestline

        code = str(code)

        if _log_add_style:
            if code[0] == "1":  # 1xx - Informational
                msg = _ansi_style(msg, "bold")
            elif code == "200":  # 2xx - Success
                pass
            elif code == "304":  # 304 - Resource Not Modified
                msg = _ansi_style(msg, "cyan")
            elif code[0] == "3":  # 3xx - Redirection
                msg = _ansi_style(msg, "green")
            elif code == "404":  # 404 - Resource Not Found
                msg = _ansi_style(msg, "yellow")
            elif code[0] == "4":  # 4xx - Client Error
                msg = _ansi_style(msg, "bold", "red")
            else:  # 5xx, or any other response
                msg = _ansi_style(msg, "bold", "magenta")

        self.log("info", '"%s" %s %s', msg, code, size)

    def log_error(self, format: str, *args: t.Any) -> None:
        self.log("error", format, *args)

    def log_message(self, format: str, *args: t.Any) -> None:
        self.log("info", format, *args)

    def log(self, type: str, message: str, *args: t.Any) -> None:
        _log(
            type,
            f"{self.address_string()} - - [{self.log_date_time_string()}] {message}\n",
            *args,
        )

可以看到log_request这个函数负责给请求信息染色(颜色信息输出),而log负责格式化输出请求信息,_log函数是Werkzeug模块内部的一个全局日志输出函数。

如果我们想要修改他的话,需要自定义一个RequestHandler继承自这个Flask默认使用的WSGIRequestHandler,重写log函数,将他的输出重新格式化,或者重定向到我们自己的日志记录器上。相关代码如下:

from werkzeug.serving import WSGIRequestHandler

from libs import FormatLogger

__all__ = ("CustomRequestHandler",)


class CustomRequestHandler(WSGIRequestHandler):
    # noinspection PyShadowingBuiltins
    def log(self, type, message, *args):
        getattr(FormatLogger, type)("Request", message % args)

这个CustomRequestHandler只是简单重定向了日志输出到我自己写的FormatLogger上。这里也可以对日志做别的操作。需要注意的是,log函数的message是格式化字符串,args是格式化的内容。

最后是在Flask模块启动的时候指定使用我们的RequestHandler

from .core import app, db, CustomRequestHandler

app.run("0.0.0.0", port=8088, request_handler=CustomRequestHandler)

输出如下

[2022-05-01 18:03:31:236] [  INFO  ] [Request] "POST /api/login/status HTTP/1.1" 200 -

至此,Flask请求日志格式化完成。

说点什么
支持Markdown语法
在"Flask 下修改请求记录日志"已有2条评论
Loading...