app.logger.info("This is a message")์ ๊ฐ์ Flask ๋ก๊ฑฐ์ ๋ฉ์์ง๋ gunicorn ๋ก๊ทธ ํ์ผ์ ์ ์ฅ๋์ง ์์ต๋๋ค.
Flask๋ ํ๊ฒฝ(http://flask.pocoo.org/docs/errorhandling/)์ ๋ํ ๊ฐ์ ์ ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก๋์ ๋ชจ๋์์ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ์ง ์์ต๋๋ค. Flask์ app.logger๊ฐ gunicorn์ ํตํด ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ๋๋ก ํ๋ ค๋ฉด ๋ก๊น ํธ๋ค๋ฌ๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์์ gunicorn์ stderr์ ๋ํ ๋ก๊ฑฐ์ ๋๋ค.
import logging
import flask
app = flask.Flask(__name__)
@app.before_first_request
def setup_logging():
if not app.debug:
# In production mode, add log handler to sys.stderr.
app.logger.addHandler(logging.StreamHandler())
app.logger.setLevel(logging.INFO)
์ด๊ฒ์ gunicorn์ ๋ฌธ์ ๊ฐ ์๋๋ฉฐ ๋ซ์ ์ ์์ต๋๋ค.
์์ฒญ์ ๋ฐ๋ผ ๋ซํ๋๋ค. ๊ฐ์ฌ ํด์!
gunicorn์ STDERR์์ ์๋์ผ๋ก ๋ก๊ทธ๋ฅผ ์ ํํฉ๋๊น?
@benoitc
gunicorn์ด STDERR์์ ๋ก๊ทธ๋ฅผ ์ ํํ๋๋ก ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
-R ํ๋๊ทธ๊ฐ ์ฐพ๊ณ ์๋ ๊ฒ์ผ ์ ์์ต๋๋ค.
http://gunicorn-docs.readthedocs.org/en/latest/settings.html#enable -stdio-inheritance
-R์ ๋๋ฅผ ์ํด ๊ทธ๊ฒ์ํ์ง ์์๋ค.
์๋๋ ๋ด ์ค์ ์ ๋๋ค
@app.route('/')
def index():
console = logging.StreamHandler()
log = logging.getLogger("asdasd")
log.addHandler(console)
log.setLevel(logging.DEBUG)
log.error("Something")
print >> sys.stderr, "Another thing"
return 'ok'
๋ค์์ ๋ด๊ฐ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
gunicorn --access-logfile - --log-file /mnt/log/test.log --bind 0.0.0.0:8080 --workers 2 --worker-class gevent --log-level -D debug server:app
/mnt/log/test.log์ gunicorn ๋ก๊ทธ๊ฐ ํ์๋์ง๋ง ์ ํ๋ฆฌ์ผ์ด์ ๋ก๊ทธ์๋ ํ์๋์ง ์์ต๋๋ค.
๊ด์ฐฎ์. ๊ฐ๋จํ ๋ฌธ์ ๊ฐ ์๋๋ผ๋ฉด ์๋ ๋ฐฉ์์ ์คํดํ ์ ์์ต๋๋ค.
stderr์ ์๋์ผ๋ก ํ๋ฌ์ํด์ผ ํจ(IIRC๋ ๋ฒํผ๋ง๋๊ธฐ ๋๋ฌธ์
๋๋ค.
gunicorn์ด ํฌํฌํ ๋, ์๋ง๋?)
๊ทธ๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ๋ก๊ทธ ๋ฉ์์ง๊ฐ ์ด๋๋ก ๊ฐ๋์ง ์ ์ดํ๋ โโ๊ฒ์ด ํจ์ฌ ์ฝ์ต๋๋ค.
stdio ๋์ ํ์ด์ฌ ๋ก๊ฑฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
2014๋
6์ 26์ผ ์คํ 1์ 39๋ถ์ "Yousuf Fauzan" [email protected] ์ด ์์ฑํ์ต๋๋ค.
-R์ ๋๋ฅผ ์ํด ๊ทธ๊ฒ์ํ์ง ์์๋ค.
์๋๋ ๋ด ์ค์ ์ ๋๋ค
@app.route('/')
def ์ธ๋ฑ์ค():
์ฝ์ = logging.StreamHandler()
๋ก๊ทธ = logging.getLogger("asdasd")
log.addHandler(์ฝ์)
log.setLevel(logging.DEBUG)
log.error("๋ญ๊ฐ")
์ธ์ >> sys.stderr, "๋ ๋ค๋ฅธ ๊ฒ"
'ํ์ธ'์ ๋ฐํ๋ค์์ ๋ด๊ฐ ์คํํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
gunicorn --access-logfile --log-file /mnt/log/test.log --bind 0.0.0.0:8080 --workers 2 --worker-class gevent --log-level ๋๋ฒ๊ทธ ์๋ฒ:app
/mnt/log/test.log์ gunicorn ๋ก๊ทธ๊ฐ ์์ง๋ง ๋ด ์์ฉ ํ๋ก๊ทธ๋จ์๋ ์์ต๋๋ค.
๋ก๊ทธ.โ
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ฑฐ๋ GitHub์์ ํ์ธํ์ธ์.
https://github.com/benoitc/gunicorn/issues/379#issuecomment -47276949.
๋ฌธ์ ๋ฅผ ์ฐพ์ ๊ฒ ๊ฐ์์. ๋ค์์ 19.00์ ๋ํ ๋ณ๊ฒฝ ๋ก๊ทธ์ ํญ๋ชฉ์ ๋๋ค.
fix logging: donโt try to redirect stdout/stderr to the logfile.
๋ฐฉ๊ธ v18๋ก ์๋ํ๋๋ฐ StreamHandler์ ๋ก๊ทธ๊ฐ gunicorn ๋ก๊ทธ๋ก ๋ผ์ฐํ
๋ฉ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ต๋๊น?
@benoitc @tilgovi
@spicavigo gunicorn์ stderr์ ๋ก๊ทธ ํ์ผ๋ก ์๋ ๋ฆฌ๋๋ ์
ํ์ง ์์ต๋๋ค. ์์ ์ฌํญ์ #591์์ ๋
ผ์๋ ๊ฒ์ฒ๋ผ ํดํน์ ์ ๊ฑฐํ๋ ๊ฒ์ด์์ต๋๋ค. ์ฝ์์ ๋ก๊ทธ๋ฅผ ํ์ํ๋ --error-logfile=-
๋ฅผ ์ฌ์ฉํด ๋ณด์
จ์ต๋๊น?
์ค๋ฅ ํ์ผ์ ์ง์ ์ค๋ฅ๋ฅผ ๋ฐํํ๋ ค๋ฉด ๊ฒฐ๊ตญ Environ['wsgi.errors']์ ์ธ์ํ๊ฑฐ๋ ee08ac86441e36c3433849b79b3839d1425647fd๋ฅผ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
@benoitc ๊ฐ์ฌํฉ๋๋ค
์ด์ stderr ๋์ ํ์ผ์ ๋ก๊น ํ๊ณ ์์ต๋๋ค. ๋ด ๊ฐ๋ฐ์ ์ฌ์ด์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋ฐ์ํ์ฌ ์์ ํ ๋์ด์ก์ต๋๋ค. ๋๋ pip install gunicorn์ด์๊ณ ๊ฐ์๊ธฐ stderr ๋ฆฌ๋๋ ์ ์ด ์๋์ ๋ฉ์ท๊ณ ๊ทธ๊ฒ์ด ๋ด ์ฝ๋์ ๋ฒ๊ทธ๊ฐ ์๋๋ผ ๋ฒ์ ๋ณ๊ฒฝ ๋๋ฌธ์ด๋ผ๋ ๊ฒ์ ๊นจ๋ซ์ง ๋ชปํ์ต๋๋ค. :)
@benoitc ์ด๋ป๊ฒ ๋ stderr์ ๋ก๊ทธ ํ์ผ์ ๊ธฐ๋กํ๋ ๊ฒ์ด ์ฌ์ ํ ๊ฐ๋ฅํฉ๋๊น?
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
Flask๋ ํ๊ฒฝ(http://flask.pocoo.org/docs/errorhandling/)์ ๋ํ ๊ฐ์ ์ ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ๋ก๋์ ๋ชจ๋์์ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ์ง ์์ต๋๋ค. Flask์ app.logger๊ฐ gunicorn์ ํตํด ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ๋๋ก ํ๋ ค๋ฉด ๋ก๊น ํธ๋ค๋ฌ๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์์ gunicorn์ stderr์ ๋ํ ๋ก๊ฑฐ์ ๋๋ค.
์ด๊ฒ์ gunicorn์ ๋ฌธ์ ๊ฐ ์๋๋ฉฐ ๋ซ์ ์ ์์ต๋๋ค.