Flask 和 Gunicorn 的logger

本文仅为作者自学之用,系统为macOS,不保证信息准确。

Flask/Gunicorn Logger


最近部署flask的服务器,发现需要合并各种middleware的logger的需求。由于一开始连logger本身是什么都不清楚,谈何合并不同的logger请求。这里且是查找网站加上实践出来的结果,未必有强劲的理论基础,可能有错误,希望能通过学习逐渐纠正。


首先,flask具有自己自带的logger。在程序中止需要使用app.logger调用即可。flask的app.logger的预设设置会讲log信息发布在stdout上。想要更改可以自己重新添加handler或者直接用logging.config中的dict来完全初始化成自己想要的logger模式。


接下来,假如需要Flask的logger与Gunicorn的合并,那么则需要在Flask中加入这样一段代码

Flask代码片段

代码的意义为,当Flask不是自启动的时候(言下之意就是被Gunicorn启动),那么则获取到gunicorn.error的logger,将app.loggerhandler赋值成gunicorn.error.handler。最后一句话则是将app.loggerlogger.level设置成和Gunicorn配置的相同的level。


在Gunicorn的命令中,带有启动Flask程序的一些配置信息。Gunicorn可以运用logging.config来进行完整的配置,但是我还没有学习过这一点,所以就先不多谈,目前只谈在命令行中的配置。
一个较为完整的命令如下图:

终端命令

这个命令中,定义了access.fileerror.file的输出文件地址。同时还定义了 log.level(记住这里这个level也会向下赋值到Flask中)。
假如还需要用supervisor来监控gunicorn的话,也是可以将gunicorn的语句移植到supervisor的config文件中。在这里顺便记录一下supervisor的常用命令,以便日后查阅:

初始化supervisor.conf

开启程序以及运行语句

在supervisor.conf文件中,带上;的行是文件说明格式以及功能的行,并没有执行能力,属于comment。若你需要执行某一行,就将;删除。新的Gunicorn的监控program应当写在program模块的位置,且如果你的flask程序会执行API的呼叫等命令,则这几行代码的;需要删掉

iNet

且这里需要换成第二行


socket

最后关于logger的结果还是有一点需要说明。正常情况下,无论是Gunicorn的启动信息,还是Flask内部的logging信息,均会写入同一个文件中(也就是stderr.log)。这里就有人会好奇了,例如我,为什么会写入stderr而不是stdout呢?只怪自己学艺不精,经过多番查询之后只能得出这样一个结论:

  • Gunicorn并没有自带的stdout这种输出方式,Gunicorn的配置文件中只有access.file stderr.file以及sysout.file三种输出文件地址的配置。其中access.file会显示调用API的程序的网络地址,sysout.file具体功能不详,但是貌似是非常底层的东西,其余的log信息都会进入stderr.file
  • 正常情况下,stdout会收集的是print到console的信息,也就是python中的print('Hello World!')或者java中的System.out.println("Hello World!")类型的信息。我在尝试在Flask中加入print功能之后再次测试,结果发现print的结果果然被写入了stdout.file中。唯一值得好奇的地方就是stderr.file的信息会实时写入文件中,但是stdout.file的文件却似乎是在我在让supervisor停止Gunicorn运行的时候才会一口气写入?着实奇怪,但是却又找不到原因。

最最后,supervisor停止了gunicorn的flask程序之后,如果flask程序中开启了新的后台进程,则进程还会占用该端口,导致supervisor无法使用restart命令,日志中一直显示端口占用,杀死该进程的方法有:

  • 查看端口占用情况
    lsof -i tcp:8080
    该命令会显示占用8080端口的进程
  • 杀死进程
    kill -9 pid

你可能感兴趣的:(Flask 和 Gunicorn 的logger)