问题
When I wrap my Flask application in gunicorn writing to stdout no longer seems to go anywhere (simple print
statements don't appear). Is there someway to either capture the stdout into the gunicorn access log, or get a handle to the access log and write to it directly?
回答1:
Use the logging: set the stream to stdout
import logging
app.logger.addHandler(logging.StreamHandler(sys.stdout))
app.logger.setLevel(logging.DEBUG)
app.logger.debug("Hello World")
回答2:
The solution from John mee works, but it duplicates log entries in the stdout from gunicorn.
I used this:
import logging
from flask import Flask
app = Flask(__name__)
if __name__ != '__main__':
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
and got I this from: https://medium.com/@trstringer/logging-flask-and-gunicorn-the-manageable-way-2e6f0b8beb2f
回答3:
You can redirect standard output to a errorlog file, which is enough for me.
Note that:
capture_output
--capture-output
False
Redirect stdout/stderr to specified file in errorlog
My config file gunicorn.config.py
setting
accesslog = 'gunicorn.log'
errorlog = 'gunicorn.error.log'
capture_output = True
Then run with gunicorn app_py:myapp -c gunicorn.config.py
The equivaluent command line would be
gunicorn app_py:myapp --error-logfile gunicorn.error.log --access-logfile gunicorn.log --capture-output
回答4:
The official Flask documentation on logging works for gunicorn. https://flask.palletsprojects.com/en/1.1.x/logging/#basic-configuration
- some example code to try out:
from logging.config import dictConfig
from flask import Flask
dictConfig(
{
"version": 1,
"formatters": {
"default": {
"format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s",
}
},
"handlers": {
"wsgi": {
"class": "logging.StreamHandler",
"stream": "ext://flask.logging.wsgi_errors_stream",
"formatter": "default",
}
},
"root": {"level": "DEBUG", "handlers": ["wsgi"]},
}
)
app = Flask(__name__)
@app.route("/")
def hello():
app.logger.debug("this is a DEBUG message")
app.logger.info("this is an INFO message")
app.logger.warning("this is a WARNING message")
app.logger.error("this is an ERROR message")
app.logger.critical("this is a CRITICAL message")
return "hello world"
- run with
gunicorn
gunicorn -w 2 -b 127.0.0.1:5000 app:app
- request it using curl
curl http://127.0.0.1:5000
- this would generate the following logs
gunicorn -w 2 -b 127.0.0.1:5000 app:app
[2020-08-20 16:52:49 +0100] [91515] [INFO] Starting gunicorn 20.0.4
[2020-08-20 16:52:49 +0100] [91515] [INFO] Listening at: http://127.0.0.1:5000 (91515)
[2020-08-20 16:52:49 +0100] [91515] [INFO] Using worker: sync
[2020-08-20 16:52:49 +0100] [91518] [INFO] Booting worker with pid: 91518
[2020-08-20 16:52:49 +0100] [91527] [INFO] Booting worker with pid: 91527
[2020-08-20 16:52:51,172] DEBUG in app: this is a DEBUG message
[2020-08-20 16:52:51,172] INFO in app: this is an INFO message
[2020-08-20 16:52:51,173] WARNING in app: this is a WARNING message
[2020-08-20 16:52:51,173] ERROR in app: this is an ERROR message
[2020-08-20 16:52:51,173] CRITICAL in app: this is a CRITICAL message
来源:https://stackoverflow.com/questions/21399680/logging-stdout-to-gunicorn-access-log