无法使用gunicorn守护程序模式为Flask进行日志记录工作

时间:2014-07-27 04:03:16

标签: python logging flask gunicorn

我正在使用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不支持应用程序日志记录。但我认为记录到文件会没问题?

有人知道如何在我的设置下注销文件吗?

4 个答案:

答案 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 容器中运行时很烦人。