我正在使用gunicorn + Nginx运行Flask Web应用程序。我以daemon
模式运行gunicorn。我配置了gunicorn和nginx来记录他们对文件的访问和错误。但我无法将Flask日志记录到文件中。
我使用shell文件用gunicorn启动我的应用程序:
#!/bin/bash
export VIRTUAL_ENV="/to/virtual/path"
export PATH="$VIRTUAL_ENV/bin:$PATH"
source "$VIRTUAL_ENV/bin/activate"
NAME="hello"
NUM_WORKERS=1
exec gunicorn hello:app \
--name $NAME \
--workers $NUM_WORKERS \
--log-level=debug \
--daemon \
--pid $VIRTUAL_ENV/logs/pid_gunicorn \
--access-logfile $VIRTUAL_ENV/logs/access_gunicorn.log \
--error-logfile $VIRTUAL_ENV/logs/error_gunicorn.log
在我的烧瓶应用程序中,我根据文档要求添加日志记录:
app.debug = False
...
if __name__ == '__main__':
if app.debug != True:
import logging
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler("flask.log", maxBytes=10000, backupCount=1)
handler.setLevel(logging.DEBUG)
app.logger.addHandler(handler)
app.logger.debug("test!!")
app.run()
我还在其他地方添加了app.logger.debug
。
当我在没有gunicorn
的情况下启动--daemon
时,日志记录文件正常工作。但是一旦我添加--daemon
,就不会生成任何日志。
我尝试使用print
但它只能在没有--daemon
的情况下使用。
我已经搜索了一段时间,it seems gunicorn不支持应用程序日志记录。但我认为记录到文件会没问题?
有人知道如何在我的设置下注销文件吗?
答案 0 :(得分:2)
所以 - 您实际上并没有设置任何日志记录。让我解释一下-
gunicorn 的第一个参数是您的应用。 gunicorn hello:app
。当您启动 gunicorn 时,它会使用常规的 Python 导入,基本上是 from hello import app
。
在您的文件 hello.py 中,您正在设置日志记录。但是,您将那段代码包裹在 if __name__ == "__main__":
块中。如果你这样做 python hello.py
那会起作用。但这不是 gunicorn 正在做的事情。您的服务没有执行这些代码(您应该注意到——毕竟,您的开发服务器并没有运行...)
在文件顶部的 if 块之外设置日志记录。您还可以选择将 gunicorn 设置为 capture-output
,在这种情况下,它会将您的应用程序输出处理到日志文件中。这可能更接近你想要的。如果您确实使用了现有的日志配置,gunicorn 将运行多个单独的进程,并且它们都将尝试登录到磁盘上的同一个文件。
我不确定您所说的“日志记录工作正常”是什么意思 - 它会保存到文件中吗?我的期望是,如果没有 --daemon,这意味着 gunicorn 正在前台运行,其输出显示在您的终端中(但除非您将脚本的输出重定向到磁盘,否则不会写入磁盘?或者正在启动它可能是 systemd?)
答案 1 :(得分:0)
我也在使用nginx + gunicorn + flask
我如何运行gunicorn app。
MYAPP.INI
[server:main]
use = egg:gunicorn#main
daemon = True
host = 0.0.0.0
python = /usr/bin/python3
port = 5005
workers = 2
proc_name = myapp
backlog = 1024
worker_class = gaiohttp
loglevel = debug
syslog = True
syslog_addr = udp://log:514
syslog_prefix = myapp
syslog_facility = local3
forwarded-allow-ips = 10.0.0.4, 10.0.0.8, 10.0.0.100
[app:main]
use = call:myapp.main:create_app
/etc/init.d/myapp
https://gist.githubusercontent.com/vpol/95970c8c4223c12548c8/raw/0b59d659d2818e19f2c6c5112664a7e0acd9b22d/gunicorn%20init%20script
的/ etc /默认/ MyApp的
# Defaults for myapp initscript
# sourced by /etc/init.d/myapp
# make this read NO_START=0 when you're done setting up your config.
NO_START=0
DAEMON="/usr/bin/gunicorn"
DAEMON_OPTS="--paste /etc/myapp/myapp.ini --preload"
MYAPP_USER="myuser"
MYAPP_GROUP="myuser"
的myapp / main.py
import logging
from flask import Flask
from werkzeug.contrib.fixers import ProxyFix
def create_app(*args, **kwargs):
app = Flask('myapp')
# Init logging
from logging.handlers import SysLogHandler
app.logger_name = 'myapp'
app.logger.addHandler(SysLogHandler(address=('log', 514), facility=local5))
app.logger.setLevel(debug)
werkzeug_logger = logging.getLogger('werkzeug')
werkzeug_logger.setLevel(DEBUG)
werkzeug_logger.addHandler(SysLogHandler(address=('log', 514), facility=local2))
app.logger.debug('started myapp')
return ProxyFix(app)
答案 2 :(得分:0)
运行守护进程的pythonic方法是使用类似Supervisord的东西,忘记bash,它的python。您是否考虑过使用nginx作为代理通行证? Gunicorn可以处理WSGI。我认为它从1.3.13起可用。它适用于websockets,但即使您运行http协议也可以工作。
类似
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/example.log;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
答案 3 :(得分:0)
为了您的目的,请将 --capture-output 设置为 True。它应该将您的应用程序输出转发到错误日志文件。
我遇到的另一个问题是,在守护进程模式下输出到 stdout 和 stderr 无处可去。当 gunicorn 在 Docker 容器中运行时很烦人。